收录于话题
#TGIP-CN 内容回顾
22个内容
🎙️ 阅读本文需 7 分钟
上周日,TGIP-CN 003 由郭斯杰继续为我们带来了关于「Topic Discovery, ServiceURL and Cluster」的分享。首先来回顾一下 Pulsar 最近的更新特性。
- Improve Zookeeper Session Timeout Handling
https://github.com/apache/pulsar/pull/6347
后续大家还想了解关于 Pulsar 的任何问题,都可以去这个 repo 下提 issue。同时关于每一次直播的各种参考细节,也可以在此 repo 下找到。
https://github.com/streamnative/tgip-cn
接下来就一起看看在 Pular 里,topic 和 broker 之间到底如何相处的吧。
Topic Discovery
>>> Topic Assignment
Pulsar 作为多租户消息系统,具有层级命名空间,这个在之前我们也提到了「Tenant & Namespace」相关概念。除去前两层,第三层就是 topic。那么 Pulsar 如何把 topic 分配给 brokers 呢?
首先看图理解一下层次化结构。
一个 Pulsar instance 内部,有很多租户,就好比一个公司有多个不同的部门。往下细分又有不同的业务线(对应 namespace),业务线里可能又有不同的主题(对应 topic)。
所有的 topic 在 Pulsar 集群里以树状结构连存,所以 topic 的分配是依照 namespace 层面进行划分的。因为每个 namespace 下边有很多 topic,对于一个 namespace,它旗下的所有 topic 会组成一个环。在需要进行分配 topic 之前,会把这一组 topic 按照名字 hash 到 namespace hash ring 里。然后根据不同 topic 的 hash 值又会分为几个小组,也就是 namespace bundle,它的数量是在前期创建 namespace 时就可以指定确认。
从 topic 到 bundle 映射完成后,Pulsar 接下来就会将 bundle 分配给 broker。也就是 topic 的分配不在于 topic 本身,而是依照 bundle 操作。处理过程依靠「Load Manager」进行,用来监控集群使用情况,并进行 bundle 分配。选出一台 broker 作为 lead manager 主操作器,进行监控每台 broker 负载情况的同时,获取每个 namespace bundle 的数量值。通过一组计算后,根据负载情况来进行 topic 的分配。即所有都由 load manager 进行主动获取并分发相关。以上就是 Pulsar 系统里,如何将 topic 分配到 broker 的过程。全程由 load manager 执行,按照 bundle 层面规则划分。在分配完成后,Pulsar 又是怎么正确找到哪台 broker 服务哪个 topic 的呢?首先提出一个新概念:Topic owner,换句话说就是 Namespace bundle owner,可以依照上部分的层级结构进行对应梳理即可明白。Owner 的相关信息以非持久化的状态储存在 ZooKeeper 里,任何一台 broker 都可以获取到 topic 到 owner 的映射关系。所以在客户端进行操作之前,会首先进行 topic lookup。具体过程如下:Pulsar 客户端发起「Topic lookup」请求,请求会发给任意一台 broker。接收到请求后,broker 会开启 lookup 操作模式,根据 namespace 去检测出映射的 bundle,然后将此反馈发给 ZooKeeper 去查找对应,最后将请求结果返回给客户端。这时客户端会发起 TCP 长链接,与 broker 2 进行直连。为了保证达到直连的效果,broker 2 提供的地址必须是 Pulsar 客户端可以直接链接的形式,这是非常重要的。
如果客户端不能直接访问代理地址,那应该如何处理呢?在 Pulsar 里为了简化操作,在组件里添加了「proxy」配置,它是一个具有 topic 查询/路由 功能的 TCP 反向代理。也就是在 producer 并不是直接连接 broker,而是把请求发给 proxy,proxy 会根据 topic-broker 的分配记录进行安排。这样就会生成一个 TCP 长链接到 broker。
Proxy 的作用就是将这些涌入 TCP 的包通过探测来分辨请求类型,并基于此进行后续操作,即前后的连接作用。这样做的好处是不需要暴露 broker 地址,只需暴露 proxy 即可。但这里也需要避开一个陷阱。很多人认为 proxy 起到了负载均衡的作用,它有一定的负载均衡连接数,但真实的负载均衡仍然是在 broker 端进行的。所以这是两个层面的负载均衡操作,一定要分清。有了 proxy 后,topic lookup 也可以更加充实一些。除了基本的操作反馈外,在客户端发起一个直连操作时,是可以将连接落实到任何一个 proxy 上。但是客户端的协议里,是带上了 topic owner,并传递给 proxy。
额外注意的是,加了 proxy 后的 topic lookup,需要保持 proxy 与 broker 在同一网络里。1.Topic lookup 请求。可以给任意 broker 发送,客户端无需提前知道所有 broker 的地址。对于这种请求,可以在 broker 之前加上 DNS 或负载均衡器/配置多个 broker 地址去提供服务。2. 知道 broker 后,需要建立 TCP 长链接的请求。额外注意的是 broker 的地址必须保证客户端与其可以直接连接。
知道了整个 topic lookup 的流程后,对 serviceURL 的使用就会更精准一些了。Service URL 是 Pulsar 客户端进行 topic lookup 所有权的访问点。ServieURL 的协议格式没有太多要求,可以是 HTTP 或者 binary。Topic lookup 是最开始的一个高可用入口,所以在配置 serviceURL 时需要高可用的考量。可以用以下方式:DNS:在 broker 之前配置一个 DNS,落实到 broker 里。DNS 会将 topic 导入到可用的 broker 上。这个做法的缺点是会有过期时间和缓存限制,影响可用性和连接性。Load balancer 负载均衡器:优点是可探测到后端的 broker 活跃与否,及时清理 broker,可以保证 lookup 的落点是活跃的 broker。Multi-Hosts:如果你什么机制都没有,只有一组机器,只需把所有机器当做一个列表,放在 service URL 里,这时 Pulsar 客户端会进行负载均衡,也就是说当第一次 lookup 的时候找一个 broker, 如果找不到会找第二个 broker 进行重试,依次类推。
在部署 Pulsar 集群时,需要指定一个 cluster-name,通常用来配置跨机房复制。一个 clusrer 有不同的 serviceURL,即集群配置信息,这些信息会作为元数据存储在 ZooKeeper 上。当你创建租户时,需要使用到 cluster-name 来进行租户的集群分配。同时,在创建 namespace 时也需要指定它在哪几个集群里进行复制。在 cluster 配置文件里,主要是四个接入端口,分为两大类。HTTP service:即提供 admin 操作的接口- Web service URL (http://)
- Web service URL TLS (https://)
Broker service:即客户端、producer、consumer 等需要连接的 6650 端口。- Broker service URL (pulsar://)
- Broker service URL TLS (pulsar+ssl://)
熟悉 Pulsar 的小伙伴应该知道,Pulsar 在部署集群创建 broker 之前,需要进行集群元数据初始化的动作。初始化是为了指定集群的名字和 ZooKeeper 的地址。这四个 serviceURL 作为集群配置信息,最后会进到集群配置文件。所以这四个信息只有在进行跨机房复制时使用,链接必须是远端机房可以连接到的状态。当然这些链接后期也是可以修改的。Cluster Operations:(在 Pulsar Admin Cluster的操作,可以认为是一个 CURD 的操作),即整个 cluster 的配置步骤可以简单分为四个过程。
综上来看,通过 topic lookup 的过程,以及 serviceURL 和 cluster 的加持,保障了在 Pulsar 系统里 topic 与 broker 之间的灵活传送。希望通过以上的讲解,可以让大家对 Pulsar 的消息传递过程更加清晰明朗。如果你想查看更多细节,也可以点击下方视频进行全程回顾。视频从 52 分钟开始,对本次直播提出的问题进行了解答,也可以多关注一下哦。
想要获取本次直播的 slides,可以点击「阅读原文」进行查看或下载。
更多参考信息可在 TGIP-CN repo 下查看:https://github.com/streamnative/tgip-cn/tree/master/episodes/003