Kafka的吞吐量毋庸置疑,可以达到单节点每秒2000万条数据
如何做到如此高的性能的呢?
可以从以下几个角度来看
1.批处理提升系统吞吐量
2.磁盘的顺序读写提高吞吐量
3.利用了操作系统的PageCache,减少了IO
4.利用了零拷贝增加消费
接下来我们分别说一下这些处理的具体实现方法
1.批处理的流程
Kafka内部是批处理的,先从发送端来看,也就是Producer这一端,虽然Kafka的客户端的SDK中,Kafka的Producer只提供单条发送send()方法,没有提供任何的接口,Kafka根本没有提供批量发送的能力,而是先放到内存中,选择合适的时机一批的发送给Broker,攒一波发一波
然后是Broker的Broker这一端,也是一批批的处理的,将这一批的消息当做一个批消息来处理,整个Broker的处理流程中,无论是写入磁盘,还是从磁盘读出来,都是作为一条批消息来进行处理的
在消费的时候,消费也是作为批的单位进行传递的,Consumer从Broker拉倒一批消息之后,一条条的处理
利用构建批消息和解开批消息分开,增加了整体的吞吐量
2.使用顺序读写提升磁盘IO性能
顺序读写比随机读写省去了大部分的寻址时间,是需要寻址一次,就可以连续的读写下去,性能要比随机读写要好得多
3.利用PageCache来加速消息读写
在Kafka中,利用PageCache来加速消息读写,调用系统API读写文件的时候,不会直接读写磁盘文件,而是利用PageCache接口
所以Kafka在读写消息文件时候,利用了PageCache的特性,消息端写入到服务端就会被消费,利用LRU的优先清除最少使用的也,增加PageCache的命中率
4.ZeroCopy 零拷贝
Kafka的服务端在消费的时候,利用了一种零拷贝的操作系统来增加性能
服务端的消费逻辑是
首先找到消息数据,读到内存
然后在利用网络发给客户端
这样,实际上数据做了多次的赋值
1,文件复制到PageCache中
2.PageCache复制到应用程序的内存空间
3.应用程序的内存复制到Socket中,调用网络框架API发送数据
Kafka利用了零拷贝,将上面的2和3合并为一个复制,
减少了一次数据复制,不用将数据复制到用户内存汇总
DMA直接完成数据复制,不用CPU参与,速度快