Kafka为什么快

Kafka是消息中间件,用在大数据领域、流式计算系统、业务系统。

PS: 想着可能业务系统可以不用这么高的吞吐量,如果为了追求延时消息、消息一致性的话,可以考虑RocketMQ。

快的原因有很多,我理解的话,分别有:顺序读写、操作系统内存缓存优势、IO优化下的零拷贝技术、分区存储和读取、批处理和压缩传输。

磁盘的顺序读写

Kafka是将消息记录持久化到本地磁盘中的,会认为磁盘读写性能差,可能会对Kafka性能如何保证提出质疑。

实际上不管是内存还是磁盘,快或慢关键在于寻址的方式,操作系统也对顺序读写的模式做了优化,Kafka就是使用了磁盘顺序读写来提升的性能。Kafka的message是不断追加到本地磁盘文件末尾的,每一个Partition其实都是一个文件。

顺序读写的缺点:没有办法删除数据,所以Kafka是不会删除数据的,它会把所有的数据都保留下来,每个消费者(Consumer)对每个Topic都有一个offset用来表示读取到了第几条数据,offset是由客户端SDK负责保存的,Kafka的Broker完全无视这个东西的存在;SDK会把它保存到zookeeper里面,所以需要给Consumer提供zookeeper的地址

操作系统的 Page Cache

Kafka利用了操作系统本身的Page Cache,就是利用操作系统自身的内存而不是JVM空间内存,好处有:

1、避免Object消耗:如果是使用 Java 堆,Java对象的内存消耗比较大,通常是所存储数据的两倍甚至更多。

2、避免GC:随着JVM中数据不断增多,垃圾回收将会变得复杂与缓慢。

3、操作系统层面的缓存利用率会更高,因为存储的都是紧凑的字节结构而不是独立的对象

4、加入服务进程重启,系统缓存依然不会消失,避免了从硬盘读数据重建缓存的过程。

IO优化的零拷贝

Linux操作系统 “零拷贝” 机制使用了sendfile方法, 允许操作系统将数据从Page Cache 直接发送到网络,只需要最后一步的copy操作将数据复制到 NIC 缓冲区, 这样避免重复复制数据 ,直接将数据从内核空间的读缓冲区直接拷贝到内核空间的socket缓冲区,然后再写入到NIC缓冲区,避免了在内核空间和用户空间之间切换上下文。

PS: 是不是只有Linux有这个优势?

存储数据分区分段+索引Partition Segment

Kafka的message是按topic分类存储的,topic中的数据又是按照一个一个的partition即分区存储到不同broker节点。每个partition对应了操作系统上的一个文件夹,partition实际上又是按照segment分段存储的,为分段后的数据文件建立了索引文件,就是文件系统上的.index文件,提升了数据读取的效率,同时也提高了数据操作的并行度。

批处理

向Kafka写入数据时,一次性写入N条数据,减少网络的IO,而且还会对消息进行压缩。

总结

Kafka把所有的消息都变成一个批量的文件,并且进行合理的批量压缩,减少网络IO损耗,通过mmap提高IO速度,写入数据的时候由于单个Partition是末尾添加,顺序读取所以速度最快,读取数据的时候配合零拷贝技术sendfile输出。

唠嗑广场

南方的热,是高温+高湿,整个人就像在蒸笼里面,整一个就是蒸人肉叉烧包。

北方的热,是高温+干燥,人就像在电烤箱里面,那就是烤串。