在一个月黑风高的夜晚,突然收到现网生产环境Kafka消息积压的告警,梦中惊醒啊,马上起来排查日志。

问题现象

消费请求卡死在查找Coordinator

Coordinator为何物?Coordinator用于管理Consumer Group中各个成员,负责消费offset位移管理和Consumer Rebalance。Consumer在消费时必须先确认Consumer Group对应的Coordinator,随后才能join Group,获取对应的topic partition进行消费。

那如何确定Consumer Group的Coordinator呢?分两步走:

1、一个Consumer Group对应一个__consumers_offsets的分区,首先先计算Consumer Group对应的__consumers_offsets的分区,计算公式如下:

__consumers_offsets partition# = Math.abs(groupId.hashCode() % groupMetadataTopicPartitionCount,其中groupMetadataTopicPartitionCount由offsets.topic.num.partitions指定。

2、1中计算的该partition的leader所在的broker就是被选定的Coordinator。

定位过程

Coordinator节点找到了,现在看看Coordinator是否有问题:

不出所料,Coordinator对应分区Leader为-1,消费端程序会一直等待,直到Leader选出来为止,这就直接导致了消费卡死。

为啥Leader无法选举?Leader选举是由Controller负责的。Controller节点负责管理整个集群中分区和副本的状态,比如partition的Leader选举,topic创建,副本分配,partition和replica扩容等。现在我们看看Controller的日志:

1.6月10日15:48:30,006 秒Broker 1成为controller

此时感知的节点为1和2,节点3 在zk读不出来:

31秒847的时候把__consumer_offsets的分区3的Leader选为1,ISR为[1,2],leader_epoch为14:

再过1秒后才感知到Controller发生变化,自身清退

2.Broker 2在其后几百毫秒后(15:48:30,936)也成为Controller

但是Broker2 是感知到Broker 3节点是活的,日志如下:

注意这个时间点,Broker1还没在zk把__consumer_offsets的分区3 的Leader从节点3改为1,这样Broker 2还认为Broker 3是Leader,并且Broker 3在它认为是活的,所以不需要重新选举Leader。这样一直保持了相当长的时间,即使Broker 1已经把这个分区的Leader切换了,它也不感知。

3.Broker 2在12号的21:43:19又感知Broker 1网络中断,并处理节点失败事件:

因为Broker 2内存中认为__consumer_offsets分区3的Leader是broker 3,所以不会触发分区3的Leader切换。

Broker 2但是在处理失败的节点Broker 1时,会把副本从ISR列表中去掉,去掉前会读一次zk,代码如下:

但是发现zk中分区3的Leader已经变为1,ISR列表为[1,2],当要去掉的节点1就是Leader的时候,Leader就会变为-1, ISR只有[2],从日志也可以看到:

这样分区3 的Leader一直为-1,直到有新的事件触发节点2重新选举才能恢复(例如重启某个节点)。

根因总结

出现网络异常后,由于新老controller之间感知的可用节点不同,导致新controller对某个分区的Leader在内存中的信息与zk记录元数据的信息不一致,导致controller选举流程出现错误,选不出Leader。 需要有新的选举事件才能触发Leader选出来,例如重启。

问题总结

这是一个典型的由于网络异常导致脑裂,进而出现了多个Controller,华为云分布式消息服务(DMS)Kafka经过电信级的可靠性验证,已经完美解决了这些问题,点击这里了解更多~

