Apache Kafka has a concept of a KTable,其中
其中每个数据记录代表更新
基本上,我可以使用kafka主题,并且只保留每个键的最新消息。
Apache Flink中是否有类似的概念?我读过Flink's Table API,但似乎没有解决同样的问题。
一些帮助比较和对比这两个框架会有所帮助。我不是在寻找哪个好或坏。而是他们的不同之处。答案是正确的,这取决于我的要求。
答案 0 :(得分:4)
你是对的。 Flink的Table API及其Table
类与Kafka的KTable不对应。 Table API是一种关系语言嵌入式API(考虑使用Java和Scala集成的SQL)。
Flink的DataStream API没有与KTable相对应的内置概念。相反,Flink提供复杂的状态管理,KTable将是keyed state的常规运营商。
例如,有两个输入的有状态运算符存储从第一个输入中观察到的最新值,并将其与第二个输入的值连接,可以使用CoFlatMapFunction
实现,如下所示:
DataStream<Tuple2<Long, String>> first = ...
DataStream<Tuple2<Long, String>> second = ...
DataStream<Tuple2<String, String>> result = first
// connect first and second stream
.connect(second)
// key both streams on the first (Long) attribute
.keyBy(0, 0)
// join them
.flatMap(new TableLookup());
// ------
public static class TableLookup
extends RichCoFlatMapFunction<Tuple2<Long,String>, Tuple2<Long,String>, Tuple2<String,String>> {
// keyed state
private ValueState<String> lastVal;
@Override
public void open(Configuration conf) {
ValueStateDescriptor<String> valueDesc =
new ValueStateDescriptor<String>("table", Types.STRING);
lastVal = getRuntimeContext().getState(valueDesc);
}
@Override
public void flatMap1(Tuple2<Long, String> value, Collector<Tuple2<String, String>> out) throws Exception {
// update the value for the current Long key with the String value.
lastVal.update(value.f1);
}
@Override
public void flatMap2(Tuple2<Long, String> value, Collector<Tuple2<String, String>> out) throws Exception {
// look up latest String for current Long key.
String lookup = lastVal.value();
// emit current String and looked-up String
out.collect(Tuple2.of(value.f1, lookup));
}
}
通常,状态可以非常灵活地与Flink一起使用,让您实现各种用例。还有更多的状态类型,例如ListState
and MapState
和ProcessFunction
,您可以随着时间的推移进行细粒度控制,例如,如果某个数量尚未更新,则删除密钥的状态时间(就我所知,KTables有一个配置)。