我在Java应用程序(Spring Cloud Stream)中使用Kafka Streams API。我有一个特定的用例,如下:
由于将运行该应用程序的多个实例,并且不能保证将任一主题的特定分区分配给这些实例,因此状态存储必须在应用程序之间进行共享共享。否则,如果主题B发生重新平衡,则应用程序实例可能会丢失它们正在跟踪主题A消息的状态信息。请考虑以下情形:
如果仅针对主题A发生重新平衡,也会发生相同的情况。
有可能实现为“全球状态存储”吗?我知道有一个GlobalKTable的概念,但是我需要使用KStream抽象,因为我需要访问完整的事件流。作为参考,我的KStream使用者如下:
@StreamListener(INPUT_TOPIC)
public void consumeKStream(KStream<String, Pojo> kStream) {
kStream.groupByKey(Serialized.with(keySerde, valueSerde)).aggregate(HashMap::new, (key, value, map) -> {
map.put(value.getFoo(), value.getBar()); return map;
}, Materialized.<String, Map<Foo, Bar>, KeyValueStore<Bytes, byte[]>>as(STATE_STORE_NAME)
.withKeySerde(keySerde).withValueSerde(valueMapSerde));
}
答案 0 :(得分:0)
如果您从主题A和主题B中读取数据,并且您具有实现来自主题B的数据并在主题A记录的存储中进行查找的拓扑,则可以保证实例将获得共分区分配。因此,您描述的情况将永远不会发生。
您可以通过检查包含子拓扑的Topology
(通过describe()
)来验证这一点。子拓扑是在任务执行时执行的,并且任务具有保证的共分区输入主题分配。
比较:https://docs.confluent.io/current/streams/architecture.html#parallelism-model