Kafka-百万级吞吐量的秘密?

2021-03-28  本文已影响0人  蠟筆小噺没有烦恼

Kafka作为一款分布式的消息队列,是如何做到百万级TPS呢?,用了哪些黑科技才能做到如此这般独孤求败呢?

1 页缓存

将磁盘的数据缓存到内存中,把对磁盘的访问变为对内存的访问

kafka在写数据的时候,会先将数据写入到页缓存,满足一定条件后刷写到磁盘上,可以保证更高的读写性能。

1.1 页缓存-读

在启用页缓存做读取的情况下,会先查看对应的页,是否在页缓存中,如果在(命中),那么直接读取并返回即可,避免了对磁盘的访问;

如果没有命中,则向磁盘发起读请求,并将读取的数据存入页缓存,之后将数据返回给进程。

1.2 页缓存-写

若一个进程需要将数据写入到磁盘,会检查对应的数据是否在页缓存中,如果不存在,会先在页缓存添加相应的页,然后将数据写入对应的页;这时候对应的页就变成了脏页;

脏页达到一定的条件之后就会被操作系统写入到磁盘。Linux系统中有几个参数可以指定脏页达到什么条件进行磁盘刷写:

虽然页缓存的刷写由操作系统来控制,但是Kafka自身也提供了同步刷盘及间断性强制刷盘(fsync)的功能,可以显著提高消息的可靠性,防止宕机造成的页缓存没有及时写到磁盘造成的数据丢失。具体的参数有:

不过建议刷盘任务还是由操作系统来做,消息的可靠性应该由多分本机制来保证,而不是影响性能的同步刷盘操作。

1.3 为什么要用页缓存

为什么要使用页缓存,而不是在JVM内维护一个缓存呢?主要原因有以下几点:

1.4 关于Swap

内存交换本身是为了再不足的时候将数据临时写入到磁盘,避免影响服务。但它的作用和我们使用页缓存的初衷背道而驰,应当尽量避免这种内存交换,可以设置vm.swappiness=1来防止内存耗尽中止某些进程,也可以最大限度的限制对Kafka的影响

2 零拷贝

通过零拷贝技术,可以去掉那些没有必要的数据复制操作,同时减少上下文的切换次数

设想一种情况,需要将服务器磁盘的一个文件展示给用户。

正常的做法是:

零拷贝-未引入DMA技术

整个过程,一共进行了4次复制,内核和用户模式的上下文切换也是4次;

采用零拷贝

如果不拷贝到用户控件,有内核模式的ReaderBuffer直接拷贝到SocketBuffer是否可行呢?


其实是可行的,但这依次有3次复制。直到引入DMA技术,才将拷贝减少到2次:

零拷贝

整个过程,进行了2次复制,上下文切换也是2次。针对内核而言,数据在内核模式下实现了零拷贝。

DMA(Direct Memroy Access,直接内存读取)
DMA就是为了解决批量数据的IO问题,允许不同速度的硬件沟通。不需要依赖CPU来进行复制,只需要CPU初始化这个传输动作,而传输本身是有DMA控制器来实现和完成的,无需CPU直接控制传输,也没有终端处理方式那样保留现场和恢复现场的过程,通过硬件为RAM和IO设备开辟一条直接传输数据的通道,是的CPU效率大大提升。

使用DMA

如果不使用DMA,CPU需要从来源把数据复制到暂存器,再将其写会新的地方,这个时间内,CPU无法处理其他工作。


不使用DMA

零拷贝使用的场景有:

3 磁盘顺序读写

磁盘的顺序写,要比内存随机写都要快

在磁盘上顺序读写,不需要移动磁盘臂来寻找数据位置,并且操作系统对于线性读写也做了很多优化,比如预读(read-ahead)技术,提前将一个比较大的磁盘读入内存和后写(write-behind),将很多小的逻辑写操作后合并组成一个大的物理写操作。


参考:

Kafka 的零拷贝技术

DMA原理介绍

上一篇下一篇

猜你喜欢

热点阅读