高可用(HA)

需要首先说明的是,zbus的高可用目前并没有实现队列数据的集群高可用,而指的是应用节点的高可用,解决应用故障单点。MQ数据集群、主从目前在试验中,也是未来增强的一个重点。

对数据要求高可用的场景,暂时可以通过物理硬件增强,或者寻求类似Kafka这样的解决方案。

除此限制外,zbus应用中所有节点都是可以动态增加减少,包括服务器节点,消费者,生产者节点

快速配置HA

zbus的HA配置非常简单,启动的配置项中,trackerList能指定当前zbus实例需要上报节点,最简单的HA场景就是两台zbus实例互相Track。

zbus1(15555) 配置

<zbus compatible="false">  
    <serverHost>0.0.0.0</serverHost>  
    <serverPort>15555</serverPort>   
    <trackerList>
        <serverAddress>
            <address>localhost:15556</address>  <!-- 指定15556为上报节点-->
            <sslEnabled certFile="ssl/zbus.crt">false</sslEnabled> 
            <token></token>
        </serverAddress>   
    </trackerList>  
</zbus>

zbus2(15556) 配置

<zbus compatible="false">  
    <serverHost>0.0.0.0</serverHost>  
    <serverPort>15556</serverPort>  
    <!-- 省略掉其他配置 -->
    <trackerList>
        <serverAddress>
            <address>localhost:15555</address>  <!-- 指定15555为上报节点-->
            <sslEnabled certFile="ssl/zbus.crt">false</sslEnabled> 
            <token></token>
        </serverAddress>   
    </trackerList>  
</zbus>

在zbus的发行包中,zbus.bat/.sh 与 zbus2.bat/.sh 可以简单修改zbus.bat/.sh完成该任务。

HA原理说明

如何去除应用故障单点,zbus采用的技术方案与很多NameServer、Register方案类似,zbus中称之为Tracker,由Tracker来实时监控管理所有zbus的Mqserver节点,支持动态增加新的MqServer,也包括Tracker本身,zbus逻辑上分离了Tracker与MqServer,但是物理上zbus节点同时可以是MqServer也可以是Tracker,这为小型节点高可用部署带来很多便捷。

                   +-----------------+                   |                    +-----------------+
                   |  Client(Broker) |                   |                    |  Client(Broker) |
                   +-----------------+                   |                    +-----------------+ 
                         |     |                         |                          |     |
              track_sub  |     |   track_sub             |               track_sub  |     |   track_sub
            +------------+     +-------------+           |             +------------+     +-------------+
            |                                |           |             |                                |
            v                                v           |             v                                v
     +-------------+                 +--------------+    |      +-------------+                 +--------------+
     |  Tracker1   |                 |   Tracker2   |   ==>    |     zbus1   | <--track_pub--> |      zbus2   |
     +-------------+                 +--------------+    |      +-------------+                 +--------------+
            ^                                ^           |
            |                                |           |
            +--------------------------------+           |                 Tracker + MqServer =>  zbus
            |  track_pub          track_pub  |           |
       +--------------+             +--------------+     |
       |   MqServer1  |             |   MqServer2  |     |
       +--------------+             +--------------+     |

逻辑视图上,Producer, Broker, Consumer都是可以动态增加减少

Archit

服务端视角 Tracker

Tracker核心是管理Topic、ConsumeGroup分组通道的网络拓扑

Tracker支持的命令:

服务器端Tracker算法设计要点:

客户端视角 Tracker

客户端可以从多个Tracker实例上获取TrackerInfo{ ServerAddress => ServerInfo }, TrackerInfo和ServerInfo都带有版本号不断自增长的InfoVersion版本号。为了防止ServerInfo脑裂, 客户端仅仅接受版本号更高的信息更新合并,这点类似ZooKeeper.

客户端自身负责构建方便使用的Topic/ConsumeGroup拓扑 -- BrokerRouteTable, 用于客户端的动态路由选择。

BrokerRouteTable构建算法

BrokerRouteTable {
  ServerTable: { ServerAddress => ServerInfo } 
  TopicTable: { TopicName => { ServerAddress => TopicInfo } }
  VotesTable: { TrackerAddress => { Servers: Set[ServerAddress], InfoVersion: <Version> } }
  VoteFactor: 0.5  //Configurable, represents a ServerInfo's votes ratio, [#trackers voted / #trackers in total]
}

各个客户端最复杂的逻辑部分可能就是这个路由信息更新算法的实现,具体可以选择喜欢的语言来对应上面的算法。