资深程序员多年总结:解密Kafka吞吐量高的原因

发布时间:2026-01-06 点击:1
众所周知kafka的吞吐量比一般的消息队列要高,号称the fastest,那他是如何做到的,让我们从以下几个方面分析一下原因。
生产者(写入数据)生产者(producer)是负责向kafka提交数据的,我们先分析这一部分。
kafka会把收到的消息都写入到硬盘中,它绝对不会丢失数据。为了优化写入速度kafak采用了两个技术,顺序写入和mmfile。
顺序写入因为硬盘是机械结构,每次读写都会寻址->写入,其中寻址是一个“机械动作”,它是最耗时的。所以硬盘最“讨厌”随机i/o,最喜欢顺序i/o。为了提高读写硬盘的速度,kafka就是使用顺序i/o。
通过mmap,进程像读写硬盘一样读写内存(当然是虚拟机内存),也不必关心内存的大小有虚拟内存为我们兜底。
使用这种方式可以获取很大的i/o提升,省去了用户
先复制到内核
zero copy中直接从内核空间(dma的)到内核空间(socket的),然后发送网卡。
这个技术非常普遍,the c10k problem 里面也有很详细的介绍,nginx也是用的这种技术,稍微搜一下就能找到很多资料。
java的nio提供了filechannle,它的transferto、transferfrom方法就是zero copy。
kafka是如何耍赖的?想到了吗?kafka把所有的消息都存放在一个一个的文件中,当消费者需要数据的时候kafka直接把“文件”发送给消费者。这就是秘诀所在,比如:10w的消息组合在一起是10mb的数据量,然后kafka用类似于发文件的方式直接扔出去了,如果消费者和生产者之间的网络非常好(只要网络稍微正常一点10mb根本不是事。。。家里上网都是100mbps的带宽了),10mb可能只需要1s。所以答案是——10w的tps,kafka每秒钟处理了10w条消息。
可能你说:不可能把整个文件发出去吧?里面还有一些不需要的消息呢?是的,kafka作为一个“高级作弊分子”自然要把作弊做的有逼格。zero copy对应的是sendfile这个函数(以linux为例),这个函数接受
out_fd作为输出(一般及时socket的句柄)
in_fd作为输入文件句柄
off_t表示in_fd的偏移(从哪里开始读取)
size_t表示读取多少个
没错,kafka是用mmap作为文件读写方式的,它就是一个文件句柄,所以直接把它传给sendfile;偏移也好解决,用户会自己保持这个offset,每次请求都会发送这个offset。(还记得吗?放在zookeeper中的);数据量更容易解决了,如果消费者想要更快,就全部扔给消费者。如果这样做一般情况下消费者肯定直接就被压死了;所以kafka提供了的两种方式——push,我全部扔给你了,你死了不管我的事情;pull,好吧你告诉我你需要多少个,我给你多少个。
总结kafka速度的秘诀在于,它把所有的消息都变成一个的文件。通过mmap提高i/o速度,写入数据的时候它是末尾添加所以速度最优;读取数据的时候配合sendfile直接暴力输出。阿里的rocketmq也是这种模式,只不过是用java写的。
单纯的去测试mq的速度没有任何意义,kafka这种“暴力”、“流氓”、“无耻”的做法已经脱了mq的底裤,更像是一个暴力的“数据传送器”。所以对于一个mq的评价只以速度论英雄,世界上没人能干的过kafka,我们设计的时候不能听信网上的流言蜚语——“kafka最快,大家都在用,所以我们的mq用kafka没错”。在这种思想的作用下,你可能根本不会关心“失败者”;而实际上可能这些“失败者”是更适合你业务的mq。


一个好的网站管理员每天必须做的几件事
上海seo刑天:关键词密度深度解析
建站公司5点让你明白建设网站流程
营销型网站:网站社交分享按钮怎么放
网站域名DNS被劫持该怎么办
云服务器的性能测试标准
如何写一遍高质量的原创文章?原来都是套路
电商网站设计怎么做好?有什么技巧?