kafka为什么是高性能的

1,228 阅读2分钟

1、零拷贝

kafka主要通过两种零拷贝技术:mmap和sendfile

零拷贝不是指不需要拷贝,而是减少那些不必要的拷贝,从而减少额外的开销。

传统的数据传输: image.png

可以看到,第2、3步的内核空间与用户空间的拷贝不仅没有什么帮助反而带来了更多的开销,于是零拷贝就出现了,他可以直接在内核空间进行copy,从内核buffer直接到网卡buffer,跳过CPU拷贝:

image.png

mmap

mmap(Memory Mapped Files)解决的是网络数据落盘。它将磁盘文件映射到内存中,之后通过修改内存来修改文件内容。

需要注意的是,这个方式需要flush才会真正的将数据存入磁盘。kafka为此提供了一个参数(producer.type)来控制是否主动flush,有两个值——sync和async,sync是写入之后立即调用flush然后再返回,async是写入之后不调用flush直接返回。

sendfile

解决的是磁盘到网络数据的传输。操作系统读取磁盘数据到内存缓存后,直接发送给网卡缓存,然后发送网络数据。

2、顺序读写

kafka在写入数据时,只允许向后追加数据,不允许修改已有数据。所以在每个partition当中,数据的顺序是能保证的。

如果topic或partition过多时,可能会导致kafka频繁切换partition,顺序读写不能保障。阿里中间件有一篇文章《Kafka vs RocketMQ——多Topic对性能稳定性的影响》对此进行了测试,结论是当topic数量超过8时,会导致相应时间的剧烈波动。

3、PageCache

PageCache是系统级别的缓存,他可以在数据写到PageCache时就返回,大大增加的写入效率。同时kafka也支持通过参数控制数据是写到PageCache时返回还是落盘时返回。

kafka使用PageCache的好处在于不会消耗JVM的内存,而且内存过大也会导致GC时间增加和频繁的GC,再进而影响kafka的吞吐效率。当JVM崩溃时也不会导致数据丢失,不过如果是服务器崩溃,PageCache中的数据也会丢失。

4、批量操作

kafka允许批量的接收、发送消息,从而增加读写效率

5、数据压缩

kafka支持接收、发送压缩之后的消息,以增加网络传输效率。需要注意的是解压的时候会消耗CPU资源。