一、为什么要给Pulsar换元数据存储
当你管理的Pulsar集群规模从几十台broker涨到上百台,topic数量突破几万时,可能会遇到原来的元数据存储ZooKeeper(下文简称ZK)跟不上节奏的问题——比如消息发送延迟变高、topic配置修改后生效慢,甚至出现broker拉取元数据超时的情况。这是因为ZK的设计更适合小规模集群,其处理请求的上限有限,而Etcd作为新一代分布式键值存储,能更好承载大规模集群的元数据需求,是很多运维团队扩容时的选择。
1.1 原场景的真实痛点
举个实际例子:我之前维护过一个Pulsar集群,前期用了3节点ZK集群,当时topic数量只有几千,一切正常。后来业务爆发,topic涨到几万,每秒有近10万次元数据修改请求,ZK节点的CPU使用率很快冲到80%以上,每次修改配置都要等几秒才能生效,broker偶尔会因为拉不到元数据出现短暂的消息断流,业务方反馈体验很差。这就是典型的ZK在大规模集群下的瓶颈问题。
1.2 适合切换的场景
不是所有Pulsar集群都需要切换,通常满足以下条件就可以考虑:集群扩容到上百台broker后性能下降;需要更高的元数据处理吞吐量;希望简化后期集群维护;或者计划结合Etcd的原生监控、自动备份等特性。如果只是小集群,ZK的稳定性足够,没必要折腾。
二、平滑切换的核心思路
切换的核心是让业务感知不到变化,所以整个流程要遵循“先备份、再同步、灰度测、全切换、后下线”的原则,每一步都留好回滚的空间,绝不直接全量切换。比如同步元数据时先做全量同步,再做增量同步,确保新旧系统的元数据完全一致;切换时先切10%的流量,验证没问题再切50%,最后全量切换。
三、具体切换步骤(带实操示例)
整个切换流程用Shell脚本完成,统一技术栈为Shell(用于Pulsar集群元数据操作),所有操作都基于Pulsar 2.10版本的官方工具,避免自定义脚本的坑。
3.1 前置准备:部署Etcd集群并同步元数据
首先要部署3节点Etcd集群,确保能正常连接,然后用Pulsar官方的元数据迁移工具把ZK里的元数据同步到Etcd,这里的脚本要带详细注释,方便复用和修改。
# 技术栈:Shell(适配Pulsar集群元数据操作)
# 1. 下载对应版本的Pulsar客户端,确保能连接原ZK集群
wget https://archive.apache.org/dist/pulsar/pulsar-2.10.2/apache-pulsar-2.10.2-bin.tar.gz
tar -zxf apache-pulsar-2.10.2-bin.tar.gz && cd apache-pulsar-2.10.2/bin
# 2. 执行元数据迁移(替换成自己的ZK和Etcd地址)
./pulsar-managed-ledger-metadata-migration \
--from zk://zk-server1:2181,zk-server2:2181/pulsar-cluster \
--to etcd://etcd-server1:2379,etcd-server2:2379/pulsar-cluster \
--operation migrate \
--delete-old-metadata false # 先不删旧ZK的元数据,方便回滚
这段脚本做了两件事:一是安装Pulsar客户端,二是把ZK里的元数据全量同步到Etcd,同时保留旧ZK的内容,防止同步失败后找不到数据。
3.2 流量灰度切换
全量同步完成后,先不要直接让所有broker用Etcd,而是灰度切换。比如先选一个测试用的命名空间,修改对应broker的配置,让broker用Etcd当元数据存储。操作步骤是:
- 找到所有broker的配置文件
broker.conf,修改metadataStoreType=etcd,同时配置etcdServers=etcd-server1:2379,etcd-server2:2379; - 滚动重启broker,每次重启1台,验证broker正常连接;
- 切换1-2个业务量小的命名空间到Etcd,验证业务正常。
3.3 切换后的验证策略
这一步是最关键的,必须确保切换后的数据和旧系统完全一致,业务能正常运行。用以下Shell命令做验证:
# 技术栈:Shell
# 验证1:统计topic数量是否一致(切换前ZK的topic数,切换后Etcd的topic数)
# 先查旧ZK的topic总数
./pulsar-admin topics list -t zk://zk-server1:2181/pulsar-cluster | wc -l
# 再查Etcd的topic总数,两个数必须完全相同
./pulsar-admin topics list -t etcd://etcd-server1:2379/pulsar-cluster | wc -l
# 验证2:发送并消费一条测试消息,确保元数据和读写正常
# 发送测试消息到test命名空间下的test-topic
./pulsar-admin produce persistent://test/ns1/test-topic -m "Hello Pulsar To Etcd!"
# 消费这条消息,10秒内能收到就算正常
./pulsar-admin consume persistent://test/ns1/test-topic -n 1 -w 5
# 验证3:检查消费组位置是否一致
./pulsar-admin subscriptions get -t etcd://etcd-server1:2379/pulsar-cluster persistent://test/ns1/test-topic
# 和切换前ZK里的消费组信息对比,位置应该完全相同
如果所有验证都通过,就可以逐步把剩下的命名空间切换到Etcd,最后全量重启所有broker,完成切换。
四、技术优缺点对比
ZK和Etcd在Pulsar里的表现差异很大,要清楚知道各自的优劣:
4.1 Etcd的优势
- 性能更高:Etcd的事务吞吐量是ZK的3-5倍,延迟更低,每秒能处理上万次请求,适合高并发场景;
- 扩展性更强:Etcd可以部署5、7甚至9个节点,支持更大规模的集群,而ZK最多7个节点就会出现性能瓶颈;
- 监控更完善:Etcd自带 metrics 指标,比如请求延迟、节点健康状态,不用额外安装监控工具;
- 自动备份:Etcd支持自动快照,数据恢复更方便,ZK的备份需要手动做快照。
4.2 ZK的劣势
- 扩展性有限:ZK节点超过7个后,集群的性能会快速下降,不适合上百台broker的集群;
- 维护成本高:ZK的配置参数多,调优复杂,比如会话超时、投票时间等,新手很难掌握;
- 性能瓶颈:大规模集群下,ZK的请求排队严重,容易出现broker元数据拉取超时的问题。
五、切换过程中的注意事项
切换过程中如果不注意细节,很容易出问题,这些坑一定要避开:
- 提前备份旧元数据:同步前一定要用ZK的快照命令备份,比如
zkCli.sh snapshot,防止同步后数据丢失,回滚时要用; - 确认Pulsar版本支持:Pulsar 2.8及以上版本才原生支持Etcd作为元数据存储,旧版本要先升级,不然会出现命令执行失败;
- 灰度切换要慢:第一次灰度只切1个命名空间,等24小时,确认业务没有问题再切第二个,不要一次性切所有;
- 切换后监控Etcd:要监控Etcd的CPU、内存、磁盘IO,特别是每秒请求数,确保没有超过上限;
- 不要删除旧元数据:全量切换完成后,至少保留旧ZK集群1周,等业务完全稳定后再下线,方便回滚。
六、总结
Pulsar元数据从ZK迁移到Etcd,本质上是给大规模集群找一个性能更好、扩展性更强的存储方案。整个流程的核心是“慢”,每一步都要验证,绝不追求快。通过本次切换,我之前维护的Pulsar集群的元数据处理吞吐量提升了4倍,延迟从几百毫秒降到了几十毫秒,broker的稳定性也大幅提升。如果你正在为大规模Pulsar集群的元数据性能问题头疼,不妨尝试平滑迁移到Etcd,按照步骤操作就能顺利完成。
Comments