我正在尝试使用状态存储来对kafka-streams拓扑接收的消息进行重复数据删除(例如,如果生产者在很长一段时间内复制消息,则会根据某些业务派生的重复数据删除密钥进行重复。)
我注意到如果我在转换步骤中向密钥库添加一个值,然后在后续步骤中抛出异常,则订阅将回滚到上一个检查点,但状态存储会保留其值,这似乎不正确
是否有正确的'在拓扑中使用状态存储的方式,以便在拓扑抛出异常时回滚状态?
n.b。即使使用Kafka的一次交付语义
,这种行为也会被复制E.g(简化)。
Toloplogy:
streamsBuilder
.addStateStore(storeBuilder)
.<String, MessageType>stream("input-topic")
.transform(() -> new Deduplicator(storeName))
.map(mapper::explode) //just throws an exception
.to(output-topic);
重复数据转换器:
public KeyValue<String, MessageType> transform(String key, MessageType value) {
String transactionId = getTransactionId();
boolean isDuplicate;
try (WindowStoreIterator<String> timeIterator = deduplicationStore.fetch(transactionId, calculateWindowStart(), calculateWindowEnd())){
isDuplicate = timeIterator.hasNext();
}
if (isDuplicate(transactionId)) {
return null;
}
deduplicationStore.put(transactionId, transactionId, Instant.now().toEpochMilli());
return KeyValue.pair(key, value);
}