kafka速度快的原因分析

        Apache Kafka基准测试:三台普通机器上每秒写入2百万消息。kafka之所以速度快,这里主要从下面几方面进行分析。

1 写数据

1.1 顺序写磁盘

在顺序磁盘IO,速度可以比内存随机IO更快。

Kafka官方给出的测试数据(Raid-5, 7200rpm)

  • 顺序I/O: 600MB/s
  • 随机I/O: 100KB/s

顺序读写磁盘优势

  • 磁盘顺序读写速度超过内存随机读写
  • 使用磁盘可以避免JVM的GC操作,GC效率低,内存占用大
  • 磁盘支持系统冷启动,内存不支持,会丢数据

顺序读写磁盘劣势

  • 不支持随机删除数据
  • 要么基于过期时间删除数据
  • 要么基于partition文件大小删除数据

1.2 mmap(内存映射)

        Kafka的数据并 不是实时的写入硬盘 ,它充分利用了现代操作系统 分页存储 来利用内存提高I/O效率。mmap在64位操作系统中一般可以表示20G的数据文件,它的工作原理是直接利用操作系统的Page来实现文件到物理内存的直接映射,完成映射之后对物理内存的操作会被同步到硬盘上(操作系统在适当的时候)。

mmap优势

  • 通过mmap进程像读写硬盘一样读写虚拟机内存,不必关心内存的大小
  • 极大提升I/O性能, 省去了用户空间和内核空间的两次拷贝开销,但增加了一内核空间的拷贝

mmap劣势

  • mmap不可靠。写到mmap中的数据并没有被真正的写到硬盘,操作系统会在程序主动调用flush的时候才把数据真正的写到硬盘。 解决方法:Kafka提供了一个参数producer.type控制是不是主动flush,如果Kafka写入到mmap之后就立即flush然后再返回Producer叫 同步 (sync);写入mmap之后立即返回Producer不调用flush叫 异步 (async)。
  • 不适合变长文件读写;不适合大量更新文件操作。不过这两个 劣势在kafka中都不存在。

2 读数据

2.1 零拷贝

        传统网络文件传统,需要4次拷贝(两次cpu拷贝、两次DMA拷贝)、两次上下文切换,系统开销大。

硬盘-->内核buf-->用户buf-->内核buf(socket buf)-->NIC

kafka用了sendfile系统调用,极大提升了性能。

  • 在内核版本2.1中,引入了sendfile系统调用,只需要三次拷贝(1次CPU拷贝、两次DMA拷贝)、0次上下文切换。

硬盘-->内核buf-->内核buf(socket buf)-->NIC

  • 在内核版本2.4中,sendfile实现了更简单的方式,只需要2次拷贝(两次DMA拷贝)、0次上下文切换,做到真正意义上的cpu零拷贝。

硬盘-->内核buf-->NIC

3 Page Cache(页缓存)

        Kafka还利用了操作系统本身的Page Cache来优化读写性能,就是利用操作系统自身的内存而不是JVM内存。

使用JVM内存有两个明显缺点:

  •     Object消耗:如果是使用Java 堆,Java对象的内存消耗比较大,通常是所存储数据的两倍甚至更多
  •     GC问题:随着JVM中数据不断增多,垃圾回收将会变得复杂与缓慢,使用系统缓存如Page Cache就不会有这问题

    相比于使用JVM或in-memory cache等数据结构,利用操作系统的Page Cache更加简单可靠,有其独特优势:

  • 操作系统层面的缓存利用率会更高,因为存储的都是紧凑的字节结构而不是独立的对象
  • 操作系统本身也对于Page Cache做了大量优化,提供了 write-behind、read-ahead以及flush等多种机制
  • 即使服务进程重启,系统缓存依然不会消失,避免了in-process cache重建缓存的过程
  • 通过操作系统的Page Cache,Kafka的读写操作基本上是基于内存的,读写速度得到了极大的提升

4 网络IO优化

在很多情况下,系统的瓶颈不是CPU或磁盘,而是网络IO。数据压缩会消耗少量的CPU资源,不过对于kafka这样的大型分布式消息系统而言,网络IO更应该需要考虑。

4.1 批量发送

        Kafka允许进行批量消息发送,先将消息缓存在buffer中,然后一次请求批量发送出去,比如可以指定缓存的消息达到某个量的时候发送,或者缓存了固定的时间后发送,这种策略大大减少了服务器端的I/O次数。

4.2 批量压缩

  • 使用了批量压缩,即将多个消息一起压缩而不是单个消息压缩
  • 通过压缩的形式传输并且在日志中保存,直到被消费者解压缩
  • Kafka支持多种压缩协议,包括Gzip和Snappy压缩协议

5 文件分段+文件索引

5.1 文件分段

        Kafka 的队列 topic 被分为多个区 partition, 每个 partition 又分为多个 segment,所以一个队列中的消息实际上是保存在 N 多个片段文件中,就是文件系统上的.log文件,这也非常符合分布式系统分区分桶的设计思想。通过分段的方式,每次文件操作都是对一个小文件的操作,非常轻便,同时也增加了并行处理能力。

5.2 文件索引

        为了进一步的查询优化,Kafka又默认为分段后的数据文件建立了索引文件,就是文件系统上的.index文件。这种分区分段+索引的设计,不仅提升了数据读取的效率,同时也提高了数据操作的并行度。

参考

https://www.cnblogs.com/binyue/p/10308754.html

https://cloud.tencent.com/developer/article/1495023

https://blog.csdn.net/kzadmxz/article/details/101576401

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值