vivo Pulsar 万亿级消息处置惩罚实践(2)-从0到1建设 Pulsar 指标监控链路

[复制链接]
发表于 7 天前 | 显示全部楼层 |阅读模式
作者:vivo 互联网大数据团队- You Shuo
本文是《vivo Pulsar万亿级消息处置惩罚实践》系列文章第2篇,Pulsar支持上报分区粒度指标,Kafka则没有分区粒度的指标,所以Pulsar的指标量级要宏大于Kafka。在Pulsar平台建设初期,提供一个稳固、低时延的监控监控链路尤为重要。
系列文章:
本文是基于Pulsar 2.9.2/kop-2.9.2展开的。
一、背景

作为一种新型消息中心件,Pulsar在架构设计及功能特性等方面要优于Kafka,所以我们引入Pulsar作为我们新一代的消息中心件。在对Pulsar进行调研的时候(比如:性能测试、故障测试等),针对Pulsar提供一套可观测可观测系统是必不可少的。Pulsar的指标是面向云原生的,并且官方提供了Prometheus作为Pulsar指标的收罗、存储和查询的方案,但是使用Prometheus收罗指标面对以下几个问题

  • Prometheus自带的时序数据库不是分布式的,它受单机资源的限制;
  • Prometheus 在存储时序数据时斲丧大量的内存,并且Prometheus在实现高效查询和聚合计算的时候会斲丧大量的CPU。
除了以上列出的可观测可观测系统问题,Pulsar还有一些指标自己的问题,这些问题包罗

  • Pulsar的订阅积存指标单元是entry而不是条数,这会严肃影响从Kafka迁徙过来的用户的使用体验及日常运维工作;
  • Pulsar没有bundle指标,因为Pulsar主动均衡的最小单元是bundle,所以bundle指标是调试Pulsar主动均衡参数时重要的观测依据;
  • kop指标上报异常等问题。
针对以上列出的几个问题,我们在下面分别展开叙述。
二、Pulsar监控监控告警系统架构

在上一章节我们列出了使用Prometheus作为观测系统的局限,由于Pulsar的指标是面向云原生的,接纳Prometheus收罗Pulsar指标是最好的选择,但对于指标的存储和查询我们使用第三方存储来减轻Prometheus的压力,整个监控监控告警系统架构如下图所示:

在整个可观测可观测系统中,各组件的职能如下:

  • Pulsar、bookkeeper等组件提供暴露指标的接口
  • Prometheus访问Pulsar指标接口收罗指标
  • adaptor提供了服务发现、Prometheus格式指标的反序列化和序列化以及指标转发远端存储的本领,这里的远端存储可以是Pulsar或Kafka
  • Druid消费指标topic并提供数据分析的本领
  • vivo内部的检测告警平台提供了动态配置检测告警的本领
基于以上监控系统的设计逻辑,我们在详细实现的过程中遇到了几个比较关键的问题:
一、adaptor需要接收Pulsar所有线上服务的指标并兼容Prometheus格式数据,所以在调研Prometheus收罗Pulsar指标时,我们基于Prometheus的官方文档开发了adaptor,在adaptor里实现了服务到场集群的发现机制以及动态配置prometheus收罗新新到场服务的指标:
在可以动态配置Prometheus收罗所有线上正在运行的服务指标之后,由于Prometheus的指标是基于protobuf协议进行传输的,并且Prometheus是基于go编写的,所以为了适配Java版本的adaptor,我们基于Prometheus和go提供的指标格式定义文件(remote.proto、types.proto和gogo.proto)天生了Java版本的指标接收代码,并将protobuf格式的指标反序列化后写入消息中心件。
二、Grafana社区提供的Druid插件不能很好的展示Counter范例的指标,但是bookkeeper上报的指标中又有许多是Counter范例的指标,vivo的Druid团队对该插件做了一些改造,新增了计算速率的聚合函数。
druid插件的安装可以参考官方文档详情
三、由于Prometheus比较依赖内存和CPU,而我们的机器资源组又是有限的,在使用远端存储的基础上,我们针对该问题优化了一些Prometheus参数,这些参数包罗:


  • --storage.tsdb.retention=30m:该参数配置了数据的保存时间为30分钟,在这个时间之后,旧的数据将会被删除。
  • --storage.tsdb.min-block-duration=5m:该参数配置了天生块(block)的最小时间隔断为5分钟。块是一组时序数据的集合,它们通常被一起压缩和存储在磁盘上,该参数间接控制Prometheus对内存的占用。
  • --storage.tsdb.max-block-duration=5m:该参数配置了天生块(block)的最大时间隔断为5分钟。如果一个块的时间跨度超过这个参数所设的时间跨度,则这个块将被分成多个子块。
  • --enable-feature=memory-snapshot-on-shutdown:该参数配置了在Prometheus关闭时,主动将当前内存中的数据快照写入到磁盘中,Prometheus在下次启动时读取该快照从而可以更快的完成启动。
三、Pulsar 指标优化

