构建下一代万亿级云原生消息架构:Apache Pulsar 在 vivo 的探索与实践( 二 )


构建下一代万亿级云原生消息架构:Apache Pulsar 在 vivo 的探索与实践
文章图片
Pulsar的设计架构带来了海量分区支撑、消费扩展、精准限流、流量均衡、快速扩缩容、故障恢复、分层存储、云原生容器部署、异地多活等特性和优势 , 可以帮助集群更好地实现高可用、高扩展 , 提高了更高的弹性 。
2ApachePulsar集群管理实践
下面我们从流量控制和数据管理方面 , 分享vivo在使用Pulsar过程中的集群管理经验 。
Bundle的管理
在集群流量控制层面 , 比较关键的一点就是Bundle的管理 。 Bundle负责控制用户流量到Broker的具体分布 。 Broker与Topic之间没有直接联系 , 而是在Broker之上抽象出Bundle概念 , 通过Bundle与Topic建立关系;Topic通过名称计算哈希值 , 并散列分布到一致性哈希环中 , 而哈希环的每一段都是一个Bundle 。 另外LoadManager根据Bundle的负载情况将后者分配到对应的Broker上 , 将Bundle数据存储在ZooKeeper中 。 由此以来就间接实现了Topic与Broker之间的联系(可参考近期StreamNative发布的Broker负载均衡技术文章) 。
构建下一代万亿级云原生消息架构:Apache Pulsar 在 vivo 的探索与实践
文章图片
构建下一代万亿级云原生消息架构:Apache Pulsar 在 vivo 的探索与实践
文章图片
图6.Bundle与Topic建立关系
这里需要注意:Bundle的个数影响均衡效果 , 因为通过一致性哈希来确认Topic应该落在哪个Bundle上 , Topic与Bundle会存在不均衡分配 , 某些Bundle分配的Topic可能较多或较少 。 Bundle越多 , 每个Bundle承载的Topic越少 , 粒度越细 。 依赖于Pulsar的负载均衡算法 , 均衡效果更好;否则若Bundle太大 , 无论如何卸载都很难平衡负载;Bundle数据和Broker映射元数据都维护在ZooKeeper中 , 需要做好Bundle数量的规划 。
针对以上两点 , 我们根据Broker来设置Bundle数量设置最小最大值来控制 , 还可以对流量较大的Topic针对性扩大分区 , 让分区均匀分配到BrokerBundle上 。
Pulsar虽然提供了海量分区能力 , 但是过多的Topic或者分区产生的lookup也会对集群产生较大的压力 。 集群管理者需要提前规划Bundle和分区设置 , 杜绝滥用 。
另外对Bundle的操作需要注意:Pulsar本身提供了卸载操作 , 可以解除Bundle和Broker的关联关系 , 将Bundle重新分配 。 线上流量较大时应卸载Bundle而不是整个命名空间 , 因为卸载后者会导致其上的全部Bundle与对应的生产者、消费者断开 , 重新进行lookup 。 利用Bundlesplit对流量较大的Bundle进行拆分 , 增加命名空间的Bundle数量 , 降低影响 。
总体而言 , 用户需要注意流量的均衡与集群的稳定性 , 在集群管理之初就做好Bundle的数量管理和相关测试 , 谨慎对待大批量Bundle卸载等运维操作 。
构建下一代万亿级云原生消息架构:Apache Pulsar 在 vivo 的探索与实践】数据的管理
接下来我们从数据的存储、过期、删除三个方面来分析 。
Ledger翻转
首先介绍数据写入ledger的过程 。 每一个Topic分区在一段时间内只创建一个Ledger维护分区写入的Entry的数据归属 。 Topic分区写入的数据以Entry的形式 , 经过Broker写入Netty线程处理队列 , 线程依次根据Entry的LedgerId , 对Ledger目录数取模 , 写入到目标磁盘Ledger目录 , 最终以EntryLog和RocksDB的索引方式存储 。 需要注意 , Ledger是一个分区在一段时间内写入数据的逻辑管理单位 , 维护了这段数据存储的Bookie位置 。 一个Topic分区在一段时间内写入的数据只被一个活跃Ledger管理 , 待该Ledger达到翻转条件后才会关闭Ledger并重新计算 , 创建新Ledger继续写入 。