Kafka - 消费者程序仅消费一半分区消息的问题
1. 问题描述
修改安全服务状态有时逻辑正常有时候逻辑不正常,排查incident服务的日志发现消息可以正常发送到 kafka topic ,但是incident-cron 服务有时候有拉取消息的日志有时候没有日志。
kafka 生产者可以将消息正常发送到 kafka topic ,利用 kafka 消费者命令也可以正常消费消息,但是 incident-cron 消费者程序只能消费一半的分区的消息。
2. 分析问题
2.1 是否存在kafka 分区消息积压问题
利用 Python 脚本手动往 kafka topic 发送消息,发现 incident-cron 程序有时候有拉取消息的日志有时候没有。似乎跟分区有关,于是尝试指定消息发送的分区,结果配置的10个分区中,incident-cron程序只有一半分区有拉取消息的日志,另一半的分区没有。初步考虑是否存在消息积压的问题,于是后台利用命令查看 kafka 消费者组的情况,结果为kafka的每个分区都没有积压消息。
./kafka-consumer-groups.sh --bootstrap-server 10.64.32.11:9092 --describe --command-config ./jaas.conf --group test1113
2.2 是否存在消费者组内有多个消费者程序消费消息的问题
kafka 的一个分区只能被同一个消费者组内的一个消费者消费,不同的消费者不能同时消费同一个分区的消息,如果分区的消息被消费者组中的一个消费者消费了,另一个消费者就不会消费。
因此,考虑当前消费者所在的消费者组内是否配置了多个消费者,导致发送到topic中的消息没有被当前消费者消费,而是被其他消费者消费了。
查看消费者组偏移量,消费者情况,消费者所在的broker,以及每个消费者消费的分区:
./kafka-consumer-groups.sh --bootstrap-server 10.64.32.11:9092 --describe --command-config ./jaas.conf --group test1113
I have no name!@kafka-0:/opt/bitnami/kafka/bin$ ./kafka-consumer-groups.sh --bootstrap-server 10.64.32.11:9092 --describe --command-config ./jaas.conf --group incident-cron-incident-service-status
GROUP TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG CONSUMER-ID HOST CLIENT-ID
incident-cron-incident-service-status platform_INCIDENT_SERVICE_SYNC 6 1209410 1209410 0 consumer-incident-cron-incident-service-status-1-4bbd6640-b95c-4e21-9236-ded434896807 /10.65.197.47 consumer-incident-cron-incident-service-status-1
incident-cron-incident-service-status platform_INCIDENT_SERVICE_SYNC 7 1300214 1300214 0 consumer-incident-cron-incident-service-status-1-4bbd6640-b95c-4e21-9236-ded434896807 /10.65.197.47 consumer-incident-cron-incident-service-status-1
incident-cron-incident-service-status platform_INCIDENT_SERVICE_SYNC 8 1298494 1298494 0 consumer-incident-cron-incident-service-status-1-4bbd6640-b95c-4e21-9236-ded434896807 /10.65.197.47 consumer-incident-cron-incident-service-status-1
incident-cron-incident-service-status platform_INCIDENT_SERVICE_SYNC 9 1300379 1300379 0 consumer-incident-cron-incident-service-status-1-4bbd6640-b95c-4e21-9236-ded434896807 /10.65.197.47 consumer-incident-cron-incident-service-status-1
incident-cron-incident-service-status platform_INCIDENT_SERVICE_SYNC 5 1299554 1299554 0 consumer-incident-cron-incident-service-status-1-4bbd6640-b95c-4e21-9236-ded434896807 /10.65.197.47 consumer-incident-cron-incident-service-status-1
incident-cron-incident-service-status platform_INCIDENT_SERVICE_SYNC 4 1212035 1212035 0 consumer-incident-cron-incident-service-status-1-4a5e86cd-f141-402e-bad1-05d301e08f0a /10.65.197.48 consumer-incident-cron-incident-service-status-1
incident-cron-incident-service-status platform_INCIDENT_SERVICE_SYNC 1 1298821 1298821 0 consumer-incident-cron-incident-service-status-1-4a5e86cd-f141-402e-bad1-05d301e08f0a /10.65.197.48 consumer-incident-cron-incident-service-status-1
incident-cron-incident-service-status platform_INCIDENT_SERVICE_SYNC 0 1209955 1209955 0 consumer-incident-cron-incident-service-status-1-4a5e86cd-f141-402e-bad1-05d301e08f0a /10.65.197.48 consumer-incident-cron-incident-service-status-1
incident-cron-incident-service-status platform_INCIDENT_SERVICE_SYNC 2 1296901 1296901 0 consumer-incident-cron-incident-service-status-1-4a5e86cd-f141-402e-bad1-05d301e08f0a /10.65.197.48 consumer-incident-cron-incident-service-status-1
incident-cron-incident-service-status platform_INCIDENT_SERVICE_SYNC 3 1300180 1300180 0 consumer-incident-cron-incident-service-status-1-4a5e86cd-f141-402e-bad1-05d301e08f0a /10.65.197.48 consumer-incident-cron-incident-service-status-1
输出信息结果分析:所有的消费者都属于同一个消费者组 incident-cron-incident-service-status
。
- 第一组消费者(
consumer-incident-cron-incident-service-status-1-4bbd6640-b95c-4e21-9236-ded434896807
)消费了分区 6、7、8、9 和 5。 - 第二组消费者(
consumer-incident-cron-incident-service-status-1-4a5e86cd-f141-402e-bad1-05d301e08f0a
)消费了分区 4、1、0、2 和 3。
该消费者组内有两个消费者,分别消费不同的分区,导致有一半分区的消息没有被 inciden-cron 消费者程序消费。
查看incident-cron 程序部署在哪些租户,结果发现有2个租户【platform 和 test0001】,也就证实了有2个消费者程序,有一半分区的消息没有被 platform 租户侧的 inciden-cron 消费者程序消费。而是被 test00001租户侧的 inciden-cron 消费者程序消费了。
[root@master01 ~]# kubectl get pods --all-namespaces -o wide | grep incident-cron
将test00001侧的 incident-cron 消费者程序关闭。
[root@master01 ~]# kubectl scale -n test00001 deployment incident-cron --replicas=0