在Apache Flink中是否有相当于Kafka的KTable?

时间:2017-11-17 16:16:11

标签: apache-flink apache-kafka-streams

Apache Kafka has a concept of a KTable,其中

  

其中每个数据记录代表更新

基本上,我可以使用kafka主题,并且只保留每个键的最新消息。

Apache Flink中是否有类似的概念?我读过Flink's Table API,但似乎没有解决同样的问题。

一些帮助比较和对比这两个框架会有所帮助。我不是在寻找哪个好或坏。而是他们的不同之处。答案是正确的,这取决于我的要求。

1 个答案:

答案 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 MapStateProcessFunction,您可以随着时间的推移进行细粒度控制,例如,如果某个数量尚未更新,则删除密钥的状态时间(就我所知,KTables有一个配置)。