Kafka核心源码解读
胡夕
Apache Kafka Committer,老虎证券技术总监
立即订阅
3904 人已学习
课程目录
已完结 44 讲
0/4登录后,你可以任选4讲全文学习。
课前必学 (3讲)
开篇词 | 阅读源码,逐渐成了职业进阶道路上的“必选项”
免费
导读 | 构建Kafka工程和源码阅读环境、Scala语言热身
重磅加餐 | 带你快速入门Scala语言
日志模块 (5讲)
01 | 日志段:保存消息文件的对象是怎么实现的?
02 | 日志(上):日志究竟是如何加载日志段的?
03 | 日志(下):彻底搞懂Log对象的常见操作
04 | 索引(上):改进的二分查找算法在Kafka索引的应用
05 | 索引(下):位移索引和时间戳索引的区别是什么?
请求处理模块 (5讲)
06 | 请求通道:如何实现Kafka请求队列?
07 | SocketServer(上):Kafka到底是怎么应用NIO实现网络通信的?
08 | SocketServer(中):请求还要区分优先级?
09 | SocketServer(下):请求处理全流程源码分析
10 | KafkaApis:Kafka最重要的源码入口,没有之一
Controller模块 (5讲)
11 | Controller元数据:Controller都保存有哪些东西?有几种状态?
12 | ControllerChannelManager:Controller如何管理请求发送?
13 | ControllerEventManager:变身单线程后的Controller如何处理事件?
14 | Controller选举是怎么实现的?
15 | 如何理解Controller在Kafka集群中的作用?
状态机模块 (3讲)
16 | TopicDeletionManager: Topic是怎么被删除的?
17 | ReplicaStateMachine:揭秘副本状态机实现原理
18 | PartitionStateMachine:分区状态转换如何实现?
延迟操作模块 (2讲)
19 | TimingWheel:探究Kafka定时器背后的高效时间轮算法
20 | DelayedOperation:Broker是怎么延时处理请求的?
副本管理模块 (6讲)
21 | AbstractFetcherThread:拉取消息分几步?
22 | ReplicaFetcherThread:Follower拉取Leader消息是如何实现的?
23 | ReplicaManager(上):必须要掌握的副本管理类定义和核心字段
24 | ReplicaManager(中):副本管理器是如何读写副本的?
25 | ReplicaManager(下):副本管理器是如何管理副本的?
26 | MetadataCache:Broker是怎么异步更新元数据缓存的?
消费者组管理模块 (7讲)
27 | 消费者组元数据(上):消费者组都有哪些元数据?
28 | 消费者组元数据(下):Kafka如何管理这些元数据?
29 | GroupMetadataManager:组元数据管理器是个什么东西?
30 | GroupMetadataManager:位移主题保存的只是位移吗?
31 | GroupMetadataManager:查询位移时,不用读取位移主题?
32 | GroupCoordinator:在Rebalance中,Coordinator如何处理成员入组?
33 | GroupCoordinator:在Rebalance中,如何进行组同步?
特别放送 (5讲)
特别放送(一)| 经典的Kafka学习资料有哪些?
特别放送(二)| 一篇文章带你了解参与开源社区的全部流程
特别放送(三)| 我是怎么度过日常一天的?
特别放送(四)| 20道经典的Kafka面试题详解
特别放送(五) | Kafka 社区的重磅功能:移除 ZooKeeper 依赖
期中、期末测试 (2讲)
期中测试 | 这些源码知识,你都掌握了吗?
期末测试 | 一套习题,测试你的掌握程度
结束语 (1讲)
结束语 | 源码学习,我们才刚上路呢
Kafka核心源码解读
15
15
1.0x
00:00/00:00
登录|注册

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

胡夕 2020-05-19
你好,我是胡夕。 今天,我们来学习下 Controller 的单线程事件处理器源码。
所谓的单线程事件处理器,就是 Controller 端定义的一个组件。该组件内置了一个专属线程,负责处理其他线程发送过来的 Controller 事件。另外,它还定义了一些管理方法,用于为专属线程输送待处理事件。
在 0.11.0.0 版本之前,Controller 组件的源码非常复杂。集群元数据信息在程序中同时被多个线程访问,因此,源码里有大量的 Monitor 锁、Lock 锁或其他线程安全机制,这就导致,这部分代码读起来晦涩难懂,改动起来也困难重重,因为你根本不知道,变动了这个线程访问的数据,会不会影响到其他线程。同时,开发人员在修复 Controller Bug 时,也非常吃力。
鉴于这个原因,自 0.11.0.0 版本开始,社区陆续对 Controller 代码结构进行了改造。其中非常重要的一环,就是将多线程并发访问的方式改为了单线程的事件队列方式
这里的单线程,并非是指 Controller 只有一个线程了,而是指对局部状态的访问限制在一个专属线程上,即让这个特定线程排他性地操作 Controller 元数据信息。
这样一来,整个组件代码就不必担心多线程访问引发的各种线程安全问题了,源码也可以抛弃各种不必要的锁机制,最终大大简化了 Controller 端的代码结构。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Kafka核心源码解读》,如需阅读全部文章,
请订阅文章所属专栏新⼈⾸单¥19.9
立即订阅
登录 后留言

精选留言(6)

  • 胡夕 置顶
    你好,我是胡夕。我来公布上节课的“课后讨论”题答案啦~

    上节课,咱们重点了解了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
    2
    1
  • huldar
    QueuedEvent 使用CountDownLatch的唯一目的,是确保 Expire 事件在建立 ZooKeeper 会话前被处理。这个没有理解,可以麻烦解释下吗?谢谢

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

    2020-07-30
    1
  • 伯安知心
    本人最近找大数据开发运维之类的工作,有没有推荐呢?各位亲
    2020-05-20
  • RonnieXie
    目前我学习的源码,理解到ControllerEventThread也是只有一个进程处理,
    是否实现ControllerEventThread每个Broker都创建专属的线程,就可以同时优化RequestSendThread和ControllerEventThread单经常处理的缺点?

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

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

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

    2020-05-20
    1
收起评论
6
返回
顶部