文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Kafka 为什么这么快的七大秘诀,涨知识了

2024-11-29 18:33

关注

我们都知道 Kafka 是基于磁盘进行存储的,但 Kafka 官方又称其具有高性能、高吞吐、低延时的特点,其吞吐量动辄几十上百万。

在座的靓仔和靓女们是不是有点困惑了,一般认为在磁盘上读写数据是会降低性能的,因为寻址会比较消耗时间。那 Kafka 又是怎么做到其吞吐量动辄几十上百万的呢?

一、Kafka Reactor I/O 网络模型

Kafka Reactor I/O 网络模型是一种非阻塞 I/O 模型,利用事件驱动机制来处理网络请求。

该模型通过 Reactor 模式实现,即一个或多个 I/O 多路复用器(如 Java 的 Selector)监听多个通道的事件,当某个通道准备好进行 I/O 操作时,触发相应的事件处理器进行处理。

这种模型在高并发场景下具有很高的效率,能够同时处理大量的网络连接请求,而不需要为每个连接创建一个线程,从而节省系统资源。

Reactor 线程模型如图 2 所示。

图 2

Reacotr 模型主要分为三个角色。

Kafka 基于 Reactor 模型架构如图 3 所示。

图 3

Kafka 的网络通信模型基于 NIO(New Input/Output)库,通过 Reactor 模式实现,具体包括以下几个关键组件:

图 4

Chaya:该模型和如何提高 kafka 的性能和效率?

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

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

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

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

二、零拷贝技术的运用

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

Kafka 使用零拷贝技术来优化数据传输,特别是在生产者将数据写入 Kafka 和消费者从 Kafka 读取数据的过程中。在 Kafka 中,零拷贝主要通过以下几种方式实现:

比如 Broker 读取磁盘数据并把数据发送给 Consumer 的过程,传统 I/O 经历以下步骤。

  1. 读取数据:通过read 系统调用将磁盘数据通过 DMA copy 到内核空间缓冲区(Read buffer)。
  2. 拷贝数据:将数据从内核空间缓冲区(Read buffer) 通过 CPU copy 到用户空间缓冲区(Application buffer)。
  3. 写入数据:通过write()系统调用将数据从用户空间缓冲区(Application) CPU copy 到内核空间的网络缓冲区(Socket buffer)。
  4. 发送数据:将内核空间的网络缓冲区(Socket buffer)DMA copy 到网卡目标端口,通过网卡将数据发送到目标主机。

这一过程经过的四次 copy 如图 5 所示。

图 5

Chaya:零拷贝技术如何提高 Kakfa 的性能?

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

三、Partition 并发和分区负载均衡

在说 Topic patition 分区并发之前,我们先了解下 kafka 架构设计。

1.Kafka 架构

一个典型的 Kafka 架构包含以下几个重要组件,如图 6 所示。

图 6

2.Topic 主题

Topic 是 Kafka 中数据的逻辑分类单元,可以理解成一个队列。Broker 是所有队列部署的机器,Producer 将消息发送到特定的 Topic,而 Consumer 则从特定的 Topic 中消费消息。

3.Partition

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

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

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

4.Partition 分区策略

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

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

轮询策略

比如一个 Topic 下有 3个分区,那么第一条消息被发送到分区0,第二条被发送到分区1,第三条被发送到分区2,以此类推。

当生产第4条消息时又会重新开始,即将其分配到分区0,如图 5 所示。

轮询策略有非常优秀的负载均衡表现,它总是能保证消息最大限度地被平均分配到所有分区上,故默认情况下它是最合理的分区策略,也是我们最常用的分区策略之一。

随机策略

所谓随机就是我们随意地将消息放置到任意一个分区上。如图所示,9 条消息随机分配到不同分区。

按消息键分配策略

一旦消息被定义了 Key,那么你就可以保证同一个 Key 的所有消息都进入到相同的分区里面,比如订单 ID,那么绑定同一个 订单 ID 的消息都会发布到同一个分区,由于每个分区下的消息处理都是有顺序的,故这个策略被称为按消息键保序策略,如图所示。

基于地理位置

这种策略一般只针对那些大规模的 Kafka 集群,特别是跨城市、跨国家甚至是跨大洲的集群。

我们就可以根据 Broker 所在的 IP 地址实现定制化的分区策略。比如下面这段代码:

List partitions = cluster.partitionsForTopic(topic);
return partitions.stream()
  .filter(p -> isSouth(p.leader().host()))
  .map(PartitionInfo::partition)
  .findAny()
  .get();

