Kafka 性能实践知多少

简介: 众所周知,Apache Kafka 是一个分布式开源流和事件处理平台,广泛应用于各大互联网公司以及基于不同体系的软件架构的业务场景中。其实,基于早期的设计理念而言,Kafka 最初被设想为消息队列,并基于分布式提交日志的抽象。然而,自 2011 年由 LinkedIn 创建并开源以来,Kafka 已迅速从消息队列演变为成熟的事件流处理平台。

    众所周知,Apache Kafka 是一个分布式开源流和事件处理平台,广泛应用于各大互联网公司以及基于不同体系的软件架构的业务场景中。其实,基于早期的设计理念而言,Kafka 最初被设想为消息队列,并基于分布式提交日志的抽象。然而,自 2011 年由 LinkedIn 创建并开源以来,Kafka 已迅速从消息队列演变为成熟的事件流处理平台。

    最初 Kafka 是在 Apache 许可下进行开发的,但后来 Confluent 对其进行了分支改造并提供了一个更为强大的版本。实际上,Confluent 使用自身的平台提供了最为完整体系的 Kafka 发行版。同时,为了获得更为广阔的市场份额, Confluent 平台基于额外的社区组织和商业功能不断优化改进 Kafka,这些功能旨在大规模增强运营商和开发人员在生产中的流媒体体验。

    Apache Kafka 是一款强大的消息系统组件,在实际的业务场景中,基于此,能够协助我们创建易于扩展的实时、高吞吐量、低延迟的数据流。经过优化后的 Kafka,其各方面的特性均有所提升,有的关键点甚至使得 Kafka 组件的固有功能特性发挥的淋漓尽致。例如,抵抗集群内部发生的机器/节点故障、集群上数据和消息的持久性以及业务的可连续性。这也是在实际的项目开发活动中,对 Kafka 优化如此重要的原因。

    通常,从本质上讲,基于不同的业务场景实现,Kafka 框架的优化应该是一个优先、持续、不断迭代的事件过程。但同时,我们往往会因运行环境的差异、业务逻辑更新而很难知道如何准确、充分地去优化 Kafka。基于 Kafka 框架的相关特性,在本篇文章中,我将为大家带来四个 Kafka 最佳优化实践的场景,以便能够在实际的业务开发活动中充分利用 Kafka 组件的相关功能特性。

    通常,针对 Kafka 组件的性能优化取决于不同的因素,例如,集群模型、架构拓扑、承载环境以及业务逻辑实现。因此,基于业务场景特性,Kafka 的选型及部署可能是一个具有挑战的活动事项,毕竟,基于分布式架构将会涉及多个层面,并且在这些层内有不同差异的参数可作为调优对象。以下为 Kafka 集群架构拓扑参考模型:

    例如,通常情况下,具有自动化数据冗余的高吞吐量发布-订阅 (Pub / Sub) 模式在很多业务场景中具有十分重要的意义,无论是基于服务组件解耦或者针对高并发请求下的流量削峰。然而,在某些特定的环境条件下,当我们的服务的消费者努力跟上数据流时,或者如果他们无法读取消息,因为这些消息在消费者到达之前就消失了,那么需要做一些工作来支持消费应用程序的性能需求。

    正如上述所说,Kafka 是一个强大的实时数据流框架及平台。但在实际的业务场景中,需要依据所承载的业务逻辑进行适应性调整,因为,在某些情况下,我们依据默认的配置或所推荐的版本进行应用架构的交互过程中可能存在各方面的问题,比如,消息流传输缓慢和生产者或消费者处理滞后等等。

    通常来讲,Kafka 优化是一个广泛的主题,基于业务场景,可以非常深入和细化,但这里有四个高度利用的 Kafka 最佳实践可以帮助大家进行快速入门:

    1、升级至最新版本

    2、理解数据吞吐率

    3、按需实现自定义分区

    4、调整消费者套接字缓冲区

    1、升级至最新版本

    这听起来可能有点无聊,但是在实际的开发活动中,我们压根无法知晓有多少人、团队依旧使用旧版本的 Kafka。当然,并不是说老版本的 Kafka 不满足实际的业务场景,而是基于从性能、稳定性角度而言。毕竟,最新的版本无论是基于缺陷修复还是功能改进、优化,都是值得尝试的。从另外一个角度而言,随着业务架构的不断演进,其底层依赖的组件可能会从兼容特性或者安全、性能特性发生较大变化,导致之前所支撑的组件在新的业务架构面前显得无所适从,影响业务系统稳定性。

   截止到目前,Kafka 目前总共演进了 8 个大版本,分别是 0.7、0.8、0.9、0.10、0.11、1.0 、2.0 及 3.0,其中的小版本和 Patch 版本很多。Kafka 每次更新都会略有改进。最新的 Kafka 版本已于 2021 年 9 月发布,是一个多方面的主要版本。Apache Kafka 3.0 引入了各种新功能、突破性的 API 更改以及对 KRaft 的改进——Apache Kafka 的内置共识机制将取代 Apache ZooKeeper 。虽然 KRaft 尚未被推荐用于生产,但其对 KRaft 元数据和 API 进行了较多改进。以及所涉及的 Exactly-once 和分区重新分配支持值得强调。

    基于 Kafka 所演进的不同版本,以前期的 0.7 版本为例,Kafka 从 0.7 时代演进到 0.8 之后正式引入了副本机制,至此 Kafka 成为了一个真正意义上完备的分布式高可靠消息队列解决方案。基于副本备份机制,使得 Kafka 尽可能比较好地做到消息无丢失。虽然基于当时的生产和消费消息使用的还是老版本的客户端 API,所谓的老版本是指当你用它们的 API 开发生产者和消费者应用时,你需要指定 ZooKeeper 的地址而非 Broker的地址。

    诚然,基于 0.8 的版本在大多数环境条件下能够提高分布式高可靠的解决方案,但在某些特定的场景中可能会造成消息的丢失,因此 0.8.2.0 版本社区引入了新版本 Producer API,即需要指定 Broker 地址的 Producer。经过几年的发展,2015 年 11 月,社区正式发布了 0.9.0.0 版本。基于当前的环境,这是一个重量级的大版本更迭,0.9 大版本增加了基础的安全认证 / 权限功能,同时使用 Java 重写了新版本消费者 API,另外还引入了 Kafka Connect 组件用于实现高性能的数据抽取。

    在后续的历史发展过程中,0.10.0.0 是一款里程碑式的大版本,毕竟,此版本引入了 Kafka Streams。正式向大家宣布了从这个版本起,Kafka 正式升级成分布式流处理平台,同时,不久后,在 2017 年 6 月,社区发布了 0.11.0.0 版本,引入了两个重量级的功能变更:一个是提供幂等性 Producer API 以及事务(Transaction) API。

    因此,当我们的业务场景无特殊要求时,若基于当前的版本出现各种性能问题,建议在后续的迭代开发中进行 Kafka 版本的升级(Server 端与 Client  端),以提升系统运行能力。(此种优化策略在笔者之前所经历的公司业务场景中均曾出现过)

    2. 理解数据吞吐率

    在整个 Kafka 体系中,Partition 分区是吞吐量性能所基于的存储层。

    每个分区的数据速率是消息的平均大小乘以每秒的消息数。简而言之,它是数据通过分区的速率。所需的吞吐率决定了分区的目标架构。Kafka 中的 Topic 中的内容可以被划分为多分 Partition ,每个 Partition 又分为多个段 Segment,所以每次操作都是针对一小部分做操作,很轻便,并且增加并行操作的能力

    Kafka 基于磁盘顺序读写来提升性能的。Kafka 的消息是不断追加到本地磁盘文件末尾,而不是随机的写入,这使得 Kafka 写入吞吐量得到了显著提升 。在 Kafka 中, 每一个partition其实都是一个文件 ,收到消息后 Kafka 会把数据插入到文件末尾。

    因此,在某些特定的场景中,或许,此种方案也是一个关键的 Kafka 优化技巧:为了提高吞吐量,我们可以扩大请求中获取的最小数据量。这导致更少的请求。然后以更大的批次传递消息。这一点至关重要,尤其是在生成的数据量较少时。对 Kafka 吞吐量指标的广泛了解将帮助用户在这种情况下完全优化他们的 Kafka 系统。

    3. 写入 Topic 时依据架构要求实现自定义分区

    其实,分区的作用就是提供负载均衡的能力,或者说对数据进行分区的主要原因,就是为了实现系统的高伸缩性(Scalability)。不同的分区能够被放置到不同节点的机器上,而数据的读写操作也都是针对分区这个粒度而进行的,这样每个节点的机器都能独立地执行各自分区的读写请求处理,并且,我们还可以通过添加新的节点机器来增加整体系统的吞吐量

    分区是实现负载均衡以及高吞吐量的关键,故在生产者这一端就要仔细盘算合适的分区策略,避免造成消息数据的倾斜,使得某些分区成为性能瓶颈,这样极易引发下游数据消费的性能下降。在实际的业务场景中,我们希望每个分区都支持类似的数据量和吞吐率。实际上,数据速率随着时间的推移而变化,生产者和消费者的原始数量也是如此。

    可变性带来的性能挑战是消费者滞后的可能性,即消费者读取率落后于生产者写入率。在前期的业务场景中,随着 Kafka 环境的扩展,随机分区或许是一种有效的方法,可确保我们不会在尝试将静态定义应用于移动性能目标时引入人为瓶颈。

    分区领导通常是通过 Zookeeper 维护的元数据进行简单选举的产物。然而,领导选举不考虑单个分区的性能。

    根据当前业务架构所选型的 Kafka 版本,可以利用专有的平衡器。但是缺少这样的工具,随机分区提供了平衡性能的最不干涉的途径。

    这就是为什么有的时候、有的场景,随机分区是我们推荐的关键 Apache Kafka 最佳实践之一。它为消费者平均分配负载。因此,扩展消费者变得更加容易。当使用默认分区器而不手动识别特定分区或消息键时,实际上会发生这种情况。随机分区最适合无状态或“令人尴尬的并行”服务。

    基于以上,分区是实现负载均衡以及高吞吐量的关键,故在生产者端我们需要仔细盘算合适的分区策略,避免造成消息数据的倾斜,使得某些分区成为性能瓶颈,这样极易引发下游数据消费的性能下降。

    4. 调整消费者套接字缓冲区

    在 Kafka 中消息存储模式中,数据存储在底层文件系统中。当有 Consumer 订阅了相应的 Topic 消息,数据需要从磁盘中读取然后将数据写回到套接字中(Socket)。此动作看似只需较少的 CPU 活动,但它的效率非常低:首先内核读出全盘数据,然后将数据跨越内核用户推到应用程序,然后应用程序再次跨越内核用户将数据推回,写出到套接字。应用程序实际上在这里担当了一个不怎么高效的中介角色,将磁盘文件的数据转入套接字。

    基于 Zero-Copy 零拷贝技术,使应用程序要求内核直接将数据从磁盘文件拷贝到套接字,而无需通过应用程序。零拷贝不仅大大地提高了应用程序的性能,而且还减少了内核与用户模式间的上下文切换。

    在较旧的 Kafka 版本中,参数 receive.buffer.bytes 设置为 64kB 作为其默认值。在较新的 Kafka 版本中,该参数为 socket.receive.buffer.bytes,默认为 100kB。

    这对 Kafka 优化意味着什么?对于高吞吐量环境,这些默认值太小,因此不足以支撑当前的业务架构要求。当 Broker 和 Consumer 之间的网络带宽延迟乘积大于 LAN(局域网)的带宽延迟乘积时,就会出现这种情况。

    除此,当没有足够的磁盘空间时,线程执行会变慢并受到限制。最重要的 Apache Kafka 最佳实践之一是增加网络请求缓冲区的大小。这样做将可以帮助应用提高吞吐量。如果我们的网络以 10 Gbps 或更高的速度运行并且延迟为 1 毫秒或更多,则建议将其接字缓冲区调整为 8 或 16 MB。如果内存表现异常,可以尝试考虑配置为 1 MB。因此,在某些特定的场景中,我们可以通过调整消费者套接字缓冲区以实现高速摄取,从而提升性能。

    基于上述所述,在实际的业务场景中,依据当前的业务架构及应用场景,进行合理的、适配的性能调优显得尤为重要。尤其是在高复杂性、高稳定性、高吞吐性的应用场景中更具有参考意义。

