pulsar-backlog

Pulsar 订阅 backlog 持续增长,消费速率长期低于生产速率。

现象

监控里 msgBacklog 或 backlogSize 持续上升,消费延迟变大;消息最终因 TTL/保留策略过期,或触发 backlog quota 导致生产被阻塞。消费者可能看起来仍在运行,但 msgRateOut 低于 msgRateIn。

快速定位

先看 topic 和订阅级统计,区分是消费慢、未 ack 还是重投递:

pulsar-admin topics stats persistent://<tenant>/<namespace>/<topic>
pulsar-admin topics stats-internal persistent://<tenant>/<namespace>/<topic>
pulsar-admin topics subscriptions persistent://<tenant>/<namespace>/<topic>
pulsar-admin topics stats persistent://<tenant>/<namespace>/<topic> | jq '.subscriptions'

订阅下重点看 msgBacklog、unackedMessages、blockedSubscriptionOnUnackedMsgs、msgRateOut、msgRateRedeliver、lastAckedTimestamp。再从 broker 指标确认趋势:

curl -s http://<broker>:8080/metrics | grep -E 'pulsar_subscription_(msg_backlog|msg_rate_out|msg_rate_redeliver|unacked_messages|blocked_on_unacked_messages)'
curl -s http://<broker>:8080/metrics | grep -E 'pulsar_storage_(size|backlog_size|write_latency)'

检查保留、TTL 和 backlog quota,并抽样看积压消息:

pulsar-admin namespaces get-backlog-quotas <tenant>/<namespace>
pulsar-admin namespaces get-retention <tenant>/<namespace>
pulsar-admin namespaces get-message-ttl <tenant>/<namespace>
pulsar-admin topics peek-messages persistent://<tenant>/<namespace>/<topic> --count 3 --subscription <sub>

易误判:msgBacklog 包含已投递但尚未 ack 的消息(仍在 consumer 的 receiver queue 中),不等于“完全没消费”;msgBacklogNoDelayed 才排除延迟消息。若 msgRateOut 很高但 msgRateRedeliver 也高,说明在重投递空转,而不是有效吞吐。

常见根因

  1. 消费处理慢:每条消息同步调用外部服务/数据库,msgRateOut 长期低于 msgRateIn。
  2. 未 ack 或 ack 超时:unackedMessages 增长,达到 maxUnackedMessagesPerConsumer/PerSubscription 后 blockedSubscriptionOnUnackedMsgs=true。
  3. 重投递风暴:ackTimeout 太短或处理异常,msgRateRedeliver 升高。
  4. 消费者数量不足,分区数大于消费者数,或 Key_Shared 的 key 热点造成倾斜。
  5. 消费者反复重连、rebalance 或客户端版本问题。
  6. Broker/BookKeeper 瓶颈:写延迟高、磁盘 IO 饱和、ledger 读取慢。
  7. backlog quota/retention 配置不当,积压触发生产阻塞或消息提前过期。
  8. 反序列化/schema 错误导致持续 nack,消息永远处理不成功。

修复

相关命令

读完自测

  1. msgBacklog 高是否一定代表消费者没在处理消息?
  2. blockedSubscriptionOnUnackedMsgs=true 说明瓶颈在哪?
  3. msgRateOut 和 msgRateRedeliver 同时很高意味着什么?
答案
  1. 不一定;msgBacklog 也包含已投递但未 ack、仍在客户端队列中的消息。
  2. 未 ack 消息达到了订阅/消费者配额上限,broker 暂停投递,问题在 ack 与处理完成,而非投递能力。
  3. 大量消息被重复投递,实际有效消费低,通常是 ack 超时、处理异常或重投递配置不当。