跨越消费者的kafka日志删除和负载平衡

时间:2015-07-21 18:47:14

标签: apache-kafka

假设消费者进行了时间密集型处理。为了扩展消费者端处理,我想以循环方式从kafka主题中生成多个消费者和消费者消息。根据文档,似乎我创建了多个消费者并将它们添加到一个消费者组中,只有一个消费者会获得消息。如果我将消费者添加到不同的消费者群体,每个消费者将获得相同的消息。那么,为了实现上述目标,是分区主题的唯一解决方案吗?这似乎是一个奇怪的设计选择,因为消费者的可扩展性现在正在流行到主题甚至生产者设计。理想情况下,如果主题没有分区,则不需要对其进行分区。这为生产者提供了不必要的逻辑,并且还使得其他消费者类型从这些分区中消费,这些分区可能仅对一种类型的消费者有意义。另外,它限制了用例,其中某个消费者类型可能希望对消息进行排序,因此可能无法将主题拆分为分区。

第二,如果我选择" cleanup.policy"紧凑,这是否意味着kafka日志将继续增加,因为它将保持每个密钥的最新值?如果没有,我如何获取日志删除和压缩?

更新: 看起来我有两种选择来实现消费者方面的可扩展性,这与主题扩展无关。

  1. 创建消费者群组并让他们消耗奇数和偶数偏移量。必须将此逻辑构建到消费者中以丢弃不需要的消息。也是网络要求的两倍

  2. 创建主题层次结构,其中根主题获取所有消息。然后,一些作业将日志分类并再次发布到更精细的主题。在这种情况下,可以在根处实现强排序,并且可以构建用于消费者缩放的更细粒度的主题。

  3. 在0.8中,kafka维持消费者的抵消,因此在各种消费者的循环中发布消息并不是他们设计的过分要求。

3 个答案:

答案 0 :(得分:2)

分区是Kafka设计中的并行度的单位。不仅仅是为了消费,而且kafka分发集群中的分区,它具有不同的其他好处,例如在不同服务器之间共享负载,复制管理以确保没有数据丢失,管理日志扩展到超出适合单个服务器的大小等。

消息排序是一个关键因素,因为如果您不需要storng排序,那么具有多个分区的潜水主题将允许您在生成时均匀分配负载(这将由生产者自己处理)。在使用消费者群体时,您只需要在同一个群组中添加更多消费者实例,以便平行消费它们。

另外它限制了用例,其中某个消费者类型可能希望对消息进行排序,因此可能无法将主题拆分为分区。

是的,来自文档

  

但是,如果您需要对邮件进行总订单,则可以通过仅包含一个分区的主题来实现,但这只会意味着一个客户流程。

维护以分布式方式消费的排序要求消息传递系统保持per-message状态以跟踪消息确认。但这将涉及系统中许多昂贵的随机I / O.显然,需要权衡利弊。

理想情况下,如果主题没有分区,则不需要对其进行分区。这会在生产者身上放置不必要的逻辑,并且还会导致其他消费者类型从这些分区中消费,而这些分区可能只对某种类型的消费者有意义

跨分区分发消息通常由生产者自己处理,无需程序员的任何干预(假设您不想使用密钥对消息进行分类)。对于刚刚提到的消费者来说,更好的选择是使用简单/低级消费者,这将允许您仅消费主题中的一部分分区。

这似乎是一个奇怪的设计选择,因为消费者可扩展性现在正在流行到主题甚至是制作人设计

我相信像Kafka这样的系统专注于高吞吐量(每秒从数千个客户端处理数百兆字节的读写),确保可扩展性和强大的耐用性以及容错保证可能不适合某人有完全不同的业务要求。

答案 1 :(得分:0)

主题分区主要是扩展消费者和经纪人的一种方式,因此如果您需要许多消费者跟上,那么您需要对主题进行分区并在同一个消费者组中添加多个消费者实例。生产者API将透明地管理分区。如果您需要让某些消费者仅订阅某些分区,那么您需要使用简单的消费者API而不是高级API,在这种情况下,您不具备消费者群体概念并且必须自己协调消费。

在分区内保证消息排序,但在分区之间不保证消息排序,因此如果需要,则需要在消费者方面处理。

设置cleanup.policy=compact意味着Kafka代理将无限期地保留最新版本的消息密钥,并且这样的用例应该更多地用于记录您要保留的内容的数据更新而不是日志流缓冲用例。

答案 2 :(得分:0)

您需要考虑从后续处理这些消息中读取Kafka消息。您可以使用分区和使用者组来尽快读取消息,但如果您将消息作为消费者逻辑的一部分进行处理,那么您只会减慢消费者的速度。通过将消息从消费者流式传输到将执行处理的其他类,您可以独立调整消费者和处理器的并行性。您将在Spark和Storm等技术中看到这种方法。

这种方法确实增加了一个复杂性,即消费者必须在处理消息之前提交消息偏移量。您可能必须跟踪飞行中的消息以确保执行完全一次。