前言
最近工作中在做一个场景的pulsar性能调优,解决了一些问题,分享给大家
业务场景
其中producer,pulsar,consumer均为多实例,4U16G部署
虽然消息量不是很大,但主要topic数目大,还要让producer,pulsar,consumer协同工作好,架构无单点问题,无损升级,这是我们的主要挑战
问题列表
Pulsar客户端连接不上broker
刚刚把测试数据准备好,我们就碰到了第一个问题,pulsar客户端连接broker困难,测试无法进行。我们根据健康检查,curl命令排查出问题在pulsar的8080端口hang住,不给响应。
这里值得一提的是,我们使用了8080端口而不是6650端口连接broker,原因主要有两点:
- 8080的日志详细,而且大部分发向8080的请求都是元数据请求,在排查问题的时候比较关键,也容易监控。比如,创建topic失败,创建producer超时,这些事件在jetty的requestLog都能很容易地监控起来
- 数据请求和元数据请求可以隔离,避免在6650端口繁忙的时候,创建topic,删除topic等功能受到影响
然而8080端口效率相对6650性能差,默认的线程数不满足5w topic量级下,consumer,producer建立的请求数(每个consumer的建立都有partitions和lookup请求等),这里我们把jetty的线程数调大,解决了这个问题
生产消费时延大
然后,我们通过测试工具发现消息从生产者到消费者,整个端到端延迟较大。
这里我们为了定位问题方便,开发了单topic debug特性,在海量消息的场景下,无论是测试环境还是生产环境,都不敢轻易在broker开启全局debug。我们在自己的配置中心做了个配置,在配置上的topic,就会打印debug日志。
在单topic debug特性的配合下, 我们很快发现消息的最大延迟出现在producer发送完消息,服务端接收到消息之间,由此推测到是netty的acceptor配置不够,调高后解决了部分问题。我们选用的版本,acceptor配置还是写死在代码里为1的。提交了PR,使之变为可配置https://github.com/apache/pulsar/pull/9061,也解决了创建生产消费者慢的问题
解决了这个问题后,我们就发现瓶颈出现在单个JVM实例上,启动5w个消费者存在很大的隐患,如内存不足,5w消费者下所需的业务线程调度导致延迟还是较大。我们决定对消费者进行分组,每个实例负责约1w个消费者,解决了生产消费时延大的问题。
创建生产消费者慢
调整netty参数配置后解决
升级呼损时间长
在测试pulsar升级的过程中,我们发现单topic不可用时间峰值竟达到过127秒,这几乎是不可接受的。随后排查发现,pulsar的优雅启停并没有执行完毕就退出了(注:pulsar的优雅启停,需要在zk上进行两次操作,我们也在实测中发现,pulsar升级过程中,zk的p99延迟会增加)随后我们调大了pulsar的优雅启停时间到180s。将单topic不可用时间控制在17s左右,再在生产者重试,保证无呼损。接下来还要继续优化这个数字。
ZooKeeper升级部分Pulsar重启
当前如果和ZooKeeper断链,pulsar就会重启,重连目前还是beta配置。当zooKeeper升级的过程中,zookeeper客户端和zookeeper服务器重连是依次重连的,间隔为1s内随机,并且每次轮完一圈后会等待1s(注:我们采用静态ZooKeeper配置,并且用域名访问,Ex: ZooKeeper-0.zookeeper:2181,ZooKeeper-1.zookeeper:2181,ZooKeeper-2.zookeeper:2181)。我们升级zookeeper的时候,重新选主大概需要0~2s。
默认的pulsar超时时间是5s,本来就算是最差的场景,以zookeeper-0升级举例: zookeeper-0=>zookeeper-1=>zookeeper-2=>sleep1s=>zookeeper-0,这样子大概4秒也是能连上来的,但是因为我们配置的域名,jvm刷新域名不及时,导致第二次重连zookeeper-0也失败了。
解决方案:把jvm的dns超时配置成5s,并且把zookeeper的session超时配成15s
健康检查波动
Pulsar自带的健康检查脚本,需要拉起一个jvm运行,在1U的场景下会造成较大的cpu波动,4U的场景下也有较大影响。我们本来就就在容器内除了pulsar进程,还拉起了一个进程,负责对接我们的告警,kpi系统等,让这个进程负责健康检查的工作(也是生产消费pulsar)避免了每次都动态拉起jvm,降低了cpu的波动
Recycled Already
这个问题比较简单,使用了TypedMessageBuilder进行重试,,提醒小伙伴们不要使用TypedMessageBuilder进行重试
普罗指标裁剪
50ktopic数量大,指标多,都进行采集,会导致我们的普罗占用资源非常大,我们根据自己的业务特点,比如每条消息大小都差不多,裁剪掉了storageSize的相关指标,忍痛裁掉了每个ml的指标,认为topic级别的监控+全局监控+bk监控足以网上运维。将普罗的占用资源控制在了8U32G。