我正在使用流DSL来重复删除一个名为users
的主题:
topology.addStateStore(Stores.keyValueStoreBuilder(Stores.persistentKeyValueStore("users"), byteStringSerde, userSerde));
KStream<ByteString, User> users = topology.stream("users", Consumed.with(byteStringSerde, userSerde));
users.transform(() -> new Transformer<ByteString, User, KeyValue<ByteString, User>>() {
private KeyValueStore<ByteString, User> store;
@Override
@SuppressWarnings("unchecked")
public void init(ProcessorContext context) {
store = (KeyValueStore<ByteString, User>) context.getStateStore("users");
}
@Override
public KeyValue<ByteString, User> transform(ByteString key, User value) {
User user = store.get(key);
if (user != null) {
store.put(key, value);
return new KeyValue<>(key, value);
}
return null;
}
@Override
public KeyValue<ByteString, User> punctuate(long timestamp) {
return null;
}
@Override
public void close() {
}
}, "users");
鉴于此代码,Kafka Streams为users
商店创建了一个内部更改日志主题。我想知道,是否有某些方法可以使用现有的users
主题,而不是创建一个基本相同的更改日志主题?
PS。我看到StreamsBuilder
说这是可能的:
但是,由于原始输入主题可用于恢复,因此未创建内部更改日志主题
但是按照InternalStreamsBuilder#table()
和InternalStreamsBuilder#createKTable()
的代码,我没有看到它是如何实现这种效果的。
答案 0 :(得分:1)
并非所有DSL在处理器API级别都可以做到 - 它使用了一些内部构件,这些内部构件不是公共API的一部分,可以实现您所描述的内容。
调用InternalTopologyBuilder#connectSourceStoreAndTopic()
可以解决问题(参见InternalStreamsBuilder#table()
)。
对于关于重复数据删除的用例,您似乎需要两个主题(取决于您应用的重复数据删除逻辑)。通过changelog主题进行恢复可以进行基于密钥的更新,因此不会考虑值(也可能是重复数据删除逻辑的一部分)。