Kafka为何如此的快
公司用RabbitMQ作为消息中间件处理业务需求,但是由于业务量大,每当到达请求高峰窗口期,RabbitMQ集群经常性的会假死甚至宕机,导致服务中断,于是决定用Kafka换掉RabbitMQ.自从使用Kafka以后,服务再也没有出现过宕机现象.
Kafka为什么能做到如此高的吞吐量和性能呢?
页缓存
Kafka接收到消息后数据后都会往磁盘上写,我们知道,磁盘的读写性能相比内存差太多了,Kafka频繁的往磁盘读写数据,性能应该是很差的,但事实为何却不是呢?
答案就是Kafka是基于操作系统页缓存来实现文件的写入的.
页缓存page cache是基于内存的缓存,由操作系统管理,当写入文件时,文件系统首先将文件写入到page cache,至于文件合适落盘由操作系统决定,操作系统会在合适的时间(系统空闲时、缓存快满时、缓存的文件大小合适时)将文件刷入磁盘.
正式由于缓存这一步,磁盘的写性能就大大的提升了,因为对Kafka而言,相当于文件写入到了内存里.
更何况Kafka是以顺序写的方式写入数据的,什么是顺序写?
就是将数据插入到文件的末尾,而不是在文件的随机位置修改数据.机械硬盘随机写入数据的时候,磁头会由一个寻址时间的,是比较耗时的,如果是追加到文件末尾的方式写数据,基本上就能达到顺序写的要求,避免了磁头寻址浪费时间.
零拷贝
写数据优化完了,kafka如何优化读数据呢?
我们先来了解下正常操作系统是如何处理数据发送的.
当操作系统收到应用程序的读取数据请求后,首先会在系统缓存中查看有无相关数据,没有的话从磁盘读取数据放到缓存里,然后从缓存里将数据拷贝给应用程序的缓存里,再从应用程序缓存里拷贝数据给操作系统Socket缓冲区,交由后面的网卡发送数据.
仔细看就会发现,这个步骤之间有两次拷贝其实是可以省略的(操作系统拷贝到应用程序, 应用程序由拷贝到操作系统),操作系统为了这两次拷贝,发生了至少三次上下文中断,所以这种方式是比较消耗时间和系统性能的.
Kafka使用的零拷贝技术就是来优化这种冗余操作的.
直接让数据从操作系统缓存中发送到操作系统Socket缓冲区,并且,Kafka并不是直接将数据拷贝到Socket缓冲区,而是将数据的文件描述符拷贝过去,从而节省了两次拷贝,三次系统上下文切换的时间.
总结
其实正常情况下,Kafka读取的数据都会在操作系统缓存中,从磁盘中读取数据的情况占少数.大家会发现,Kafka基本上就是基于内存提供的读写服务,再配合零拷贝技术,所以整体性能很高.