08 | SocketServer(中):请求还要区分优先级?
胡夕
你好,我是胡夕。
在上节课,我给你详细地介绍了 Kafka 网络层的架构,以及 SocketServer 组件中的 Acceptor 线程和 Processor 线程是如何利用 Java NIO 实现网络通信的,还简单提到了请求队列和响应队列。
今天,我们接着说 SocketServer 源码,重点学习下社区是如何对不同类型的请求进行优先级划分的。
案例分享
在 Kafka 中,处理请求是不区分优先级的,Kafka 对待所有请求都一视同仁。这种绝对公平的策略有时候是有问题的。我跟你分享一个真实的案例,你就明白了。我敢保证,你在真实的线上系统中一定遇到过类似的问题。
曾经,我们在生产环境中创建过一个单分区双副本的主题,当时,集群中的 Broker A 机器保存了分区的 Leader 副本,Broker B 保存了 Follower 副本。某天,外部业务量激增,导致 Broker A 瞬间积压了大量的未处理 PRODUCE 请求。更糟的是,运维人员“不凑巧”地执行了一次 Preferred Leader 选举,将 Broker B 显式地调整成了 Leader。
这个时候,问题就来了:如果 Producer 程序把 acks 设置为 all,那么,在 LeaderAndIsr 请求(它是负责调整副本角色的,比如 Follower 和 Leader 角色转换等)之前积压的那些 PRODUCE 请求就无法正常完成了,因为这些请求要一直等待 ISR 中所有 Follower 副本同步完成。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入解析了SocketServer源码中对请求优先级划分的实现机制,通过案例和技术概念深入浅出地介绍了其实现原理。文章首先指出不区分优先级可能导致的问题,引出了Data plane和Control plane的概念,以及监听器的作用。随后详细解释了SocketServer类的定义,包括请求队列长度、动态修改配置、Processor线程池、Acceptor线程池等属性。特别强调了Control plane的设置,以及其对应的Processor线程和RequestChannel的特点。文章还介绍了如何设置用于Control plane的监听器,以及请求优先级与Data plane和Control plane的关系。最后,通过实际案例和技术概念,读者能够快速了解SocketServer源码中对请求优先级划分的实现机制,以及其在Kafka中的应用。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Kafka 核心源码解读》,新⼈⾸单¥59
《Kafka 核心源码解读》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(9)
- 最新
- 精选
- 胡夕置顶你好,我是胡夕。我来公布上节课的“课后讨论”题答案啦~ 上节课,咱们重点了解了Kafka中SocketServer组件以及底层网络通信的部分原理。课后我让你思考这样一个问题,即为什么Request队列被设计成线程共享的,而Response队列是线程私有的。我给出关于这个问题的思考:一个可能的原因是Response的发送速度要远大于Request的认领速度,因此让多个线程同时发送Response能大大缓解Broker端Response积压的问题。 okay,你同意这个说法吗?或者说你有其他的看法吗?我们可以一起讨论下。2020-05-0671
- 曾轼麟关于直接将请求队列改造成优先队列,我感觉可能回牺牲一些kafka处理request请求的速度,因为优先队列的出队和入队的时间复杂度为O(logn),而链表下普通队列的出队和入队的时间复杂度为O(1),头入,尾出,使用优先队列可能不是很满足kafka高性能的特点
作者回复: 嗯, 有一定道理~
2020-05-264 - 伯安知心可知data plan和control plan 请求大小不同,而且处理层使用轮询建立连接,会有偏斜。如果在请求队列限制,API层handle处理受影响。
作者回复: 嗯嗯,很有道理~
2020-05-051 - 趁早还是没有看明白dataplane和control plane如何解决 prefer 选主的问题,如果控制队列优先,先切换主从,那堆积在broker a的消息还是没办法得到处理哈
作者回复: 这个方案不是要堆积了之后怎么办的问题,而是要加快leader选举,避免堆积
2020-07-282 - 曾轼麟1、老师在最新的kafka代码中socketServer.startProcessingRequests被替换成了 socketServer.startControlPlaneProcessor(authorizerFutures),socketServer.startDataPlaneProcessors(authorizerFutures)这两个方法
作者回复: 是的是的,所以这也是使用trunk代码讲解有意思的地方。你会发现它不断地演进着。也许今天讲的明天就不适用了,但至少我们可以继续讨论,总比拿一个过时的代码讲要好:)
2020-05-263 - QAQ也可以改成双端队列,左边进去,右边出,然后优先级高的数据不在左边进,而是右边进,已确保可以快速被访问处理。 另外学到现在,架构图什么的偏少,感觉有种为了源码而源码的感觉,缺少一些实际处理吧,例如之前的log部分,到底是如何完整的写入到log和index文件的操作,那些offset,position,relation offset,Leo啥的到底什么关系,另外方案有很多种可选,本来也没有绝对的优劣之分,说清楚重点解决了哪些问题会更好些吧。后面希望老师能完善一些内容~~谢谢了2021-05-1411
- 未设置老师问一下 这个trunk版本代码 是kafka哪个版本的呢2022-11-30归属地:浙江
- 张三丰老师好,这个listen是怎么跟acceptor线程串联起来的呢?2022-05-19
- 胡小禾为什么Request队列被设计成线程共享的,而Response队列是线程私有的 ? 这个不是因为 线程模型设计如此吗?2021-12-05
收起评论