Pulsar是一个非常优秀的消息流平台。本文主要讲讲通过Broker中的负载均衡工具Bundle在Pulsar中进行topic的分发。1Topic层级概念首先看一下Pulsar的架构图,如下图所示:Pulsar的Broker可以管理一个或多个Topic。Pulsar是一个多租户平台。多租户的特点体现在Topic是一个层次化的概念。Topic的URL如下:一个Topic可以使用persistent属性指定是否持久化,Topic上层使用租户隔离权限,使用Namespace来管理策略。Topic的层级概念也可以用下图来表示:在一个公司内部的Pulsar集群中,可以按照业务部门建立租户,按照业务部门内部不同的项目组划分Namespaces,不同业务单元的每个项目组都可以用来创建租户。分主题。2NamespaceBundlesPulsar将Namespace拆分为Bundle,Bundle是namespace的子集。一个Namespace下有6个topic,如下图所示:我们把这个Namespace分为四个hash区,从0x00000000到0xffffffff,然后对这6个topic按照名字进行hash运算(上图URL图中最后一部分))并将它们分配给这四个区域。在这个区域,如下图所示:上图中,Topic0的值经过Hash运算后落在0xc0000000~0xffffffff区域,其他几个topic也落在自己的Hash区域。Bundle子集为什么要为Namespace划分?因为Pulsar有自动负载均衡机制,会把繁忙的Broker中的一些topic迁移到空闲的Broker中,从而实现Broker的直接流量均衡。如果这一招是直接移动Namespace,那就太重了。比如上图,需要一次性移动6个主题。如果以topic为单位,每次移动的数据会太小,迁移过程中需要保存topic和broker之间的大量元数据。有了捆绑包之后,以捆绑包为单位迁移主题就容易多了。比如上图中,一次迁移一个bundle,有的包含一个topic,有的包含两个topic。3Broker分配BundleBundleBroker集群在启动过程中会在Zookeeper中竞争创建一个临时节点,创建成功会成为Leader节点,称为LoadManager。这个节点会定时收集其他Broker的服务状态,比如CPU、内存、网卡带宽利用率,这些指标都是临时数据,所以Leader节点不会保存太多数据。Leader节点会根据收集到的负载情况,将Bundle分配给其他Broker节点。如下图所示:Broker1竞争成为上图中的Leader,它负责为其他几个Broker分配Bundle。在初始化的时候,每个Broker都没有Boundle,Leader将topic0分配给Broker3,也就是说topic0所在的Bundle分配给Broker3,然后所有和topic0相同的Hash值落入这个束。然后将topic1赋给Broker2,也就是说topic1所在的Bundle赋给了Broker2。类似于将另外两个Bundle分别分配给Broker0和Broker1。4高可用还是以上图为例。如果Broker0挂了,LoadManager和ZK都可以检测到broker0挂了。这时候LoadManager会重置Bundle(0x00000000~0x400000000)分配给其他三个broker。选择哪个broker取决于LoadManager收集到的各个broker的负载,会找到一个负载最小的broker进行分配。如下图:如果Broker1宕机,也就是Leader节点宕机,那么Broker0、Broker1、Broker2这三个节点会去Zookeeper抢占注册零时节点,注册的变成新的Leader,新的Leader节点会把Broker1的Bundle分发给剩下的3个Brokers。5客户端Topic通过Bundle绑定到Broker后,客户端就可以和自己要访问的Broker建立长链接了,如下图:这里注意:图中步骤1和2既可以使用HTTPorTCP也可以,但是第三步在Broker和client之间建立连接只能使用TCP。Pulsar为客户端提供了一个代理,客户端可以直接与代理进行通信,如下图:6总结使用Bundle,Pulsar可以很方便的通过LoadManager节点进行负载均衡,不用担心移动过多的主题在一个时间。移动主题需要保存太多元数据。
