这篇文章就是讲讲Kafka的一些架构设计原则,也是互联网公司面试中非常高频的技术考点。Kafka是一种高吞吐、低延迟、高并发、高性能的消息中间件,广泛应用于大数据领域。一个配置良好的Kafka集群甚至可以达到每秒几十万甚至上百万的超高并发写入。那么Kafka是如何做到如此高的吞吐量和性能的呢?让我们在本文中详细讨论它。页面缓存技术+磁盘顺序写入首先,Kafka每次接收到数据,都会写入磁盘,如下图所示:那么这里不禁要问一个问题。如果数据存储在磁盘上,则经常写入磁盘文件。数据,这个性能会差吗?大家肯定觉得磁盘写性能极差。没错,如果真的像上图那么简单,那么性能确实比较差。但其实Kafka这里有一个非常优秀的设计,就是为了保证数据写入的性能。首先,Kafka是基于操作系统的pagecache来实现文件写入的。操作系统本身有一层缓存,叫做PageCache,是内存中的缓存。我们也可以称之为OSCache,意思是操作系统自己管理的缓存。写入磁盘文件时,可以直接写入OSCache,也就是只写入内存,然后由操作系统决定何时真正将OSCache中的数据刷入磁盘文件。仅仅这一步就可以大大提高磁盘文件写入的性能,因为实际上这相当于写入内存,而不是写入磁盘。请看下图:下一张是Kafka写数据的时候,非常关键。它以磁盘顺序方式写入。也就是说,仅将数据附加到文件末尾,而不是在文件中的随机位置修改数据。普通机械盘如果随便写,也就是找文件中的某个位置写入数据,性能极差。但是如果你通过追加到文件末尾的方式顺序写入数据,那么这种磁盘顺序写入的性能基本上可以和写入内存本身的性能相近。所以大家知道上图中,Kafka写数据的时候,一方面是基于OS层面的PageCache写数据,所以性能很高,本质上是写内存。还有一个是它采用的是磁盘顺序写入,所以即使是flush到磁盘,性能也是非常高的,和写内存差不多。基于以上两点,Kafka实现了写入数据的超高性能。那么大家想一想,如果Kafka写一条数据需要1毫秒,是不是每秒可以写1000条数据呢?但是如果kafka的性能极高,写一条数据只需要0.01毫秒?那么每秒能写10万条数据吗?因此,保证每秒写入数万甚至数十万条数据的核心点是尽可能提高每条数据写入的性能,从而可以写入更大的数据量每单位时间提高吞吐量。说完零拷贝技术的写法,再说说消费。大家应该都知道,我们经常需要从kafka消费数据,所以在消费的时候,我们其实需要从kafka的磁盘文件中读取某条数据,发送给下游的消费者,如下图所示:从磁盘读取数据并将其发送给消费者。性能瓶颈在哪里?假设Kafka不做任何优化,从磁盘读取数据发送给下游消费者是非常简单的。大致过程如下:首先查看要读取的数据是否在OSCache中,如果不在,则从磁盘文件中读取数据放入OSCache中。然后从操作系统的OSCache中拷贝数据到应用进程的缓存中,再从应用进程的缓存中拷贝数据到操作系统层面的Socket缓存中。***从Socket缓存中提取数据发送给网卡,***发送给下游消费者。整个过程如下图所示:如果你看上图,你可以清楚地看到有两个不必要的副本!一种是从操作系统缓存到应用进程缓存,再从应用缓存复制回操作系统的Socket缓存。而且,为了执行这两个副本,中间发生了几次上下文切换。一会儿是应用程序在执行,一会儿是上下文切换到操作系统执行。所以这种方式读取数据是比较耗性能的。为了解决这个问题,Kafka在读取数据的时候引入了零拷贝技术。也就是说,直接将操作系统的Cache中的数据发送给网卡再传输给下游的消费者,跳过了中间复制数据的两步,Socket缓存中只会复制一个描述符,并没有数据将被复制到Socket缓存中。请看下图来体验一下这个微妙的过程:通过零拷贝技术,不需要先将OSCache中的数据拷贝到应用缓存中,再从应用缓存中拷贝到Socket缓存中。两个副本都被省略,所以称为零副本。Socket缓存只是将数据描述符复制过去,然后数据直接从OSCache发送到网卡。这个过程大大提高了数据消费时读取文件数据的性能。而且你会注意到,从磁盘读取数据时,你会先检查OSCache内存中是否有。如果是这样的话,读取的数据实际上是直接从内存中读取的。如果Kafka集群调优好,会发现大量的数据直接写入OSCache,读取数据时再从OSCache中读取。相当于Kafka完全基于内存提供数据写入和读取,所以整体性能会非常高。顺便说一句,下次有机会给大家讲讲Elasticsearch的架构原理。其实ES底层也是基于OSCache来实现海量数据的高性能检索,这和Kafka的原理类似。小结通过本文对Kafka底层页面缓存技术的使用,磁盘顺序写入的思想,以及零拷贝技术的应用,你应该明白了Kafka在底层每台机器读写数据时使用的是什么这个思路,为什么它的性能可以这么高,达到每秒几十万的吞吐量。这种设计思维对我们自己设计中间件架构,或者出去面试的时候很有帮助。中华石山:十余年BAT架构经验,一线互联网公司技术总监。带领数百人团队开发过亿级大流量高并发系统。多年工作积累的研究手稿和经验总结,现整理成文,一一传授。微信公众号:石山的建筑笔记(ID:shishan100)。