Pulsar的指标可以乐成观测之后,我们在日常的调优和运维过程中发现了一些Pulsar指标自己存在的问题,这些问题包罗正确性、用户体验、以及性能调优等方面,我们针对这些问题做了一些优化和改造,使得Pulsar更加通用、易维护。
3.1 Pulsar消费积存指标

原生的Pulsar订阅积存指标单元是entry,从Kafka迁徙到Pulsar的用户盼望Pulsar可以或许和Kafka一样,提供以消息条数为单元的积存指标,这样可以方便用户判断详细的延迟大小并只管不改变用户使用消息中心件的风俗。
在确保配置brokerEntryMetadataInterceptors=
org.apache.pulsar.common.intercept.AppendIndexMetadataInterceptor情况下,Pulsar broker端在往bookkeeper端写入entry前,通过拦截器往entry的头部添加索引元数据,该索引在同一分区内单调递增,entry头部元数据示比方下:
  1. biz-log-partition-1 -l 24622961 -e 6
  2. Batch Message ID: 24622961:6:0
  3. Publish time: 1676917007607
  4. Event time: 0
  5. Broker entry metadata index: 157398560244
  6. Properties:
  7. "X-Pulsar-batch-size    2431"
  8. "X-Pulsar-num-batch-message    50"
复制代码
以分区为指标统计的最小单元,基于last add confirmed entry和last consumed entry计算两个entry中的索引差值,即是订阅在每个分区的数据积存。下面是cursor基于订阅位置计算订阅积存的表示图,此中last add confirmed entry在拦截器中有记录最新索引,对于last consumed entry,cursor需要从bookkeeper中读取,这个操纵可能会涉及到bookkeeper读盘,所以在网络延迟指标的时候可能会增加收罗的耗时。

效果
上图是新订阅积存指标和原生积存指标的对比,新增的订阅积存指标单元是条,原生订阅积存指标单元是entry。在客户端指定单条发送100w条消息时,订阅积存都有明显的升高,当客户端指定批次发送100w条消息的时候,新的订阅积存指标会有明显的升高,而原生订阅积存指标相对升高幅度不大,所以新的订阅积存指标更详细的体现了订阅积存的情况。

3.2 Pulsar bundle指标

Pulsar相比于Kafka增加了主动负载均衡的本领,在Pulsar里topic分区是绑定在bundle上的,而负载均衡的最小单元是bundle,所以我们在调优负载均衡策略和参数的时候比较依赖bunlde的流量分布指标,并且该指标也可以作为我们切分bundle的参考依据。我们在开发bundle指标的时候做了下面两件事变:
统计当前Pulsar集群非游离状态bundle的负载情况对于处于游离状态的bundle(即没有被分配到任何broker上的bundle),我们指定Pulsar leader在上报自身bundle指标的同时,上报这些处于游离状态的bundle指标,并打上是否游离的标签。
效果

上图就是bundle的负载指标,除了出入流量分布的情况,我们还提供了生产者/消费者到bundle的毗连数目,以便运维同学从更多角度来调优负载均衡策略和参数。
3.3 kop消费延迟指标无法上报

在我们实际运维过程中,重启kop的Coordinator节点后会偶发消费延迟指标下降或者掉0的问题,从druid查看上报的数据,我们发现在重启broker之后消费组就没有继续上报kop消费延迟指标。
(1)缘故原由分析
由于kop的消费延迟指标是由Kafka lag exporter收罗的,所以我们重点分析了Kafka lag exporter收罗消费延迟指标的逻辑,下图是Kafka-lag-exporter收罗消费延迟指标的表示图:

此中,kafka-lag-exporter计算消费延迟指标的逻辑会依赖kop的describeConsumerGroups接口,但是当GroupCoordinator节点重启后,该接口返回的member信息中assignment数据缺失,kafka-lag-exporter会将assignment为空的member给过滤掉,所以最终不会上报对应member下的分区指标,代码调试如下图所示:


为什么kop/Kafka describeConsumerGroups接口返回member的assignment是空的?因为consumer在启动消费时会通过groupManager.storeGroup写入__consumer_
offset,在coordinator关闭时会转移到另一个broker,但另一个broker并没有把assignment字段反序列化出来(序列化为groupMetadataValue,反序列化为readGroupMessageValue),如下图:

(2)解决方案
在GroupMetadataConstants#readGroup-
MessageValue()方法对coordinator反序列化消费组元数据信息时,将assignment字段读出来并设置(序列化为groupMetadataValue,反序列化为readGroupMessageValue),如下图:

四、总结

在Pulsar监控系统构建的过程中,我们解决了与用户体验、运维服从、Pulsar可用性等方面相关的问题,加速了Pulsar在vivo的落地进度。固然我们在构建Pulsar可观测系统过程中解决了一部分问题,但是监控链路仍旧存在单点瓶颈等问题,所以Pulsar在vivo的发展未来还会有许多挑衅。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

© 2001-2025 Discuz! Team. Powered by Discuz! X3.5

GMT+8, 2025-6-19 21:10 , Processed in 0.080228 second(s), 32 queries 手机版|qidao123.com技术社区-IT企服评测▪应用市场 ( 浙ICP备20004199 )|网站地图

快速回复 返回顶部 返回列表