Kafka 核心源码解读
胡夕
Apache Kafka Committer,老虎证券技术总监
19216 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 44 讲
结束语 (1讲)
Kafka 核心源码解读
15
15
1.0x
00:00/00:00
登录|注册

13 | ControllerEventManager:变身单线程后的Controller如何处理事件?

你好,我是胡夕。 今天,我们来学习下 Controller 的单线程事件处理器源码。
所谓的单线程事件处理器,就是 Controller 端定义的一个组件。该组件内置了一个专属线程,负责处理其他线程发送过来的 Controller 事件。另外,它还定义了一些管理方法,用于为专属线程输送待处理事件。
在 0.11.0.0 版本之前,Controller 组件的源码非常复杂。集群元数据信息在程序中同时被多个线程访问,因此,源码里有大量的 Monitor 锁、Lock 锁或其他线程安全机制,这就导致,这部分代码读起来晦涩难懂,改动起来也困难重重,因为你根本不知道,变动了这个线程访问的数据,会不会影响到其他线程。同时,开发人员在修复 Controller Bug 时,也非常吃力。
鉴于这个原因,自 0.11.0.0 版本开始,社区陆续对 Controller 代码结构进行了改造。其中非常重要的一环,就是将多线程并发访问的方式改为了单线程的事件队列方式
这里的单线程,并非是指 Controller 只有一个线程了,而是指对局部状态的访问限制在一个专属线程上,即让这个特定线程排他性地操作 Controller 元数据信息。
这样一来,整个组件代码就不必担心多线程访问引发的各种线程安全问题了,源码也可以抛弃各种不必要的锁机制,最终大大简化了 Controller 端的代码结构。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kafka的ControllerEventManager是用于处理Controller端事件的单线程事件处理器。在0.11.0.0版本之前,Controller组件的源码非常复杂,因为集群元数据信息在程序中同时被多个线程访问,导致代码晦涩难懂且改动困难。为了解决这一问题,社区对Controller代码结构进行了改造,将多线程并发访问的方式改为了单线程的事件队列方式,从而简化了Controller端的代码结构。文章介绍了Controller单线程事件队列处理模型及其基础组件,包括ControllerEventProcessor、ControllerEvent、ControllerEventManager和QueuedEvent。通过学习这些组件的源码,读者可以深入了解Controller端处理各类事件的原理,从而提升在实际场景中处理Controller各类问题的能力。 文章详细介绍了ControllerEventThread类的定义和执行流程,以及ControllerEventProcessor的实现。此外,还讨论了put方法和clearAndPut方法的重要性,以及对其是否需要被锁保护的看法。总结了ControllerEvent、ControllerState、ControllerEventManager和ControllerEventThread等关键组件的作用和关系。 总的来说,本文通过深入分析Kafka的ControllerEventManager,帮助读者了解了Kafka Controller端的事件处理机制,为读者提升在实际场景中处理Controller各类问题的能力提供了重要参考。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Kafka 核心源码解读》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(11)

  • 最新
  • 精选
  • 胡夕
    置顶
    你好,我是胡夕。我来公布上节课的“课后讨论”题答案啦~ 上节课,咱们重点了解了Controller通道管理器类ControllerChannelManager。课后我请你思考这样一个问题,即为每个Broker都创建一个RequestSendThread的方案有什么优缺点。Controller为每个Broker都创建专属的线程,可以隔离与其他Broker之间的交互,代码实现起来也容易,没有额外线程安全方面的开销。不过消耗资源也要更多,毕竟线程是需要操作系统分配一定内存和其他资源的。总的来看,专属线程的收益还是要大过于它的开销。 okay,你同意这个说法吗?或者说你有其他的看法吗?我们可以一起讨论下。
    2020-05-19
    2
  • 曾轼麟
    ControllerEventManager ,我觉得其实put 方法被Lock包围起来其实问题不大: 【首先】,目前的put方法是单线程的加上或者不加上Lock其实对实际业务的处理影响并不大。 【再者】,putLock是基于ReentrantLock,本质是AQS,既然是AQS那么在当线程的情况下本质上是不会像synchronized那样可能会进入内核态,跟多的时候可能只是一个CAS是判断而已,不会抢占也不会对性能产生较大的影响。 【最后】,通过加入lock可以起到一个兜底的效果,避免在版本和功能迭代过程中出现一些意想不到的并发问题。 总而言之就是,既然对性能影响不大,那么可以对编码要求苛刻一些

    作者回复: 非常同意:)

    2020-06-07
    3
    8
  • 对与错
    请问KafkaRequestHandle和ControllerEventThread之间有没有啥联系?

    作者回复: 没有关系。前者是broker处理外部请求的线程;后者是Controller所在broker处理Controller事件的线程

    2020-09-18
    1
  • Drake Wang
    put() 和 clearPut() 两个方法对共享队列执行写操作,为了保证线程安全,加锁是必要的吧?

    作者回复: LinkedBlockingQueue本身也是线程安全的,而且这里不是复合方法,所以我依然觉得更多的是一种防御性编程

    2020-12-02
  • huldar
    QueuedEvent 使用CountDownLatch的唯一目的,是确保 Expire 事件在建立 ZooKeeper 会话前被处理。这个没有理解,可以麻烦解释下吗?谢谢

    作者回复: 主要是为了确保抢占式的事件优先被处理

    2020-07-30
    3
  • RonnieXie
    目前我学习的源码,理解到ControllerEventThread也是只有一个进程处理, 是否实现ControllerEventThread每个Broker都创建专属的线程,就可以同时优化RequestSendThread和ControllerEventThread单经常处理的缺点?

    作者回复: 嗯,也许是个不错的方案。你可以尝试实现下,可能是个很好的功能改进

    2020-05-20
  • 伯安知心
    从put代码看,只有2步骤,增加时间戳封装队列事件,然后加入linked有序阻塞队列,也许kafka是为了保持加入顺序吧,但是这个阻塞队列本身就是线程安全的,确实有些鸡肋,个人观点。

    作者回复: 有一定道理;0

    2020-05-20
    2
  • xyzker
    put方法不仅会跟自己并发,也会和clearAndPut方法并发,不加锁的话行为会不确定:有可能clearAndPut刚调用queue.clear(),put方法又加进来一个event,无法保证clearAndPut方法的原子性。
    2022-05-10
    1
  • z.l
    『该线程排他性地读取事件队列』请问这里的『排他』怎么理解?
    2022-08-31归属地:上海
  • 对与错
    请问ControllerBrokerRequestBatch类里面的sendEvent和sendRequest有什么意义?我看源码里面是发送请求收到响应之后再来进行sendEvent的回调工作,是为了先把请求发送出去由controller所在的broker处理完成之后,再来发送event给其他的broker吗?
    2020-09-21
收起评论
显示
设置
留言
11
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部