【问题标题】:Java Kafka Consumer store state in memory?Java Kafka Consumer在内存中存储状态?
【发布时间】:2021-11-21 21:59:12
【问题描述】:

我有一个用例,我需要为客户“批处理”事件数据。

每条事件数据都会有一个 customerId。

在我的应用层 (java) 中,我需要根据客户 ID 批量处理所有事件,然后应用我的业务逻辑。我的业务逻辑需要每个客户的所有事件都可用。基本上,我先按 customerId 进行分组,然后才能对其进行任何操作。

方法: 将所有事件提取到 Kafka 主题分区键为“customerId”。因此,属于特定客户的事件总是发送给同一个消费者。在消费者中,我可以收集内存中的事件(也许使用一个简单的到期图左右)并执行批处理。在这种方法中,我的整个批次都是瞬态的并存储在应用程序内存中。

注意事项: 当发生 Kafka 分区重新平衡(无论出于何种原因)以及将不同的分区重新分配给不同的消费者时,数据就会变得不一致。不知道有什么办法可以克服。

我想知道这种“批处理”用例的实用方法是什么? Kafka-Streams 是合适的人选吗?但这不是无限的流。批处理数据集显然有一个开始和结束。结束事件被用作执行业务逻辑的触发器。

【问题讨论】:

  • 如果数据明明有尽头,为什么要从Kafka主题消费呢?如果要构建物化视图,可以,可以使用 Global KTable,但使用 Kafka Connect 将主题下沉到数据库也可以
  • DB 方法不适合我们的用例的原因是该组件本质上是一个由消息驱动的微服务,并且不了解数据源(也没有数据库的额外开销和成本) (当然除了卡夫卡)。这是一种数据输入数据输出实用程序。
  • 当然,但是 Kafka 不是永久持久的,所以您是否关闭了保留或一直使用压缩?除了/代替消息队列之外,没有什么可以阻止微服务使用数据库
  • 完全同意。但是对于这个服务(仅),拥有一个数据库是我试图避免的,纯粹因为这是一种实用服务——它所做的只是纯粹的数据转换,不需要保持任何状态,因此不需要一个数据库。
  • “分组”任何东西是一个有状态的过程。您正在维护历史数据,然后根据某些属性对其进行聚合。你不需要外部数据库,你可以像 Kafka Streams 那样使用 sqlite、h2 或rocksdb

标签: java apache-kafka kafka-consumer-api apache-kafka-streams


【解决方案1】:

事件将按 customerId 排序,但如果消费者实例中没有 StickyAssignor,它们将不会 "go to" 被同一个消费者消费,尤其是在分布式环境中的替换事件

如果您在一个紧凑主题中有一些数据充当您的原始事件,并且将它们全部消耗到某个缓存中将构建您的物化视图,那么这就是 Kafka Streams 对变更日志主题所做的事情,是的。您还可以使用普通消费者自行构建此逻辑,例如 Confluent Schema Registry 使用其_schemas 主题和多个内部哈希图

【讨论】:

    猜你喜欢
    • 2019-07-14
    • 1970-01-01
    • 2023-03-23
    • 2017-06-08
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    相关资源
    最近更新 更多