【问题标题】:kafka log deletion and load balancing across consumerskafka 日志删除和消费者之间的负载均衡
【发布时间】:2015-10-11 09:20:09
【问题描述】:

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

其次,如果我选择“cleanup.policy”进行压缩,是否意味着 kafka 日志会不断增加,因为它将保持每个键的最新值?如果没有,我怎样才能获得日志删除和压缩?

更新: 似乎我有两种选择可以在消费者端实现可扩展性,它们独立于主题扩展。

  1. 创建消费者组并让他们消费奇数和偶数偏移量。这个逻辑必须内置到消费者中以丢弃不需要的消息。网络需求也翻倍

  2. 创建主题层次结构,其中根主题获取所有消息。然后一些工作对日志进行分类并将它们再次发布到更细粒度的主题。在这种情况下,可以在根上实现强排序,并且可以构建更细粒度的消费者扩展主题。

在 0.8 中,kafka 维护了消费者偏移量,因此在各个消费者之间循环发布消息对于他们的设计来说并不是一个太牵强的要求。

【问题讨论】:

    标签: apache-kafka


    【解决方案1】:

    在设计上,分区是 Kafka 中的并行单元。不仅是为了消费,kafka 还跨集群分布分区,这具有不同的其他好处,例如在不同服务器之间共享负载、复制管理以确保不丢失数据、管理日志以超出适合单个服务器的大小等。

    消息的顺序是一个关键因素,就好像您不需要强排序一样,使用多个分区潜水主题将允许您在生产时平均分配负载(这将由生产者自己处理)。在使用消费者组时,您只需在同一组中添加更多消费者实例,以便并行使用它们。

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

    是的,来自文档

    但是,如果您需要对消息进行总排序,这可以通过只有一个分区的主题来实现,尽管这意味着只有一个消费者进程。

    在以分布式方式消费的同时维护排序要求消息传递系统保持per-message 状态以跟踪消息确认。但这将涉及系统中大量昂贵的随机 I/O。很明显,这是一个权衡。

    理想情况下,如果主题不分区,则不需要对其进行分区。这给生产者带来了不必要的逻辑,并导致其他消费者类型从这些分区中消费,这可能只对一种消费者类型有意义

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

    这似乎是一个奇怪的设计选择,因为消费者可扩展性现在正在渗透到主题甚至生产者设计中

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

    【讨论】:

    • 消息系统将生产者和消费者分离。因此,在我看来,将主题的扩展与消费者的扩展相结合的消息传递系统违反了上述范式。主题的缩放应该独立于消费者的缩放。如我的示例中所述,我不需要对主题进行分区,但我希望并行处理跟上消息速率。对于失败场景,我仍然可以在单个主题上设置因子 X 的复制。
    【解决方案2】:

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

    消息排序在分区内得到保证,但在分区之间不保证,因此如果这是一个要求,则需要在消费者端进行处理。

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 根据spark.apache.org/docs/latest/streaming-kafka-integration.html,spark kafka 集成指南,提出的两种策略,旧的一种是接收者拉入消息并在 hdfs 中创建一个预写日志..有点失败基于日志的消息传递的目的系统和另一个,较新的方法,直接消费,依赖于主题分区,这将焦点带回这个问题。
      猜你喜欢
      • 1970-01-01
      • 2021-09-18
      • 1970-01-01
      • 2022-10-05
      • 1970-01-01
      • 1970-01-01
      • 2020-03-09
      • 2021-05-20
      • 1970-01-01
      相关资源
      最近更新 更多