Apache Kafka是一款流行的分布式数据流平台,它已经广泛地被诸如New Relic(数据智能平台)、Uber、Square(移动支付公司)等大型公司用来构建可扩展的、高吞吐量的、且高可靠的实时数据流系统。例如,在New Relic的生产环境中,Kafka群集每秒能够处理超过1500万条消息,而且其数据聚合率接近1 Tbps。
可见,Kafka大幅简化了对于数据流的处理,因此它也获得了众多应用开发人员和数据管理专家的青睐。然而,在大型系统中Kafka的应用会比较复杂。如果您的consumers无法跟上数据流的话,各种消息往往在未被查看之前就已经消失掉了。同时,它在自动化数据保留方面的限制,高流量的发布+订阅(publish-subscribe,pub/sub)模式等,可能都会影响到您系统的性能。可以毫不夸张地说,如果那些存放着数据流的系统无法按需扩容、或稳定性不可靠的话,估计您经常会寝食难安了。
为了减少上述复杂性,我在此分享New Relic公司为Kafka集群在应对高吞吐量方面的20项最佳实践。我将从如下四个方面进行展开:
-
Partitions(分区)
-
Consumers(消费者)
-
Producers(生产者)
-
Brokers(代理)
针对Partitions的最佳实践
• 了解分区的数据速率,以确保提供合适的数据保存空间。此处所谓“分区的数据速率”是指数据的生成速率。换言之,它是由“平均消息大小”乘以“每秒消息数”得出的。数据速率决定了在给定时间内,所能保证的数据保存空间的大小(以字节为单位)。如果您不知道数据速率的话,则无法正确地计算出满足基于给定时间跨度的数据,所需要保存的空间大小。同时,数据速率也能够标识出单个consumer在不产生延时的情况下,所需要支持的最低性能值。
• 除非您有其他架构上的需要,否则在写topic时请使用随机分区。在您进行大型操作时,各个分区在数据速率上的参差不齐是非常难以管理的。其原因来自于如下三个方面:
-
首先,“热”(有较高吞吐量)分区上的consumer势必会比同组中的其他consumer处理更多的消息,因此很可能会导致出现在处理上和网络上的瓶颈。
-
其次,那些为具有最高数据速率的分区,所配置的最大保留空间,会导致topic中其他分区的磁盘使用量也做相应地增长。
-
第三,根据分区的leader关系所实施的最佳均衡方案,比简单地将leader关系分散到所有broker上,要更为复杂。在同一topic中,“热”分区会“承载”10倍于其他分区的权重。
针对Consumers的最佳实践
如果consumers运行的是比Kafka 0.10还要旧的版本,那么请马上升级。在0.8.x 版中,consumer使用Apache ZooKeeper来协调consumer group,而许多已知的bug会导致其长期处于再均衡状态,或是直接导致再均衡算法的失败(我们称之为“再均衡风暴”)。因此在再均衡期间,一个或多个分区会被分配给同一组中的每个consumer。而在再均衡风暴中,分区的所有权会持续在各个consumers之间流转,这反而阻碍了任何一个consumer去真正获取分区的所有权。
调优consumer的套接字缓冲区(socket buffers),以应对数据的高速流入。在Kafka的0.10.x版本中,参数receive.buffer.bytes的默认值为64 kB。而在Kafka的0.8.x版本中,参数socket.receive.buffer.bytes的默认值为100 kB。这两个默认值对于高吞吐量的环境而言都太小了,特别是如果broker和consumer之间的网络带宽延迟积(bandwidth-delay product)大于局域网(local area network,LAN)时。对于延迟为1毫秒或更多的高带宽的网络(如10 Gbps或更高),请考虑将套接字缓冲区设置为8或16 MB。如果您的内存不足,也至少考虑设置为1 MB。当然,您也可以设置为-1,它会让底层操作系统根据网络的实际情况,去调整缓冲区的大小。但是,对于需要启动“热”分区的consumers来说,自动调整可能不会那么快。
设计具有高吞吐量的consumers,以便按需实施背压(back-pressure)。通常,我们应该保证系统只去处理其能力范围内的数据,而不要超负荷“消费”,进而导致进程中断“挂起”,或出现consume group的溢出。如果是在Java虚拟机(JVM)中运行,consumers应当使用固定大小的缓冲区(请参见Disruptor模式:http://lmax-exchange.github.io/disruptor/files/Disruptor-1.0.pdf),而且最好是使用堆外内存(off-heap)。固定大小的缓冲区能够阻止consumer将过多的数据拉到堆栈上,以至于JVM花费掉其所有的时间去执行垃圾回收,进而无法履行其处理消息的本质工作。
在JVM上运行各种consumers时,请警惕垃圾回收对它们可能产生的影响。例如,长时间垃圾回收的停滞,可能导致ZooKeeper的会话被丢弃、或consumer group处于再均衡状态。对于broker来说也如此,如果垃圾回收停滞的时间太长,则会产生集群掉线的风险。
针对Producers的最佳实践
• 配置producer,以等待各种确认。籍此producer能够获知消息是否真正被发送到了broker的分区上。在Kafka的0.10.x版本上,其设置是acks;而在0.8.x版本上,则为request.required.acks。Kafka通过复制,来提供容错功能,因此单个节点的故障、或分区leader关系的更改不会影响到系统的可用性。如果您没有用acks来配置producer(或称“fire and forget”)的话,则消息可能会悄然丢失。
• 为各个producer配置retries。其默认值为3,当然是非常低的。不过,正确的设定值取决于您的应用程序,即:就那些对于数据丢失零容忍的应用而言,请考虑设置为Integer.MAX_VALUE(有效且最大)。这样将能够应对broker的leader分区出现无法立刻响应produce请求的情况。
• 为高吞吐量的producer,调优缓冲区的大小,特别是buffer.memory和batch.size(以字节为单位)。由于batch.size是按照分区设定的,而producer的性能和内存的使用量,都可以与topic中的分区数量相关联。因此,此处的设定值将取决于如下几个因素:producer数据速率(消息的大小和数量)、要生成的分区数、以及可用的内存量。请记住,将缓冲区调大并不总是好事,如果producer由于某种原因而失效了(例如,某个leader的响应速度比确认还要慢),那么在堆内内存(on-heap)中的缓冲的数据量越多,其需要回收的垃圾也就越多。
• 检测应用程序,以跟踪诸如生成的消息数、平均消息大小、以及已使用的消息数等指标。
针对Brokers的最佳实践
• 在各个brokers上,请压缩topics所需的内存和CPU资源。日志压缩需要各个broker上的堆栈(内存)和CPU周期都能成功地配合实现。而如果让那些失败的日志压缩数据持续增长的话,则会给brokers分区带来风险。您可以在broker上调整log.cleaner.dedupe.buffer.size和log.cleaner.threads这两个参数,但是请记住,这两个值都会影响到各个brokers上的堆栈使用。如果某个broker抛出OutOfMemoryError异常,那么它将会被关闭、并可能造成数据的丢失。而缓冲区的大小和线程的计数,则取决于需要被清除的topic partition数量、以及这些分区中消息的数据速率与密钥的大小。对于Kafka的0.10.2.1版本而言,通过ERROR条目来监控日志清理程序的日志文件,是检测其线程可能出现问题的最可靠方法。
• 通过网络吞吐量来监控brokers。请监控发向(transmit,TX)和收向(receive,RX)的流量,以及磁盘的I/O、磁盘的空间、以及CPU的使用率,而且容量规划是维护群集整体性能的关键步骤。
• 在群集的各个brokers之间分配分区的leader关系。Leader通常会需要大量的网络I/O资源。例如,当我们将复制因子(replication factor)配置为3、并运行起来时,leader必须首先获取分区的数据,然后将两套副本发送给另两个followers,进而再传输到多个需要该数据的consumers上。因此在该例子中,单个leader所使用的网络I/O,至少是follower的四倍。而且,leader还可能需要对磁盘进行读操作,而follower只需进行写操作。
• 不要忽略监控brokers的in-sync replica(ISR)shrinks、under-replicated partitions和unpreferred leaders。这些都是集群中潜在问题的迹象。例如,单个分区频繁出现ISR收缩,则暗示着该分区的数据速率超过了leader的能力,已无法为consumer和其他副本线程提供服务了。
• 按需修改Apache Log4j的各种属性。Kafka的broker日志记录会耗费大量的磁盘空间,但是我们却不能完全关闭它。因为有时在发生事故之后,需要重建事件序列,那么broker日志就会是我们最好的、甚至是唯一的方法。
• 禁用topic的自动创建,或针对那些未被使用的topics建立清除策略。例如,在设定的x天内,如果未出现新的消息,您应该考虑该topic是否已经失效,并将其从群集中予以删除。此举可避免您花时间去管理群集中被额外创建的元数据。
• 对于那些具有持续高吞吐量的brokers,请提供足够的内存,以避免它们从磁盘子系统中进行读操作。我们应尽可能地直接从操作系统的缓存中直接获取分区的数据。然而,这就意味着您必须确保自己的consumers能够跟得上“节奏”,而对于那些延迟的consumer就只能强制broker从磁盘中读取了。
• 对于具有高吞吐量服务级别目标(service level objectives,SLOs)的大型群集,请考虑为brokers的子集隔离出不同的topic。至于如何确定需要隔离的topics,则完全取决于您自己的业务需要。例如,您有一些使用相同群集的联机事务处理(multiple online transaction processing,OLTP)系统,那么将每个系统的topics隔离到不同brokers子集中,则能够有助于限制潜在事件的影响半径。
• 在旧的客户端上使用新的topic消息格式。应当代替客户端,在各个brokers上加载额外的格式转换服务。当然,最好还是要尽量避免这种情况的发生。
• 不要错误地认为在本地主机上测试好broker,就能代表生产环境中的真实性能了。要知道,如果使用复制因子为1,并在环回接口上对分区所做的测试,是与大多数生产环境截然不同的。在环回接口上网络延迟几乎可以被忽略的,而在不涉及到复制的情况下,接收leader确认所需的时间则同样会出现巨大的差异。
其他资源
希望上述各项建议能够有助于您更有效地去使用Kafka。如果您想提高自己在Kafka方面的专业知识,请进一步查阅Kafka配套文档中的“操作”部分,其中包含了有关操作群集等实用信息。此外,Confluent(https://www.confluent.io/)也会定期举行并发布各种在线讨论,以帮助您更好地了解Kafka。
本文英文原文《20 Best Practices for Working With Apache Kafka at Scale》:https://blog.newrelic.com/engineering/kafka-best-practices/
相关推荐
它结合了消息队列和日志聚合的功能,使得大规模数据的实时处理变得高效且可靠。 **核心概念** 1. **主题(Topics)**:主题是Kafka中的数据存储结构,类似于数据库的表,数据被分片存储在多个分区(Partitions)中...
- 这些资源提供了实用的技巧和最佳实践案例,有助于加深对 Kafka 的理解。 5. **工具和库**: - Kafka Connect:用于将 Kafka 与外部系统连接的框架。 - Kafka Streams:用于构建流处理应用程序的库。 - ...
5. **最佳实践与案例分享**:分享了实际项目中Kafka和Flink结合使用的一些成功案例,以及遇到的问题和解决方案。 6. **性能优化**:讲解如何调整Kafka和Flink的配置以提升系统的吞吐量和响应速度。 7. **未来发展...
- 遵守Kafka的最佳实践,如合理设置分区数和副本数,避免单点故障。 - 注意监控Kafka-Manager自身的资源消耗,避免影响其正常运行。 总的来说,Kafka-Manager为Kafka的日常运维提供了便利,使得管理复杂的大规模...
Kafka的分布式特性使其非常适合在大规模集群中运行,可以轻松扩展以应对不断增长的数据流量。同时,通过结合其他大数据工具,如Spark、Flink或Hadoop,可以构建复杂的数据处理管道,实现实时分析和决策。 总的来说...
书中通过丰富的案例和最佳实践,引导读者学习如何配置和优化Kafka的性能,确保其能够满足不同业务场景的需求。特别值得一提的是,这本书提供了与其他大数据组件集成的详细指南,例如如何将Kafka与Hadoop、Spark等...
1. 高吞吐量:Kafka能够处理每秒数十万条消息,适合大规模数据传输。 2. 离线与在线处理:Kafka的消息存储在磁盘上,支持实时消费的同时,也便于离线批量处理。 3. 分区与复制:消息被分到多个分区,每个分区可以在...
Kafka是一种强大的分布式消息中间件,由LinkedIn开发并贡献给Apache软件基金会,它在处理大规模实时数据流方面表现出色。Kafka的核心概念包括主题(Topics)、分区(Partitions)和副本(Replicas)。在本文中,我们...
- **高吞吐量**:设计时考虑了大规模并发写入和读取,能处理大量的实时数据流。 - **持久化**:消息被持久化到硬盘,保证在故障后可恢复。 - **容错性**:通过副本机制和故障切换策略保证服务连续性。 - **实时...
- **高吞吐量**:Kafka设计时考虑了大规模数据处理,能够处理每秒数十万条消息。 - **持久化**:消息默认会被持久化到磁盘,即使在服务器故障后也能恢复。 - **可扩展性**:通过添加更多的Broker节点,可以轻松...
它最初设计的目的是解决大规模日志聚合问题,但随着时间的推移,Kafka 已经发展成为适用于多种场景的消息中间件,包括实时数据流处理、数据集成以及大数据分析。Kafka 2.11-1.0.0 版本是其中的一个重要里程碑,提供...
这使得Kafka能够处理大规模的数据流,并保持高性能。 6. **实时流处理**:Kafka结合Apache Flink或Spark Streaming等实时处理框架,可以构建实时数据处理管道,实现实时分析和决策。 7. **安全性与认证**:Kafka...
在大规模数据处理、日志收集、实时分析等领域有着广泛的应用。 《Kafka权威指南》可能涵盖以下知识点: 1. **Kafka基本概念**:包括生产者、消费者、主题、分区和副本等核心概念,以及它们在Kafka架构中的作用。 2...
- **高吞吐量**:Kafka设计时就考虑到了大规模数据处理的需求,能处理每秒数十万条消息。 - **持久化**:Kafka将消息存储在磁盘上,提供持久化能力,即使服务器重启也不会丢失数据。 - **可扩展性**:通过增加...
Apache Kafka作为一种实时数据和流处理平台,能够在大规模环境下实时处理数据,它与现代大数据技术和微服务架构的结合使其成为业界关注的焦点。通过本书的学习,开发者不仅能够掌握Kafka的使用,而且能够理解在企业...
在构建和管理大规模分布式消息系统时,Apache Kafka通常与Zookeeper协同工作,形成高效、可靠的实时数据流处理平台。Kafka作为一个高吞吐量、低延迟的发布/订阅消息系统,而Zookeeper则是一个分布式协调服务,用于...
**Apache Kafka** 是一款高性能、分布式的发布-订阅消息系统,适用于处理大规模实时数据流。它最初由LinkedIn开发,后捐赠给Apache软件基金会,并成为顶级项目。Kafka的核心设计理念在于其能够提供一种高效的、持久...
2. 性能优化:根据实际需求调整 Kafka Manager 的配置,如调整缓存大小,以适应大规模集群的管理。 3. 定期更新:关注 Kafka Manager 的新版本发布,及时升级以获取最新的功能和修复的安全漏洞。 总结,Kafka ...