APP下载

Kafka如何实现每秒上百万的高并发写入?_资料

消息来源:baojiabao.com 作者: 发布时间:2024-05-24

报价宝综合消息Kafka如何实现每秒上百万的高并发写入?_资料

这篇文章来聊一下Kafka的一些架构设计原理,这也是互联网公司面试时非常高频的技术考点。

Kafka是高吞吐低延迟的高并发、高效能的讯息中介软件,在大资料领域有极为广泛的运用。配置良好的Kafka丛集甚至可以做到每秒几十万、上百万的超高并发写入。

那么Kafka到底是如何做到这么高的吞吐量和效能的呢?这篇文章我们来一点一点说一下。

一、页快取技术 + 磁盘顺序写

首先Kafka每次接收到资料都会往磁盘上去写,如下图所示:

那么在这里我们不禁有一个疑问了,如果把资料基于磁盘来储存,频繁的往磁盘档案里写资料,这个效能会不会很差?大家肯定都觉得磁盘写效能是极差的。

没错,要是真的跟上面那个图那么简单的话,那确实这个效能是比较差的。

但是实际上Kafka在这里有极为优秀和出色的设计,就是为了保证资料写入效能,首先Kafka是基于操作系统的页快取来实现档案写入的。

操作系统本身有一层快取,叫做page cache,是在内存里的快取,我们也可以称之为os cache,意思就是操作系统自己管理的快取。

你在写入磁盘档案的时候,可以直接写入这个os cache里,也就是仅仅写入内存中,接下来由操作系统自己决定什么时候把os cache里的资料真的刷入磁盘档案中。

仅仅这一个步骤,就可以将磁盘档案写效能提升很多了,因为其实这里相当于是在写内存,不是在写磁盘,大家看下图:

接着另外一个就是kafka写资料的时候,非常关键的一点,他是以磁盘顺序写的方式来写的。也就是说,仅仅将资料追加到档案的末尾,不是在档案的随机位置来修改资料。

普通的机械磁盘如果你要是随机写的话,确实效能极差,也就是随便找到档案的某个位置来写资料。

但是如果你是追加档案末尾按照顺序的方式来写资料的话,那么这种磁盘顺序写的效能基本上可以跟写内存的效能本身也是差不多的。

所以大家就知道了,上面那个图里,Kafka在写资料的时候,一方面基于了os层面的page cache来写资料,所以效能很高,本质就是在写内存罢了。

另外一个,他是采用磁盘顺序写的方式,所以即使资料刷入磁盘的时候,效能也是极高的,也跟写内存是差不多的。

基于上面两点,kafka就实现了写入资料的超高效能。

那么大家想想,假如说kafka写入一条资料要耗费1毫秒的时间,那么是不是每秒就是可以写入1000条资料?但是假如kafka的效能极高,写入一条资料仅仅耗费0.01毫秒呢?那么每秒是不是就可以写入10万条数?

所以要保证每秒写入几万甚至几十万条资料的核心点,就是尽最大可能提升每条资料写入的效能,这样就可以在单位时间内写入更多的资料量,提升吞吐量。

二、零拷贝技术

说完了写入这块,再来谈谈消费这块。

大家应该都知道,从Kafka里我们经常要消费资料,那么消费的时候实际上就是要从kafka的磁盘档案里读取某条资料然后传送给下游的消费者,如下图所示。

那么这里如果频繁的从磁盘读资料然后发给消费者,效能瓶颈在哪里呢?

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

先看看要读的资料在不在os cache里,如果不在的话就从磁盘档案里读取资料后放入os cache。

接着从操作系统的os cache里拷贝资料到应用程序程式的快取里,再从应用程序程式的快取里拷贝资料到操作系统层面的Socket快取里,最后从Socket快取里提取资料后传送到网络卡,最后传送出去给下游消费。

整个过程,如下图所示:

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

一次是从操作系统的cache里拷贝到应用程序的快取里,接着又从应用程序快取里拷贝回操作系统的Socket快取里。

而且为了进行这两次拷贝,中间还发生了好几次上下文切换,一会儿是应用程序在执行,一会儿上下文切换到操作系统来执行。

所以这种方式来读取资料是比较消耗效能的。

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

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

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

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

对Socket快取仅仅就是拷贝资料的描述符过去,然后资料就直接从os cache中传送到网络卡上去了,这个过程大大的提升了资料消费时读取档案资料的效能。

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

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

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

说个题外话,下回有机会给大家说一下Elasticsearch的架构原理,其实ES底层也是大量基于os cache实现了海量资料的高效能检索的,跟Kafka原理类似。

三、最后的总结

通过这篇文章对kafka底层的页快取技术的使用,磁盘顺序写的思路,以及零拷贝技术的运用,大家应该就明白Kafka每台机器在底层对资料进行写和读的时候采取的是什么样的思路,为什么他的效能可以那么高,做到每秒几十万的吞吐量。

这种设计思想对我们平时自己设计中介软件的架构,或者是出去面试的时候,都有很大的帮助。

作者:中华石杉

来源:石杉的架构笔记订阅号(ID:shishan100)

dbaplus社群欢迎广大技术人员投稿,投稿邮箱:[email protected]

2019-11-11 13:20:00

相关文章