news 2026/7/28 21:34:22

深入理解kafka

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入理解kafka

文章目录

        • 前言
        • 1、kafka集群架构图
        • 2、kafka 高性能读写的设计
          • 2.1、利用read-ahead 和 write-behind提升写性能
          • 2.2、使用pagecache缓存程序数据提升读写性能
          • 2.3 通过sendfile(零拷贝机制)提高消费者端的读吞吐量
        • 3、kafka的repilcas副本机制
          • 3.1 主分区的副本
          • 3.2 leade如何管理follower节点
          • 3.3 Replica如何均匀分布到整个kafka集群
        • 4、Kafka消息的ack机制
        • 5、kafka 消息索引机制
        • 6、consumer group的工作机制
          • 6.1 一个topic为何需要被多个consumer消费?
          • 6.2 同一个partition能否被多个consumer同时消费?
          • 6.3 kafka为何设计多个consumer group这样的模型?
            • 6.3.1 无consumer group,应用A和应用B会出现什么情况?
            • 6.3.2 为应用建立consumer group,观测应用A和应用B的情况。
前言

在前面的文章《在hadoopHA节点上部署kafka集群组件》,介绍大数据实时分析平台生态圈组件——kafka,前向用于连接flume,后向连接spark streaming。在研究Kafka过程中,发现该中间件的设计很巧妙,因此专设一篇文章用于深入理解Kafka核心知识。Kafka已经纳入个人目前最欣赏的中间件list:redis,zookeeper,kafka

1、kafka集群架构图

以下为kafka集群一种经典的架构图,该图以《在hadoopHA节点上部署kafka集群组件》文章的kafka集群以及sparkapp topic作为示例绘成,本文的内容将以该图为标准作为说明。
图1 kafka集群架构图

2、kafka 高性能读写的设计
2.1、利用read-ahead 和 write-behind提升写性能

kafka底层设计高度依赖现代磁盘优化技术和文件系统的优化技术。在kafka官方文档的:don’t fear the filesystem章节说明了kafka是如何利用磁盘已有的高性能读写技术:read-ahead 和 write-behind 实现日志在磁盘山高性能顺序写。
read-ahead 是以大的 data block 为单位预先读取数据。write-behind(后写) 是将多个小型的逻辑写合并成一次大型的物理磁盘写入,producer向kafka写入消息日志时,因为消息是一条一条的过来,而且消息本身payload很小,如果每条消息进来立刻执行写入磁盘,显然IO非常高,因此需要将进来的消息先缓存,然后到一定数量或者到一定容量时再触发写入磁盘,kafka用了pagecache实现write-behind而不是通过内存。
官方举例说明用廉价的RAID-5模式sata硬盘可以去到600MB/秒,但随机写入的性能仅约为100k/秒,相差6000倍以上。

2.2、使用pagecache缓存程序数据提升读写性能

同样,在kafka官方文档的:don’t fear the filesystem章节还提到另外一个技术:pagecache。kafka利用了现代操作系统主动将所有空闲内存用作磁盘caching这一机制(代价是在内存回收时性能会有所降低),再次提升基于filesystem的读写性能的效果。
kafka 跑在 jvm之上,那么jvm一定会有复杂的GC情况:

  • 对象的内存开销非常高,通常是所存储的数据的两倍(甚至更多)。
  • 随着堆中数据的增加,Java 的垃圾回收变得越来越复杂和缓慢。

受这些因素影响, 维护in-memory cache就会显得很复杂,而kafka通过文件系统方式和 pagecache 读写消息反而显得更有优势(避免复杂低效率的GC),通过自动访问所有空闲内存将可用缓存的容量至少翻倍,并且通过存储紧凑的字节结构而不是独立的对象,有望将缓存容量再翻一番,例如32GB内存的服务器,它的 pagecache缓存容量可以达到28-30GB,并且不会产生额外的 GC 负担。kafka自己也说还有重要一点:简化核心代码。
为何这么设计?
kafka自己这么解释:因为相比于维护尽可能多的 in-memory cache,并且在空间不足的时候匆忙将消息数据 flush 到文件系统的,kafka写过程把这个过程倒过来:所有消息数据一开始就被写入(write-behind)到文件系统的持久化日志中,而不用在in-memory cache 空间不足的时候 flush 到磁盘。实际上,是先把数据被转移到了内核的 pagecache 中。
这里可以联想到Hbase的MemStore设计:MemStore基于in-memory cache,MemStore 在内存中存在,保存修改key-value数据,当MemStore的大小达到一个阀值(默认64MB)时,MemStore里面的数据会被flush到Hfile文件上,也就是flush到磁盘上。

为何page cache 会加速读过程?
linux的文件cache分为两层,一个是page cache,另一个是buffer cache;每一个page cache包含若干个buffer cache,结构图如下图所示:

