【问题标题】:Kafka Processor API: Different key for Source and StateStore?Kafka 处理器 API:Source 和 StateStore 的不同键?
【发布时间】:2018-04-18 16:37:16
【问题描述】:

我们目前正在实现一个流程(使用 Kafka 处理器 API),我们需要将来自主题的 2 个相关事件(消息)的信息组合起来,然后转发这些组合信息。事件源自物联网设备,由于我们希望保持它们的顺序,源主题使用设备标识符作为键。这些事件还包含一个相关 ID:

{ deviceId: "..." }

留言

{ deviceId: "...", correlationId: "...", data: ...}

我们的第一种方法是创建一个具有连接状态存储的处理器,该状态存储使用关联 ID 作为键来存储每条传入消息。这使我们能够在 store 中查询传入消息的相关 ID,如果 store 中已经存在具有相同 ID 的消息,我们可以组合信息,转发新事件并从 store 中删除条目。因此,对于每个关联 ID,都会发生以下情况:在某个时间点,具有该 ID 的第一条消息被使用和存储,而在另一个时间点,具有该 ID 的第二条消息导致存储条目被删除。

状态键

{ correlationId: "..." }

状态值

{ event: { deviceId: "...", correlationId: "...", data: ... }}

但现在我们想知道 Kafka Streams 是如何处理不同的密钥的。我们正在使用微服务方法,并且将运行该服务的多个实例。商店由内部主题自动支持。考虑重新缩放服务实例,s.t.源主题和状态主题的分区被重新平衡。是否有可能将特定关联 ID 的分区分配给另一个服务而不是相应设备 ID 的分区?我们是否会遇到这样一种情况,即具有相同关联 ID 的第二个事件将被服务实例使用,而该服务实例无权访问已存储的第一个事件?

提前致谢!

【问题讨论】:

    标签: apache-kafka apache-kafka-streams


    【解决方案1】:

    如果我正确理解您的设置,那么是的,该方法是正确的,并且(重新)缩放将起作用。

    TL;DR:如果一个流任务从机器 A 移动到机器 B,那么它的所有状态也将被移动,无论该状态是如何键控的(在你的情况下,它恰好是由 correlationId 键控的)。

    更详细的:

    • Kafka Streams 将处理工作分配给stream tasks。这是通过基于输入分区中的消息键(在您的情况下:由deviceId 键控)以确定的方式将输入分区映射到流任务来实现的。这样可以确保,即使流任务在机器/VM/容器之间移动,它们也将始终看到“它们的”输入分区 = 它们的输入数据。
    • 流任务基本上由实际处理逻辑(在您的情况下:处理器 API 代码)和任何相关的 状态(在您的情况下:您有一个由correlationId 键入的状态存储)。对于您的问题,重要的是状态如何键入并不重要。唯一重要的是输入分区的键控方式,因为这决定了哪些数据从输入主题流向特定的流任务(参见前面的要点)。当流式任务在机器/VM/容器之间移动时,它的所有状态也将被移动,以便它始终拥有“自己的”可用状态。

    商店由内部主题自动支持。

    正如您已经建议的那样,存储具有内部主题的事实(用于容错和弹性扩展,因为当流任务从 A 移动到 B 时,该内部主题用于重建状态存储)是一个实现细节。作为使用 Kafka Streams API 的开发人员,状态存储恢复的处理会自动且透明地为您完成。

    当一个流任务被移动,因此它的状态存储被移动时,Kafka Streams 知道它需要如何在流任务的新位置重建状态存储。你不必担心这个。

    是否可以将特定关联 ID 的分区分配给另一个服务而不是相应设备 ID 的分区?

    不(这很好)。流任务将始终知道如何重建其状态(1+ 状态存储),而不管该状态本身是如何键控的。

    我们是否会遇到这样一种情况,即具有相同关联 ID 的第二个事件将被服务实例使用,而该服务实例无权访问已存储的第一个事件?

    不(这很好)。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 2023-01-21
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    相关资源
    最近更新 更多