Apache Kafka 以其处理大量实时事件的能力而闻名。然而,为了处理数百万个事件,我们在实现 Kafka 生产者服务和消费者服务时需要遵循某些最佳实践。
在开始使用 Kafka之前,让我们了解何时使用 Kafka:
- 高流量事件流。当您的应用程序/服务生成连续的事件流,如用户活动事件、网站点击事件、传感器数据事件、日志事件或股市更新时,Kafka 处理大规模低延迟的能力非常有用。
- 实时分析。Kafka 在构建实时数据处理管道方面尤其非常有用,在这些管道中,数据需要在到达时立即处理。它允许您将数据流式传输到分析引擎,如 Kafka Streams、Apache Spark 或 Flink,以进行即时分析/洞察和流式或批处理。
- 解耦应用程序。作为中央消息中心,它可以解耦应用程序的不同部分,使服务能够独立开发和扩展,鼓励负责任的分离原则。
- 系统间数据集成。在集成分布式系统时,Kafka可以高效地在不同团队/项目之间传输数据,充当可靠的数据代理。
与其他队列系统的关键区别
以下是Apache Kafka与ActiveMQ、ZeroMQ和VerneMQ等系统的区别:
持久性存储
Kafka将事件存储在分布式日志中,允许随时重放数据并在系统/节点故障时保持数据持久性,不像一些依赖于内存存储(如Redis)的传统消息队列。
分区
数据分布在经纪人/主题之间,实现大数据流的并行处理和高吞吐量。这有助于消费者线程连接到单个分区,促进水平扩展。
消费者组
多个消费者可以订阅同一主题并从分区内的不同偏移量读取,允许不同团队的重复消费模式用于不同目的消费和处理相同数据。一些示例包括:
- 由ML团队消费的用户活动以便检测可疑活动
- 建议团队构建推荐系统
- 广告团队生成相关广告
Kafka生产者最佳实践
批处理大小和等待时间
通过配置batch.size
和linger.ms
,可以提高Kafka生产者的吞吐量。 batch.size
是批处理的最大字节大小。 Kafka在发送给生产者之前会尝试进行批处理。
linger.ms
确定生产者等待将其他消息添加到批处理中进行处理的最大时间(以毫秒为单位)。
通过配置batch size
和linger.ms
设置,可以显著提高系统的性能,控制在将数据发送到处理系统之前累积多少数据,从而实现更好的吞吐量和降低延迟,尤其是在处理大量数据时。它还可能根据所选择的值引入轻微的延迟。特别是,具有正确的linger.ms
的大批处理大小可以优化数据传输效率。
压缩
通过启用compression.type
配置,还可以通过压缩来增加吞吐量。生产者可以在将数据发送到代理之前使用gzip
、snappy
或lz4
对数据进行压缩。对于大数据量,该配置有助于减少压缩开销,提高网络效率。它还节省带宽并提高系统的吞吐量。此外,通过设置适当的序列化器和键序列化器,我们可以确保数据以与您的消费者兼容的格式进行序列化。
重试和幂等性
为确保Kafka生产者的可靠性,应启用重试和幂等性。通过配置retries
,生产者可以在一定数量的尝试内,自动重新发送任何未在经纪人处获得ack
的数据批次。
确认
此配置控制在考虑消息发送成功之前从代理那里需要的确认级别。通过选择正确的acks
级别,您可以控制应用程序的可靠性。以下是此配置的可接受值。
- 0 – 最快,但不能保证消息传递。
- 1 – 消息在写入主代理后得到确认,提供基本的可靠性。
- all – 仅当所有副本都确认后,消息才被视为传递,确保高耐用性。
根据工作负载进行配置调优
您应该开始跟踪指标,例如消息发送率、批量大小和错误率,以识别性能瓶颈。根据功能/数据的修改或更新,定期检查并调整生产者设置。
Kafka消费者最佳实践
消费者组
每个Kafka消费者都应属于一个消费者组;一个消费者组可以包含一个或多个消费者。通过在组中创建更多消费者,您可以扩展以从所有分区读取,从而允许您处理大量数据。group.id
配置有助于识别消费者所属的消费者组,从而在多个消费者之间实现负载均衡,这些消费者从同一主题消费。最佳实践是使用有意义的组ID,以便在您的应用程序中轻松识别消费者组。
偏移量提交
您可以控制何时提交偏移量,这可以帮助避免数据丢失。有两种提交偏移量的方法:自动和手动。对于高吞吐量的应用程序,您应考虑手动提交以获得更好的控制。
- auto.offset.reset – 定义当消费者开始消费没有提交偏移量的主题时要执行的操作(例如,新主题或消费者首次加入组时)。 选项包括
earliest
(从开头读取)、latest
(从末尾读取)或none
(抛出错误)。 在大多数情况下选择”earliest”,以避免新消费者加入组时丢失数据。控制消费者开始消费数据的方式,确保在消费者重新启动或加入组时保持正确行为。 - enable.auto.commit – 帮助配置定期自动提交偏移量。通常,在大多数生产场景中,我们将值设置为
false
,这样我们就不需要高可靠性,并且可以在应用程序逻辑中手动提交偏移量,以确保精确一次处理。提供控制以管理偏移提交,从而更好地控制数据处理。 - auto.commit.interval.ms – interval指定以毫秒为单位的时间间隔,在此间隔内,如果
enable.auto.commit
设置为true
,则偏移量将自动提交。根据您的应用程序处理时间进行修改,以避免由于意外故障而导致数据丢失。
Fetch Size和Max Poll Records
该配置有助于控制每个请求中检索的记录数量,配置fetch.min.bytes
和max.poll.records
。增加此值可以提高应用程序的吞吐量,同时减少CPU使用率并减少向代理程序发出的调用次数。
- fetch.min.bytes – 每个单独的轮询请求从代理程序获取的最小字节数。设置一个较小的值以避免不必要的网络调用,但不要设置得太小以避免过多的轮询。通过防止频繁的小请求,有助于优化网络效率。
- fetch.max.bytes – 单个拉取请求从代理中拉取的最大字节数。 根据可用内存调整,以防止过载消费者工作。这可以减少 单次拉取的数据量,避免内存问题。
- max.poll.interval.ms – 在超时之前等待拉取请求返回数据的最长时间。 设置一个合理的超时时间,以避免消费者挂起/延迟,如果数据不可用。它有助于防止 消费者等待消息时间过长而被卡住。(有时,如果活跃探针受影响,k8s pods可能会重新启动)。
分区分配
这是用于将分区(partition.assignment.strategy
)分配给组内消费者的策略(例如,range
、roundrobin
)。 对于大多数情况,请使用 range
以均匀分配分区给消费者。这可以实现 组内消费者之间负载均衡分布。
在使用Kafka之前的一些建议考虑事项:
- 复杂性。实施Kafka需要对分区和偏移管理等分布式系统概念有更深入的了解,因为它具有先进的功能和配置。
- 监控和管理。实施监控和Kafka集群管理对于确保高可用性和性能至关重要。
- 安全性。实施强大的安全实践来保护通过Kafka主题传输的敏感数据也很重要。
实施这些最佳实践可以帮助您扩展基于Kafka的应用程序以处理数百万/数十亿个事件。然而,重要的是要记住,最佳配置可能因应用程序的具体要求而有所不同。
Source:
https://dzone.com/articles/best-practices-for-scaling-kafka-based-workloads