Alexu
发布于 2025-07-07 / 0 阅读
0
0

kafka如何实现百万并发

那 Kafka 的架构是怎样的?又是怎么做到其吞吐量动辄几十上百万的呢?

  1. Kafka I/O 模型拆解;

  2. 零拷贝技术的运用;

  3. Kakfa 架构设计和负载均衡;

    1. Kafka 架构

    2. Topic 实现原理

    3. partition 水平拓展和负载均衡算法

  4. 分段(Segment)存储消息实现原理

  5. 磁盘顺序写、pageCache

  6. 数据压缩。

kafka架构:

  1. Producer(生产者):发送消息的一方,负责发布消息到 Kafka 主题(Topic)。

  2. Consumer(消费者):接受消息的一方,订阅主题并处理消息。Kafka 有 ConsumerGroup 的概念,每个 Consumer 只能消费所分配到的 Partition 的消息,每一个 Partition 只能被一个 ConsumerGroup 中的一个 Consumer 所消费,所以同一个 ConsumerGroup 中 Consumer 的数量如果超过了 Partiton 的数量,将会出现有些 Consumer 分配不到 partition 消费。

  3. Broker(代理):服务代理节点,Kafka 集群中的一台服务器就是一个 broker,可以水平无限扩展,同一个 Topic 的消息可以分布在多个 broker 中

  4. Topic(主题)与 Partition(分区) :Kafka 中的消息以 Topic 为单位进行划分,生产者将消息发送到特定的 Topic,而消费者负责订阅 Topic 的消息并进行消费。图中 TopicA 有三个 Partiton(TopicA-par0、TopicA-par1、TopicA-par2)

    为了提升整个集群的吞吐量,Topic 在物理上还可以细分多个 Partition,一个 Partition 在磁盘上对应一个文件夹。

  5. Replica(副本):副本,是 Kafka 保证数据高可用的方式,Kafka 同一 Partition 的数据可以在多 Broker 上存在多个副本,通常只有 leader 副本对外提供读写服务,当 leader 副本所在 broker 崩溃或发生网络一场,Kafka 会在 Controller 的管理下会重新选择新的 Leader 副本对外提供读写服务。

  6. ZooKeeper:管理 Kafka 集群的元数据和分布式协调。


  1. IO多路复用

高并发处理能力:通过 I/O 多路复用机制,Kafka 能够同时处理大量的网络连接请求,而不需要为每个连接创建一个线程,从而节省了系统资源。

低延迟:非阻塞 I/O 操作避免了线程的阻塞等待,使得 I/O 操作能够更快地完成,从而降低了系统的响应延迟。

资源节省:通过减少线程的数量和上下文切换,Kafka 在处理高并发请求时能够更有效地利用 CPU 和内存资源。

扩展性强:Reactor 模式的分层设计使得 Kafka 的网络模块具有很好的扩展性,可以根据需要增加更多的 I/O 线程或调整事件处理器的逻辑。

  1. 零拷贝技术

是一种计算机操作系统技术,用于在内存和存储设备之间进行数据传输时,避免 CPU 的参与,从而减少 CPU 的负担并提高数据传输效率。

在 Kafka 中,零拷贝主要通过以下几种方式实现:

  • sendfile() 系统调用:在发送数据时,Kafka 使用操作系统的 sendfile() 系统调用直接将文件从磁盘发送到网络套接字,而无需将数据复制到应用程序的用户空间。这减少了数据复制次数,提高了传输效率。

  • 文件内存映射(Memory-Mapped Files):Kafka 使用文件内存映射技术(mmap),将磁盘上的日志文件映射到内存中,使得读写操作可以在内存中直接进行,无需进行额外的数据复制。

零拷贝技术通过减少 CPU 负担和内存带宽消耗,提高了 Kakfa 性能。

  • 降低 CPU 使用率:由于数据不需要在内核空间和用户空间之间多次复制,CPU 的参与减少,从而降低了 CPU 使用率,腾出更多的 CPU 资源用于其他任务。

  • 提高数据传输速度:直接从磁盘到网络的传输路径减少了中间步骤,使得数据传输更加高效,延迟更低。

  • 减少内存带宽消耗:通过减少数据在内存中的复制次数,降低了内存带宽的消耗,使得系统能够处理更多的并发请求。

3. Partition分区

为了提高并行处理能力和扩展性,Kafka 将一个 Topic 分为多个 Partition。每个 Partition 是一个有序的消息队列,消息在 Partition 内部是有序的,但在不同的 Partition 之间没有顺序保证。

Producer 可以并行地将消息发送到不同的 Partition,Consumer 也可以并行地消费不同的 Partition,从而提升整体处理能力。

因此,可以说,每增加一个 Paritition 就增加了一个消费并发。Partition 的引入不仅提高了系统的可扩展性,还使得数据处理更加灵活。

Partition 分区策略

码楼:“生产者将消息发送到哪个分区是如何实现的?不合理的分配会导致消息集中在某些 Broker 上,岂不是完犊子。”

主要有以下几种分区策略:

  1. 轮询策略:也称 Round-robin 策略,即顺序分配。

  2. 随机策略:也称 Randomness 策略。所谓随机就是我们随意地将消息放置到任意一个分区上。

  3. 按消息键保序策略

  4. 基于地理位置分区策略。

Segment 日志文件和稀疏索引

  1. 日志

前面已经介绍过,Kafka 的 Topic 可以分为多个 Partition,每个 Partition 有多个副本,你可以理解为副本才是存储消息的物理存在。其实每个副本都是以日志(Log)的形式存储。

码楼:“日志文件过大怎么办?”

为了解决单一日志文件过大的问题,kafka 采用了分段(Segment)的形式进行存储

所谓 Segment,就是当一个日志文件大小到达一定条件之后,就新建一个新的 Segment,然后在新的 Segment 写入数据。Topic、Partition、和日志的关系如图 8 所示。

5顺序读写磁盘

6Page Cache 。

简而言之:利用操作系统的缓存技术,在读写磁盘日志文件时,操作的是内存,而不是文件,由操作系统决定什么在某个时间将 Page Cache 的数据刷写到磁盘中

7数据压缩和批量处理

数据压缩在 Kafka 中有助于减少磁盘空间的使用和网络带宽的消耗,从而提升整体性能。

通过减少消息的大小,压缩可以显著降低生产者和消费者之间的数据传输时间。

Chaya:Kafka 支持的压缩算法有哪些?

在 Kafka 2.1.0 版本之前,Kafka 支持 3 种压缩算法:GZIP、Snappy 和 LZ4。从 2.1.0 开始,Kafka 正式支持 Zstandard 算法(简写为 zstd)。

这么多压缩算法,我如何选择?

一个压缩算法的优劣,有两个重要的指标:压缩比,文件压缩前的大小与压缩后的大小之比,比如源文件占用 1000 M 内存,经过压缩后变成了 200 M,压缩比 = 1000 /200 = 5,压缩比越高越高;另一个指标是压缩/解压缩吞吐量,比如每秒能压缩或者解压缩多少 M 数据,吞吐量越高越好。


评论