Kafka流-定义具有容错功能的自定义关系/非键值状态存储

时间:2018-10-28 18:07:27

标签: apache-kafka apache-kafka-streams spring-cloud-stream

我正在尝试使用kafka实现事件源。

我对流处理器应用程序的愿景是典型的3层Spring应用程序,其中:

  • “表示”层已替换为Kafka流API(由其实现)。
  • 拓扑中的处理器API使用业务逻辑层。
  • 此外,该数据库是关系型H2内存数据库,可通过Spring Data JPA存储库进行访问。存储库还实现了必要的接口,以便将其注册为Kafka状态存储库,以使用收益(恢复和容错)

但是我想知道应该如何实现自定义状态存储部分?

我一直在搜索And:

  • 有一些接口,例如StateStoreStoreBuilderStoreBuilder有一个withLoggingEnabled()方法;但是,如果启用它,什么时候才发生实际的更新和更改日志记录?通常,这些示例都是所有键值存储区,即使是自定义的。如果我不想要键值怎么办? kafka文档中“交互式查询”部分中的示例并未删除。

  • 我知道交互式查询。但是它们似乎很适合查询而不是更新。顾名思义。

在键值存储中,发送到更改日志的记录非常简单。但是,如果我不使用键值;何时以及如何通知卡夫卡我的状态已经改变?

1 个答案:

答案 0 :(得分:3)

您将需要为要使用的实际存储引擎实现StateStore。该界面不决定商店的任何内容,您可以做任何您想做的事情。

您还需要实现一个StoreBuilder作为工厂来创建自定义商店的实例。

MyCustomStore implements StateStore {
    // define any interface you want to present to the user of the store
}

MyCustomStoreBuilder implements StoreBuilder<MyCustomStore> {
    MyCustomStore builder() {
        // create new instance of MyCustomStore and return it
    }

    // all other methods (except `name()`) are optional
    // eg, you can do a dummy implementation that only returns `this`
}

比较:https://docs.confluent.io/current/streams/developer-guide/processor-api.html#implementing-custom-state-stores

  

但是,如果我不使用键值;何时以及如何通知卡夫卡我的状态已经改变?

如果要实现withLoggingEnabled()(与缓存类似),则需要在存储中实现此日志记录(或缓存)。因为,Kafka Streams不知道您商店的工作方式,所以它无法为此提供实现。因此,无论您的商店是否支持登录到changelog主题,这都是您的设计决定。而且,如果要支持日志记录,则需要设计一个将商店更新映射到键-值对(您还可以为每个更新编写多个)的设计,该设计可以写入更改日志主题,并允许您重新创建状态当从changelog主题读取这些记录时。

不仅可以通过更改日志记录来获取容错存储。例如,您还可以插入一个远程存储,该存储在内部进行复制等操作,因此依赖于存储的容错功能,而不是使用更改日志记录。当然,与使用本地存储区相比,使用远程存储区意味着其他挑战。

对于Kafka Streams默认存储,日志记录和缓存被实现为实际存储的包装器,使其易于插入。但是您可以以最适合您的商店的任何方式实施此操作。您可能想查看以下类以比较键值存储:

对于交互式查询,您实现一个相应的QueryableStoreType来集成您的定制商店。 cf. https://docs.confluent.io/current/streams/developer-guide/interactive-queries.html#querying-local-custom-state-stores是正确的,因为“ Processors应该负责维护商店,所以交互式查询是现有商店的只读接口。但是,也没有什么可以阻止您打开自定义存储进行写入的。但是,这将使您的应用程序天生就具有不确定性,因为如果您倒退输入主题并对其进行重新处理,则它可能会计算不同的结果,具体取决于执行的“外部存储写入”。您应该考虑通过输入主题对存储进行任何写操作。但这是您的决定。如果允许“外部写入”,则还需要确保也记录了它们,以防您想要实现记录。