kafka如何做到每秒几十万的吞吐量

kafka读写速度块,是基于两点实现:

1、页缓存技术 + 磁盘顺序写

2、零拷贝技术

页缓存技术 + 磁盘顺序写:

为了保证数据写入性能,首先Kafka是基于操作系统的页缓存来实现文件写入的。其实操作系统本身有一层缓存,叫做page cache是在内存里的缓存,我们也可以称之为os cache ,意思就是操作系统自己管理的缓存,在写入磁盘文件是,先直接写入os cache,然后在有操作系统决定什么时候刷新到磁盘文件中。

kafka如何做到每秒几十万的吞吐量

 我们只是到,普通的写入磁盘是随机读写的,而kafka在写入时是采用顺序读写,追加在文件末尾的。

零拷贝技术:

Kafka里我们经常要消费数据,那么消费的时候实际上就是要从kafka的磁盘文件里读取某条数据然后发送给下游的消费者。

假设要是kafka什么优化都不做,就是很简单的从磁盘读数据发送给下游的消费者,那么大概过程如下所示:

先看看要读的数据在不在os cache里,如果不在的话就从磁盘文件里读取数据后放入os cache。

接着从操作系统的os cache里拷贝数据到应用程序进程的缓存里,再从应用程序进程的缓存里拷贝数据到操作系统层面的Socket缓存里,最后从Socket缓存里提取数据后发送到网卡,最后发送出去给下游消费。

整个过程,如下图所示:

kafka如何做到每秒几十万的吞吐量

大家看上图,很明显可以看到有两次没必要的拷贝吧!

Kafka为了解决这个问题,在读数据的时候是引入零拷贝技术。

也就是说,直接让操作系统的cache中的数据发送到网卡后传输给下游的消费者,中间跳过了两次拷贝数据的步骤,Socket缓存中仅仅会拷贝一个描述符过去,不会拷贝数据到Socket缓存。

大家看下图,体会一下这个精妙的过程:

kafka如何做到每秒几十万的吞吐量

通过零拷贝技术,就不需要把os cache里的数据拷贝到应用缓存,再从应用缓存拷贝到Socket缓存了,两次拷贝都省略了,所以叫做零拷贝。

对Socket缓存仅仅就是拷贝数据的描述符过去,然后数据就直接从os cache中发送到网卡上去了,这个过程大大的提升了数据消费时读取文件数据的性能。

而且大家会注意到,在从磁盘读数据的时候,会先看看os cache内存中是否有,如果有的话,其实读数据都是直接读内存的。

如果kafka集群经过良好的调优,大家会发现大量的数据都是直接写入os cache中,然后读数据的时候也是从os cache中读。

相当于是Kafka完全基于内存提供数据的写和读了,所以这个整体性能会极其的高。