相关文章
|
6月前
|
消息中间件 存储 网络协议
【Kafka】Kafka 性能高的原因分析
【4月更文挑战第5天】【Kafka】Kafka 性能高的原因分析
|
23天前
|
消息中间件 存储 监控
构建高可用性Apache Kafka集群:从理论到实践
【10月更文挑战第24天】随着大数据时代的到来,数据传输与处理的需求日益增长。Apache Kafka作为一个高性能的消息队列服务,因其出色的吞吐量、可扩展性和容错能力而受到广泛欢迎。然而,在构建大规模生产环境下的Kafka集群时,保证其高可用性是至关重要的。本文将从个人实践经验出发,详细介绍如何构建一个高可用性的Kafka集群,包括集群规划、节点配置以及故障恢复机制等方面。
58 4
|
23天前
|
消息中间件 监控 大数据
优化Apache Kafka性能:最佳实践与调优策略
【10月更文挑战第24天】作为一名已经对Apache Kafka有所了解并有实际使用经验的开发者,我深知在大数据处理和实时数据流传输中,Kafka的重要性不言而喻。然而,在面对日益增长的数据量和业务需求时,如何保证系统的高性能和稳定性成为了摆在我们面前的一个挑战。本文将从我的个人视角出发,分享一些关于如何通过合理的配置和调优来提高Kafka性能的经验和建议。
60 4
|
1月前
|
消息中间件 存储 监控
说说如何解决RocketMq消息积压?为什么Kafka性能比RocketMq高?它们区别是什么?
【10月更文挑战第8天】在分布式系统中,消息队列扮演着至关重要的角色,它不仅能够解耦系统组件,还能提供异步处理、流量削峰和消息持久化等功能。在众多的消息队列产品中,RocketMQ和Kafka无疑是其中的佼佼者。本文将围绕如何解决RocketMQ消息积压、为什么Kafka性能比RocketMQ高以及它们之间的区别进行深入探讨。
82 1
|
3月前
|
图形学 人工智能 C#
从零起步,到亲手实现:一步步教你用Unity引擎搭建出令人惊叹的3D游戏世界,绝不错过的初学者友好型超详细指南 ——兼探索游戏设计奥秘与实践编程技巧的完美结合之旅
【8月更文挑战第31天】本文介绍如何使用Unity引擎从零开始创建简单的3D游戏世界,涵盖游戏对象创建、物理模拟、用户输入处理及动画效果。Unity是一款强大的跨平台游戏开发工具,支持多种编程语言,具有直观编辑器和丰富文档。文章指导读者创建新项目、添加立方体对象、编写移动脚本,并引入基础动画,帮助初学者快速掌握Unity开发核心概念,迈出游戏制作的第一步。
204 1
|
3月前
|
消息中间件 Kafka 测试技术
【Azure 事件中心】使用Kafka的性能测试工具(kafka-producer-perf-test)测试生产者发送消息到Azure Event Hub的性能
【Azure 事件中心】使用Kafka的性能测试工具(kafka-producer-perf-test)测试生产者发送消息到Azure Event Hub的性能
|
3月前
|
消息中间件 传感器 缓存
为什么Kafka能秒杀众多消息队列?揭秘它背后的五大性能神器,让你秒懂Kafka的极速之道!
【8月更文挑战第24天】Apache Kafka作为分布式流处理平台的领先者,凭借其出色的性能和扩展能力广受好评。本文通过案例分析,深入探讨Kafka实现高性能的关键因素:分区与并行处理显著提升吞吐量;批量发送结合压缩算法减少网络I/O次数及数据量;顺序写盘与页缓存机制提高写入效率;Zero-Copy技术降低CPU消耗;集群扩展与负载均衡确保系统稳定性和可靠性。这些机制共同作用,使Kafka能够在处理大规模数据流时表现出色。
63 3
|
3月前
|
分布式计算 搜索推荐 物联网
大数据及AI典型场景实践问题之通过KafKa+OTS+MaxCompute完成物联网系统技术重构如何解决
大数据及AI典型场景实践问题之通过KafKa+OTS+MaxCompute完成物联网系统技术重构如何解决
|
3月前
|
消息中间件 负载均衡 Kafka
Kafka 实现负载均衡与故障转移:深入分析 Kafka 的架构特点与实践
【8月更文挑战第24天】Apache Kafka是一款专为实时数据处理和流传输设计的高性能消息系统。其核心设计注重高吞吐量、低延迟与可扩展性,并具备出色的容错能力。Kafka采用分布式日志概念,通过数据分区及副本机制确保数据可靠性和持久性。系统包含Producer(消息生产者)、Consumer(消息消费者)和Broker(消息服务器)三大组件。Kafka利用独特的分区机制实现负载均衡,每个Topic可以被划分为多个分区,每个分区可以被复制到多个Broker上,确保数据的高可用性和可靠性。
77 2
|
3月前
|
消息中间件 存储 算法
时间轮在Kafka的实践:技术深度剖析
【8月更文挑战第13天】在分布式消息系统Kafka中,时间轮(Timing Wheel)作为一种高效的时间调度机制,被广泛应用于处理各种延时操作,如延时生产、延时拉取和延时删除等。本文将深入探讨时间轮在Kafka中的实践应用,解析其技术原理、优势及具体实现方式。
126 2