Kafka速度为什么快

    在之前的《Kafka基本概念整理》文章中曾经说过,Kafka中一个Topic会分成多个Partition,并且每个Partition都有一个leader和零或多个followers。所有的读写操作都由leader处理,一般分区的数量都比broker的数量多的多,各分区的leader均匀的分布在brokers中。

    本篇文章来说明下Kafka速度为什么这么快的原因,核心就是Memory Mapped Files(pagecache) + 顺序写 + sendfile(零拷贝) + 压缩

 

 

Kafka写为什么快:

    之前文章说过,Kafka使用一堆日志文件来保存单个Partition中的数据的。数据写入如下图所示,Kafka会把数据追加到文件末尾(虚框部分):

    由于文件是追加写,故实现了对磁盘文件的顺序写,避免磁盘随机写时的磁盘寻道的开销(实际场景中,由于其他程序也要读写磁盘,所以寻址操作不可避免,不过这样也比随机写要快的多)。

   追加写有一个缺点,就是无法删除指定的数据,只能通过配置保存时间或者文件大小的方式,批量将不符合条件的数据删除。Kafka提供两种删除策略,一是基于时间,二是基于Partion文件大小。

    除了顺序写之外,Kafka还使用了Memory Mapped Files(内存映射文件),它利用了操作系统的Page来实现文件到物理内存的映射,完成之后对物理内存的操作会直接同步到硬盘,这样大大提高了IO速率。使用这种方式可以省去用户空间到内核空间复制的开销(调用文件的read会把数据先放到内核空间的内存中,然后再复制到用户空间的内存中)。

 

   但是它的缺点也显而易见--不可靠,当发生宕机而数据未同步到硬盘时,数据会丢失,所以Kafka提供了produce.type参数来控制是否主动的进行刷新,如果kafka写入到mmp后立即flush再返回给生产者则为同步模式,反之为异步模式。

 

Kafka读为什么快:

    Consumer在读取数据时底层使用了sendfile方法(网络文件传输专用方法),sendfile方法可以避免了内核缓冲区和用户缓冲区之间的数据拷贝,效率很高,被称为零拷贝。

   使用普通方法读取文件时,先将磁盘上的文件拷贝到内核缓冲区中,然后再讲内核缓冲区的数据拷贝到用于应用程序的缓冲区中(理解成JVM堆中),然后再讲数据拷贝到socket相关的缓冲区中,最后再拷贝到相关的协议引擎,需要经历四次拷贝操作!

   使用sendfile之后就可以无视用户缓存区,直接从内核缓存区(磁盘)到socket缓冲区。

 

 

    同时Kafka0.7版本之后就支持压缩功能,可以提高读写的速度。Kafka就是基于如上这些底层Linux提供的技术实现高吞吐!

 

 

参考:

https://blog.csdn.net/im_cheer/article/details/89811004

https://www.cnblogs.com/MrVolleyball/archive/2019/08/15/11355971.html(磁盘随机读写与顺序读写)

https://www.jianshu.com/p/d69e27749b00(Kafka压缩)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值