我们可以从所有分区中找出那些Leader副本在南方的所有分区,然后随机挑选一个进行消息发送。

四、Segment 日志文件和稀疏索引

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

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

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

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

图 8

一个 segment 对应磁盘上多个文件。

.log 文件存储实际的 message,kafka为每一个日志文件添加了2 个索引文件 .index以及 .timeindex

segment 文件命名规则:partition 第一个 segment 从 0 开始,后续每个 segment 文件名为上一个 segment 文件最后一条消息的 offset 值。数值最大为 64 位 long 大小,19 位数字字符长度,没有数字用 0 填充。

码楼:“为什么要有 .index 文件?”

为了提高查找消息的性能。kafka 为消息数据建了两种稀疏索引,一种是方便 offset 查找的 .index 稀疏索引,还有一种是方便时间查找的 .timeindex 稀疏索引。

1.稀疏索引

Chaya:“为什么不创建一个哈希索引,从 offset 到物理消息日志文件偏移量的映射关系?”

万万不可,Kafka 作为海量数据处理的中间件,每秒高达几百万的消息写入,这个哈希索引会把把内存撑爆炸。

稀疏索引不会为每个记录都保存索引,而是写入一定的记录之后才会增加一个索引值,具体这个间隔有多大则通过 log.index.interval.bytes 参数进行控制,默认大小为 4 KB,意味着 Kafka 至少写入 4KB 消息数据之后,才会在索引文件中增加一个索引项。

哈希稀疏索引把消息划分为多个 block ,只索引每个 block 第一条消息的 offset 即可 。

Chaya:如果消费者要查找 Offset 为 4 的消息,查找过程是怎样的?

.timeindex 文件同理,只不过它的查找结果是 offset,之后还要在走一遍 .index 索引查找流程。

由于 kafka 设计为顺序读写磁盘,因此遍历区间的数据并对速度有太大的影响,而选择稀疏索引还能节约大量的磁盘空间。

2.mmap

有了稀疏索引,当给定一个 offset 时,Kafka 采用的是二分查找来扫描索引定位不大于 offset 的物理位移 position,再到日志文件找到目标消息。

利用稀疏索引,已经基本解决了高效查询的问题,但是这个过程中仍然有进一步的优化空间,那便是通过 mmap(memory mapped files) 读写上面提到的稀疏索引文件,进一步提高查询消息的速度

就是基于 JDK nio 包下的 MappedByteBuffer 的 map 函数,将磁盘文件映射到内存中。

进程通过调用mmap系统函数,将文件或物理内存的一部分映射到其虚拟地址空间。这个过程中,操作系统会为映射的内存区域分配一个虚拟地址,并将这个地址与文件或物理内存的实际内容关联起来。

一旦内存映射完成,进程就可以通过指针直接访问映射的内存区域。这种访问方式就像访问普通内存一样简单和高效。

图引自《码农的荒岛求生》

五、顺序读写磁盘

码楼:“不管如何,Kafka 读写消息都要读写磁盘,如何变快呢?”

磁盘就一定很慢么?人们普遍错误地认为硬盘很慢。然而,存储介质的性能,很大程度上依赖于数据被访问的模式。

同样在一块普通的7200 RPM SATA硬盘上,随机I/O(random I/O)与顺序I/O相比,随机I/O的性能要比顺序I/O慢3到4个数量级。

合理的方式可以让磁盘写操作更加高效,减少了寻道时间和旋转延迟。

码楼,你还留着课本吗?来,翻到讲磁盘的章节,让我们回顾一下磁盘的运行原理。

码楼:“鬼还留着哦,课程还没上到一半书就没了。要不是考试俺眼神好,就挂科了。”

磁盘的运行原理如图所示。

硬盘在逻辑上被划分为磁道、柱面以及扇区。硬盘的每个盘片的每个面都有一个读写磁头。

完成一次磁盘 I/O ,需要经过寻道、旋转和数据传输三个步骤。

因此,如果在写磁盘的时候省去寻道、旋转可以极大地提高磁盘读写的性能。

Kafka 采用顺序写文件的方式来提高磁盘写入性能。顺序写文件,顺序 I/O 的时候,磁头几乎不用换道,或者换道的时间很短。减少了磁盘寻道和旋转的次数。磁头再也不用在磁道上乱舞了,而是一路向前飞速前行。

Kafka 中每个Partition 是一个有序的,不可变的消息序列,新的消息可以不断追加到 Partition 的末尾,在 Kafka 中 Partition 只是一个逻辑概念,每个Partition 划分为多个 Segment,每个 Segment 对应一个物理文件,Kafka 对 Segment 文件追加写,这就是顺序写文件。

