【Kafka】核心原理(一)

286 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

Kafka 极限的性能压测,Kafka 单个节点的极限处理能力接近每秒钟 2000 万条消息,吞吐量达到每秒钟 600MB

Kafka 如何实现高性能 IO

  1. 批处理:减少网络通信开销
  2. 利用操作系统 page cache 来缓存数据:减少磁盘 IO 开销
  3. 零拷贝技术:减少数据多次拷贝开销
  4. 磁盘顺序写:减少寻道移臂开销

1. Kafka 的批处理

批量处理是一种非常有效的提升系统吞吐量的方法,减少网络通信开销

Kafka 的客户端 SDK(软件开发工具包)中,KafkaProducer 只提供了单条发送的 send() 方法,并没有提供任何批量发送的接口。

原因是,Kafka 根本就没有提供单条发送的功能,采用了异步批量发送的机制。

  • 当你调用 send() 方法发送一条消息之后
  • 无论你是同步发送还是异步发送,Kafka 都不会立即就把这条消息发送出去
  • 它会先把这条消息,存放在内存中缓存起来,然后选择合适的时机把缓存中的所有消息组成一批,一次性发给 Broker

批量.png 各端批量处理数据:

  • 生产端 Producer:内部批量发送。
  • 消费端 ConsumerConsumerBroker 拉到一批消息后,在客户端把批消息解开,再一条一条交给用户代码处理。
  • Broker 端:每批消息都会被当做一个“批消息”来处理。

2. Kafka 写入数据:page cache + 磁盘顺序写

通俗地说,PageCache 就是操作系统在内存中给磁盘上的文件建立的缓存。

  • 应用程序在写入文件的时候,操作系统会先把数据写入到内存中的 PageCache,然后再一批地写到磁盘上。

  • 读取文件的时候,也是从 PageCache 中来读取数据,这时候会出现两种可能情况:

    1. PageCache 中有数据,那就直接读取,这样就节省了从磁盘上读取数据的时间

    2. PageCache 中没有数据,这时候操作系统会引发一个缺页中断

    应用程序的读取线程会被阻塞,操作系统把数据从文件中复制到 PageCache 中,然后应用程序再从 PageCache 中继续把数据读出来,这时会真正读一次磁盘上的文件,这个读的过程就会比较慢。

数据写入.png

流程如下:

  1. 接收到一批数据,Kafka Broker 直接写入 Page CachePage Cache 是基于 OS Cache
  2. Page Cache 再顺序写入磁盘

3. Kafka 高效数据读取:零拷贝技术

当不使用零拷贝技术读取数据时:

数据读取.png

流程如下:

  1. 消费端 Consumer:向 Kafka Broker 请求拉取消息

  2. Kafka BrokerOS Cache 读取消息到 应用程序的内存空间:

    1. OS Cache 中有消息,则直接读取
    2. OS Cache 中无消息,则从磁盘里读取
  3. 再通过网卡,socket 将数据发送给 消费端Consumer

当使用零拷贝技术读取数据:

数据读取2.png

Kafka 使用零拷贝技术可以把这个复制次数减少一次,直接从 PageCache 中把数据复制到 Socket 缓冲区中。

  • 这样不用将数据复制到用户内存空间。
  • DMA 控制器直接完成数据复制,不需要 CPU 参与,速度更快。

零拷贝对应的系统调用:

#include <sys/socket.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);