page cache:文件系统层级的缓存,从磁盘里读取数据缓存到page cache(属于内核空间,而不是应用用户的空间),这样应用读磁盘数据会被加速,例如使用find等命令查找文件时,第一次会慢很多,第二次查找相同文件时会瞬间读取到。如果page cache的数据被修改过后,也即脏数据,等到写入磁盘时机到来时,会把数据转移到buffer cache 而不是直接写入到磁盘。
buffer cache:磁盘等块设备的缓冲。
大致流程:
page cache其优化读的工作过程如下:
A、文件的第一次读请求
系统读入所请求的page页并读入紧随其后的的少数几个页面,这种读取方式称为同步预读。
B、文件的第二次读请求:
如果page页不在第一次的cache中,说明不是顺序读,所以又会重新继续第一次那种同步预读过程。

如果page页面在cache中,说明是顺序读,Linux会将预读group扩大一倍,继续把不在首次cache中的文件数据读进来,此为异步预读。kafka之所以设计按顺序读写,完全就是按照底层page cahe的这种预读机制来设计,所以在文件系统底层就已经有不错的性能了。

2.3 通过sendfile(零拷贝机制)提高消费者端的读吞吐量

在kafka官方文档的Efficiency章节解释了kafka通过使用sendfile (零拷贝技术)继续提高消费者端的读性能。
前面2.1和2.2解释了kafka里利用相关底层机制,解决了磁盘访问模式不佳的情况。接下来,还需要解决以下两个影响kafka性能的情况:
too many small I/O operations, and excessive byte copying
(大量的小型 I/O 操作以及过多的字节拷贝 )

  • A、 The small I/O problem happens both between the client and the server and in the server’s own persistent operations.
    (大量小型的 I/O 操作表现在client和broker之间以及broker服务端自身持久化操作中)
    解决方式:kafka用一个称为 “消息块” 的抽象基础上,合理将消息分组。 这使得网络请求将多个消息打包成一组,而不是每次发送一条消息,从而使整组消息分担网络中往返的开销。consumer 每次获取多个大型有序的消息块,并由服务端依次将消息块一次加载到它的日志中。
    这个简单的优化对速度有着数量级的提升。批处理允许更大的网络数据包,更大的顺序读写磁盘操作,连续的内存块等等

  • B、excessive byte copying
    另一个低效率的操作是字节拷贝,在消息量少时,这不是什么问题,但是在高负载的情况下,影响就不容忽视。为了避免这种情况,kafka在producer、broker 和 consumer 都是用相同标准化的二进制消息格式,这样数据块不用修改就能在他们之间传递。
    broker 维护的消息日志本身就是一个文件目录,每个segment文件都由一系列以相同格式消息组成,保持这种通用格式将非常有利于消息日志文件的网络传输的效率。 现代的unix 操作系统提供了一个高度优化的编码方式,用于将数据从 pagecache 转移到 socket 网络连接中

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/28 21:33:39

C++跨平台获取CPU温度:WMI与sysfs实现详解

1. 项目概述:为什么我们需要在C中获取CPU温度?在桌面应用开发、系统监控工具编写,甚至是游戏或高性能计算的后台守护进程中,实时获取CPU温度是一个看似小众但实际需求广泛的功能。你可能正在开发一个超频软件,需要监控…

作者头像 李华
网站建设 2026/7/28 21:31:25

Ornith-1.0:Agentic Coding如何实现智能任务规划与代码生成

如果你正在寻找一个能在本地运行、专门解决复杂编程任务的AI助手,那么Ornith-1.0的发布绝对值得你花时间了解。这个刚刚开源的模型家族,不是又一个"全能型"大模型,而是精准定位在"Agentic Coding"——让AI像真正的软件工…

作者头像 李华
网站建设 2026/7/28 21:30:53

为什么你的开源模型推理成本比同行高2.3倍?——基于27个生产环境日志的冷启动延迟、批处理吞吐、显存碎片率深度归因分析

更多请点击: https://kaifayun.com 第一章:为什么你的开源模型推理成本比同行高2.3倍?——基于27个生产环境日志的冷启动延迟、批处理吞吐、显存碎片率深度归因分析 在对27个真实部署场景(涵盖Llama-2-13B、Phi-3-mini、Qwen2-7B…

作者头像 李华
网站建设 2026/7/28 21:30:00

158、【Agent】【OpenCode】TuiThreadCmd(RPC 泛型推导)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除 标题 158、【Agent】【OpenCode】TuiThreadCm…

作者头像 李华
网站建设 2026/7/28 21:28:54

上海创客周末活动指南:RISC-V、AIoT实战与高效参与策略

1. 活动背景与价值解析又到周末了,上海的创客朋友们是不是又在为“去哪儿玩”而发愁?别急,我花了点时间,把本周末(6月14日至15日)上海滩上那些值得一去的创客活动给梳理了出来。作为一个在上海创客圈混迹了…

作者头像 李华
网站建设 2026/7/28 21:27:40

企业部门助手系统配置与优化实践指南

1. 部门助手配置概述在企业日常运营中,部门助手作为连接不同岗位的桥梁,其配置质量直接影响团队协作效率。一个合理配置的部门助手系统能够自动化处理约40%的常规事务,包括日程管理、文件流转、数据收集等基础工作。我在为多个部门搭建助手系…

作者头像 李华