【消息队列】Kafka如何实现高性能IO

我们直到Kafka是一个自称高性能的消息队列引擎,一般来说对于中间件的设计需要从计算、存储、网络三方面进行下手,而消息从产生到消费,也会经历多个流程,比如在生产者端采用异步\同步方式发送,采用高效的压缩算法,高效的序列化方式,以及网络IO等。那么Kafka主要实现高性能IO的。

批量消息发送

我们直到通过send方法,不管是同步还是异步方式,消息都会直接先暂存到内存中,然后等够一批数据消息后,才会发送到broker端,而Broker端不会将消息进行拆解,而是按照一个批量消息为一个单位进行处理,我们假设处理一个单条消息到Broker端需要1ms,那么需要1S中最多处理1000个消息,但是如果是批量发送,那么1S中处理的消息肯定是对于1000个消息的。因为这个途中会涉及本地IO、网络IO、数据拷贝等。
构建批消息和解开批消息分别在发送端和消费端的客户端完成,不仅减轻了 Broker 的压力,最重要的是减少了 Broker 处理请求的次数,提升了总体的处理能力。

顺序读写提升磁盘 IO 性能

我们直到磁盘顺序读写要比随机读写速度快很多,最根本的是可以减少寻址操作。

Kafka也利用这个顺序读写的机制,来提升IO性能,在消息发送到Broker的时候,会按照分区 将消息顺序写到Log文件中,而消费者在消费的时候,也是按照log文件进行读。当一个文件写完或者读完就会生成下一个文件。
充分利用了顺序读写这个特性,极大提升了 Kafka 在使用磁盘时的 IO 性能。

PageCache 加速消息读写

在 Kafka 中,它会利用 PageCache 加速消息读写。PageCache 是现代操作系统都具有的一项基本特性。通俗地说,PageCache 就是操作系统在内存中给磁盘上的文件建立的缓存。无论我们使用什么语言编写的程序,在调用系统的 API 读写文件的时候,并不会直接去读写磁盘上的文件,应用程序实际操作的都是 PageCache,也就是文件在内存中缓存的副本。
【消息队列】Kafka如何实现高性能IO_第1张图片
写数据流程,应用程序在写入数据的时候,先将数据写入到PageCache中,然后在一批批写入到磁盘中。
读数据流程,一个是pageCache中有数据,直接返回。没有数据从磁盘中读取到数据后,写入到pageCahce中,这个之后从pageCache读取数据。
数据淘汰算法,采用LRU 可以将最近写入的数据,提升读的能力。
Kafka 在读写消息文件的时候,充分利用了 PageCache 的特性。一般来说,消息刚刚写入到服务端就会被消费,按照 LRU 的“优先清除最近最少使用的页”这种策略,读取的时候,对于这种刚刚写入的 PageCache,命中的几率会非常高。

也就是说,大部分情况下,消费读消息都会命中 PageCache,带来的好处有两个:一个是读取的速度会非常快,另外一个是,给写入消息让出磁盘的 IO 资源,间接也提升了写入的性能

ZeroCopy:零拷贝技术

我们直到服务端Broker在处理消费时候,会先从磁盘上读取数据,如果命中pageCache的话 直接返回,然后将数据读取到应用程序中,通过网络socket发送出去。

未使用零拷贝

  • 先从磁盘读取数据,如果数据在pageCache中返回,没有从磁盘读取。写入到用户缓冲区。然后将用户缓冲区数据写到socket缓冲区,最后写到网卡缓冲区。
    【消息队列】Kafka如何实现高性能IO_第2张图片

使用零拷贝

从图中可以得知 可以把数据直接从pageCache中写到Socke缓冲区中,减少1/2次数据拷贝的过程,而这就是DMA技术,
【消息队列】Kafka如何实现高性能IO_第3张图片

小结

本篇主要介绍了Kafka的高性能IO设计,其实本质上都是从计算、存储、网络三个方面进行入手。而高性能的目的是实现高吞吐量,以及提升系统的并发容量。而高可用则是避免出现单点故障,通过服务冗余、分片、分区等方式实现系统的可用。

你可能感兴趣的:(#,消息队列,kafka,java,分布式)