大家好,我是舒怡。Kafka作为消息队列的中坚力量,基本上是每次面试必问的知识点。说到Kafka,大家对它的印象就是快!难以置信的快!所以,Kafka为什么这么快,也是每次面试必问的知识点。对于混迹Java技术圈多年的我来说,Kafka的快速特性已经是胸有成竹了。今天,就带你来一盘吧!Kafka的写入速度非常快,主要得益于其系统架构设计,包括:PageCache批量压缩传输序列、批量写入磁盘多分区分布式存储PageCache学过操作系统的同学都知道内存是一种容易丢失的存储介质,以及磁盘是一种不易丢失的存储介质。但是内存的读写速度快,而磁盘的读写速度慢。为了提高写入磁盘的速度,操作系统会创建一小块内存作为写入磁盘的缓冲区,以提高写入磁盘的速度。这一小块内存称为PageCache。Kafka如此之快的重要原因之一是使用了PageCache。Kafkabroker写消息的时候,并不是直接写文件,而是写到系统的PageCache内存中,然后由操作系统刷写到文件中。这样kafkabroker不直接写文件,而是直接写内存,速度非常快!因为PageCache的存在,所以也就有了所谓的flushing。简单的说就是同步或者异步。同步刷盘可以理解为写入PageCache后直接写入磁盘。这样做的好处是消息不会丢失,缺点是速度慢。异步闪烁则相反。写完PageCache就结束,等待操作系统异步刷入。这里所说的“盘”指的就是“磁盘”。因此Kafka也提供了两个参数来控制flush方式,分别是:log.flush.interval.messages和log.flush.interval.ms。前者是指当数据条数达到时,将消息刷入磁盘。如果希望数据不丢失,必须将其设置为1。后者表示将累积的消息刷新到磁盘的频率。这两个参数中任意一个达到指定值触发写入。批量压缩传输我们都知道Kafka消息是由生产者发送到Kafka服务器,然后由Kafka服务器存储。很多时候,系统的瓶颈不是CPU或磁盘,而是网络带宽,尤其是对于需要在广域网上的数据中心之间发送消息的数据管道。Kafka之所以能够如此之快,重要的原因之一就是采用了批量压缩传输。在Kafka提供的客户端中,每次向Kafka服务器端发送时,并不是一条一条地发送消息,而是一批又一批地发送消息,同时还开启了数据压缩算法。这样一来,每秒只能发送1条消息的能力可以瞬间提升到1000条,甚至10000条。顺序批量写入磁盘当消息到达Kafka服务器时,Kafka将其写入内存,最后需要写入磁盘。我们知道现在的磁盘大部分还是机械结构的(SSD不在讨论范围)。如果消息以随机写入的形式存储在磁盘中,会按照柱面、磁头、扇区的方式进行(寻址过程),缓慢的机械运动(相对于内存)会消耗大量时间,导致磁盘的写入速度。只能达到内存写入速度的百万分之几。为了避免随机写入带来的时间消耗,Kafka采用顺序写入的方式存储数据,减少了寻址时间,大大提高了写入速度。因此,顺序写入磁盘是Kafka速度如此之快的关键原因。其次,Kafka还采用了消息批量写入磁盘的方式,每次写入一批数据,而不是只写入一条消息,大大提高了效率。多分区分布式存储我们知道磁盘写入是有物理限制的。如果同时写入的线程太多,达到了物理极限,那么其他线程就只能等待了。Kafka存储的特点是文件存储小,分为多个Partition,分散在多台机器上。这样在读取的时候就可以充分利用磁盘的IO,从而达到高效读取的目的。试想一下,如果文件太大,只有一个磁盘,磁盘会有多大的压力?总结Kafka的写入过程可以分为向Kafka服务器传输数据,然后将数据写入磁盘。在数据传输阶段,Kafka采用批量压缩的方式,大大增加了每次可以发送的数据量,从而提高了写入速度。在写磁盘环节,通过存储结构的设计,Kafka可以实现批量、顺序写入,从而减少寻盘时间。并且通过小文件的存储,提高了整体磁盘的续航能力。批量写入、压缩传输方式、顺序写入磁盘、小文件多分区,造就了Kafka强大的写入速度!