每条消息在发送前会根据负载均衡策略计算出要发往的目标 Partition 中,broker 收到消息之后把该条消息按照追加的方式顺序写入 Partition 的日志文件中。

如下图所示,可以看到磁盘顺序写的性能远高于磁盘随机写,甚至比内存随机写还快。

六、PageCache

Chaya:“码哥,使用稀疏索引和 mmap 内存映射技术提高读消息的性能;Topic Partition 加磁盘顺序写持久化消息的设计已经很快了,但是与内存顺序写还是慢了,还有优化空间么?”

小姑娘,你的想法很好,作为快到令人发指的 Kafka,确实想到了一个方式来提高读写写磁盘文件的性能。这就是接下来的主角 Page Cache 。

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

Kafka重度依赖底层操作系统提供的PageCache功能。当上层有写操作时,操作系统只是将数据写入PageCache,同时标记Page属性为Dirty。

当读操作发生时,先从PageCache中查找,如果发生缺页才进行磁盘调度,最终返回需要的数据。

于是我们得到一个重要结论:如果Kafka producer的生产速率与consumer的消费速率相差不大,那么就能几乎只靠对broker page cache的读写完成整个生产-消费过程,磁盘访问非常少。

实际上PageCache是把尽可能多的空闲内存都当做了磁盘缓存来使用。

七、数据压缩和批量处理

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

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

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

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

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

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

1.生产者压缩

Kafka 的数据压缩主要在生产者端进行。具体步骤如下:

2.解压缩

有压缩,那必有解压缩。通常情况下,Producer 发送压缩后的消息到 Broker ,原样保存起来。

Consumer 消费这些消息的时候,Broker 原样发给 Consumer,由 Consumer 执行解压缩还原出原本的信息。

Chaya:Consumer 咋知道用什么压缩算法解压缩?

Kafka会将启用了哪种压缩算法封装进消息集合中,这样当Consumer读取到消息集合时,它自然就知道了这些消息使用的是哪种压缩算法。

总之一句话:Producer端压缩、Broker端保持、Consumer端解压缩。

3.批量数据处理

Kafka Producer 向 Broker 发送消息不是一条消息一条消息的发送,将多条消息打包成一个批次发送。

批量数据处理可以显著提高 Kafka 的吞吐量并减少网络开销。

Kafka Producer 的执行流程如下图所示:

发送消息依次经过以下处理器:

八、无锁轻量级 offset

Offset 是 Kafka 中的一个重要概念,用于标识消息在分区中的位置。

每个分区中的消息都有一个唯一的 offset,消费者通过维护自己的 offset 来确保准确消费消息。offset 的高效管理对于 Kafka 的性能至关重要。

offset 是从 0 开始的,每当有新的消息写入分区时,offset 就会加 1。offset 是不可变的,即使消息被删除或过期,offset 也不会改变或重用。

Consumer需要向Kafka汇报自己的位移数据,这个汇报过程被称为提交位移(Committing Offsets)。因为Consumer能够同时消费多个partition的数据,所以位移的提交实际上是在partition粒度上进行的,即Consumer需要为分配给它的每个partition提交各自的位移数据

提交位移主要是为了表征Consumer的消费进度,这样当Consumer发生故障重启之后,就能够从Kafka中读取之前提交的位移值,然后从相应的位移处继续消费。

在传统的消息队列系统中,offset 通常需要通过锁机制来保证一致性,但这会带来性能瓶颈。Kafka 的设计哲学是尽量减少锁的使用,以提升并发处理能力和整体性能。

1.无锁设计思想

Kafka 在 offset 设计中采用了一系列无锁的技术,使其能够在高并发的环境中保持高效。

2.消费者 Offset 管理流程

graph TD;
    A[启动消费者] --> B[从分区读取消息];
    B --> C[处理消息];
    C --> D{是否成功处理?};
    D --> |是| E[更新 Offset];
    D --> |否| F[记录失败, 重新处理];
    E --> G[提交 Offset];
    G --> H[继续处理下一个消息];
    F --> B;
    H --> B;

Kafka 通过无锁轻量级 offset 的设计,实现了高性能、高吞吐和低延时的目标。

九、总结

Kafka 通过无锁轻量级 offset 的设计,实现了高性能、高吞吐和低延时的目标。

其 Reactor I/O 网络模型、磁盘顺序写入、内存映射文件、零拷贝、数据压缩和批量处理等技术,为 Kafka 提供了强大的数据处理能力和高效的消息队列服务。

来源:码哥跳动内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