Kafka无法消费!?究竟是bug的“沦陷”还是配置的“扭曲”?的更多相关文章

  1. Kafka重复消费和丢失数据研究

    Kafka重复消费原因 底层根本原因:已经消费了数据,但是offset没提交. 原因1:强行kill线程,导致消费后的数据,offset没有提交. 原因2:设置offset为自动提交,关闭kafka时 ...

  2. Flume简介与使用(三)——Kafka Sink消费数据之Kafka安装

    前面已经介绍了如何利用Thrift Source生产数据,今天介绍如何用Kafka Sink消费数据. 其实之前已经在Flume配置文件里设置了用Kafka Sink消费数据 agent1.sinks ...

  3. IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?

    1.前言 IM的群聊消息,究竟存1份(即扩散读方式)还是存多份(即扩散写方式)? 上一篇文章<IM群聊消息的已读回执功能该怎么实现?>是说,“很容易想到,是存一份”,被网友们骂了,大家争论 ...

  4. Kafka 温故(五):Kafka的消费编程模型

    Kafka的消费模型分为两种: 1.分区消费模型 2.分组消费模型 一.分区消费模型 二.分组消费模型 Producer : package cn.outofmemory.kafka; import ...

  5. kafka查看消费数据

    一.如何查看 在老版本中,使用kafka-run-class.sh 脚本进行查看.但是对于最新版本,kafka-run-class.sh 已经不能使用,必须使用另外一个脚本才行,它就是kafka-co ...

  6. kafka多线程消费及处理和手动提交处理方案设计[转]

    转自:http://blog.csdn.net/haoyifen/article/details/54692503 kafka与其他消息队列不同的是, kafka的消费者状态由外部( 消费者本身或者类 ...

  7. kafka 多线程消费

    一. 1.Kafka的消费并行度依赖Topic配置的分区数,如分区数为10,那么最多10台机器来并行消费(每台机器只能开启一个线程),或者一台机器消费(10个线程并行消费).即消费并行度和分区数一致. ...

  8. kafka多线程消费

    建立kafka消费类ConsumerRunnable ,实现Runnable接口: import com.alibaba.fastjson.JSON; import com.alibaba.fastj ...

  9. 【SparkStreaming学习之四】 SparkStreaming+kafka管理消费offset

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 scala-2.10.4(依赖jdk1.8) spark ...

随机推荐

  1. java树型结构的数据展现设计

    在做一个需求管理的页面时,需求的展现是不限层级树型结构,需求下还可以分拆任务,页面要展现的字段有20多个,而且需求采用通用表单设计,db采用大宽表存储,有一百多个字段.目前数据量不大,第一版采用普通的 ...

  2. Tcl之Math

    expr is for Tcl to do math operations. It takes all of its arguments ("2 + 2" for example) ...

  3. Shell基础笔记一

    由于工作需要,开始学习Shell编程,都是一些简单的基础知识,现整理收集分享出来,希望对大家有帮助 -------------------------------------------------- ...

  4. Computed Properties vs Property Requirements - protocol

    In addition to stored properties, classes, structures, and enumerations can define computed properti ...

  5. Invalid character found in the request target.The valid characters are defined in RFC 7230 and RFC3986

    Tomcat在 7.0.73, 8.0.39, 8.5.7 版本后,添加了对于http头的验证. 具体来说,就是添加了些规则去限制HTTP头的规范性 参考这里 具体来说: org.apache.tom ...

  6. Python之TCP编程

    参考原文 廖雪峰Python教程 客户端 我们知道每一条TCP的连接有2个端点,这两个端点叫做套接字socket.如果我们要进行基于TCP的通信必须先创建套接字.在Python中可以这样创建套接字so ...

  7. Spring事物不回滚

    今天发现个自己的bug,仔细排查后,发现根本原因我在service方法中抛出的异常被控制层的方法捕获了,所以后台页面也只是出现个错误提示,而数据却没有回滚. 解决方式:对自己抛出的异常使用try ca ...

  8. 字符串系列——KMP模板整理

    KMP模板整理 KMP与扩展KMP: /*vs 2017/ vs code以外编译器,去掉windows.h头文件和system("pause");*/ #include<i ...

  9. Diango REST framework 视图继承图

  10. APUE 文件和目录

    文件和目录 Unix 所有的文件都对应一个 struct stat,包含了一个文件所有的信息. #include <sys/stat.h> struct stat { mode_t st_ ...