Kafka为什么快(高性能的原因)

我们知道,Kafka 是基于磁盘存储的,但它却又具有高性能、高吞吐、低延时等特点,吞吐量可达几十上百万。那么 Kafka 这么快的原因是什么呢?

Kafka 高性能主要取决于以下几方面:

(1)消息批处理+压缩传输

(2)顺序写磁盘 + PageCache

(3)零拷贝技术

(4)分区分段+索引

1、消息批处理及压缩传输
(1)批处理

Kafka内部,消息都是以"批"为单位处理的,Kafka的客户端SDK在实现消息发送逻辑的时候,采用了异步批量发送的机制。

当调用 send() 方法发送一条消息后,无论是同步还是异步发送,Kafka 并不会立刻将该条消息发出去,它会先把它存在内存,然后选择合适的时机(涉及两个参数)把缓存的所有消息组成一批,一次性的发给Broker。

Broker端在数据处理过程中,无论是写磁盘、读磁盘读出来、还是复制消息到其他副本,都是以批进行(批不会被解开为一条一条消息)处理的。

消费时,消息同样是以批为单位,Consumer 从 Broker 拉到一批消息后,在客户端把批消息解开,再一条条的交给用户代码处理。

由此,构建和解开批消息分别在发送端和消费端的客户端完成,减轻了 Broker 的压力,也减少了 Broker 处理请求的次数,提升了整体的吞吐能力。

producer 端涉及两个批处理参数:
batch.size :消息条数积累到该阈值,立即发送.
linger.ms:不管消息有没有积累足够条数,超过该时间就立即发送

(2)压缩传输

默认情况下,在 Kafka 生产者中不启用消息压缩(compression.type参数来控制压缩方式)。因为压缩虽然可以减少网络带宽消耗和存储空间,但也会增加 CPU 的负担。

在 Kafka 中,压缩可能会发生在两个地方:生产者端和 Broker 端,一句话总结下压缩和解压缩,即 Producer 端压缩,Broker 端保持,Consumer 端解压缩。

Kafka 支持多种压缩算法:lz4、snappy、gzip,从 Kafka 2.1.0 开始新增了 ZStandard 算法,该算法是 Facebook 开源的压缩算法,能提供超高的压缩比。

Producer、Broker、Consumer 要使用相同的压缩算法,在 Producer 向 Broker 写入数据,Consumer 向 Broker 读取数据的时候可以不用解压缩,只需要在最终 Consumer 到消息的时候才进行解压缩,这样可以节省大量的网络和磁盘开销。

2、顺序写磁盘 + PageCache

Kafka 为了保证磁盘写入性能,通过基于操作系统的页缓存来实现文件写入的。操作系统本身有一层缓存,叫做 page cache,是在内存里的缓存,也可以称之为 os cache,意思就是操作系统自己管理的缓存。那么在写磁盘文件的时候,就可以先直接写入 os cache 中,也就是仅写入内存中,接下来由操作系统自己决定什么时候把 os cache 里的数据真正刷入到磁盘,这样大大提高写入效率和性能。

另外还有个关键操作,就是 kafka 在写数据的时候是以磁盘顺序写的方式来进行落盘的,即将数据追加到文件的末尾,而不是在文件的随机位置来修改数据,对于普通机械磁盘,如果是随机写的话,涉及到磁盘寻址的问题,导致性能极低,但是如果只是按照顺序的方式追加文件末尾的话,这种磁盘顺序写的性能基本可以跟写内存的性能相差无几。

3、零拷贝技术
(1)传统拷贝流程

流程步骤:

(1)操作系统将数据从磁盘文件中读取到内核空间的页面缓存;

(2)应用程序将数据从内核空间读入用户空间缓冲区;

(3)应用程序将读到数据写回内核空间放入 socket 缓冲区;

(4)操作系统将数据从 socket 缓冲区复制到网卡接口,然后数据通过网络发送。

可以看出,上述过程涉及到 4 次数据的复制,并且有两次复制操作是由 CPU 完成。但这个过程中,数据完全没有变化,仅仅是从磁盘复制到网卡缓冲区。

(2)零拷贝流程

可以看到,使用零拷贝技术把上面第2、3步的两次复制合并成一次。直接从 PageCache 中将数据复制到 Socket 缓冲区,这不仅减少了复制次数,且由于不用把数据复制到用户内存空间,DMA 控制器就可以直接完成数据复制,不需要CPU 的参与,速度更快。

4、分区分段 + 索引

Kafka 中的消息是按 topic 分类存储的,topic 中的数据又是按照一个一个分区(partition)存储到不同的 broker 节点上。每个 partition 对应操作系统上的一个文件夹,每个 partition 数据是以追加方式写入到一个有序的日志文件中。

这个日志文件实际上是由多个日志段(segment)文件组成。

每个 segment 文件都是一个独立的文件,它包含一定数量的消息。随着新消息不断追加,旧的 segment 文件会根据清理策略最终被删除。

通过这种分区分段的设计,Kafka 的消息最终相当于是分布式存储在一个个小的 segment 中,每次文件操作也是直接操作 segment。

同时,为了进一步的查询优化,Kafka 又默认为分段后的数据文件建立了索引文件(index文件)。通过索引文件,Kafka 可以快速定位特定偏移量的消息,而不需要遍历整个日志。

这种分区分段+索引的设计,不仅提升了数据读取的效率,同时也提高了数据操作的并行度。

大佬,点个赞再走呗!

相关推荐
Rookie小强6 小时前
kafka的rebalance机制是什么
分布式·kafka
终端行者6 小时前
jenkins实现分布式构建并自动发布到远程服务器上 jenkins实现自动打包编译发布远程服务器
服务器·分布式·jenkins
码农小灰20 小时前
Kafka消息持久化机制全解析:存储原理与实战场景
java·分布式·kafka
Raisy_21 小时前
05 ODS层(Operation Data Store)
大数据·数据仓库·kafka·flume
纪莫1 天前
Kafka如何保证「消息不丢失」,「顺序传输」,「不重复消费」,以及为什么会发生重平衡(reblanace)
java·分布式·后端·中间件·kafka·队列
想躺平的咸鱼干1 天前
RabbitMQ 基础
java·分布式·rabbitmq·idea·amqp·消息转换器·交换机模型
要开心吖ZSH1 天前
java八股文-中间件-参考回答
微服务·中间件·消息中间件
poemyang1 天前
千亿消息“过眼云烟”?Kafka把硬盘当内存用的性能魔法,全靠这一手!
kafka·高并发·pagecache·存储架构·顺序i/o·局部性原理
KaiwuDB1 天前
KWDB 分布式架构探究——数据分布与特性
数据库·分布式
武子康1 天前
大数据-75 Kafka 高水位线 HW 与日志末端 LEO 全面解析:副本同步与消费一致性核心
大数据·后端·kafka