我想将FlinkKafkaConsumer010
生成的消息的时间戳提取为数据流中的值。
我知道AssignerWithPeriodicWatermarks
类,但这似乎只是通过DataStream
API提取时间聚合的时间戳。
我想在Table
中提供Kafka消息时间戳,以后可以使用SQL。
编辑:试过这个:
val consumer = new FlinkKafkaConsumer010("test", new SimpleStringSchema, properties)
consumer.setStartFromEarliest()
val env = StreamExecutionEnvironment.getExecutionEnvironment
val tenv = TableEnvironment.getTableEnvironment(env)
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
class KafkaAssigner[T] extends AssignerWithPeriodicWatermarks[T] {
var maxTs = 0L
override def extractTimestamp(element: T, previousElementTimestamp: Long): Long = {
maxTs = Math.max(maxTs, previousElementTimestamp)
previousElementTimestamp
}
override def getCurrentWatermark: Watermark = new Watermark(maxTs - 1L)
}
val stream = env
.addSource(consumer)
.assignTimestampsAndWatermarks(new KafkaAssigner[String])
.flatMap(_.split("\\W+"))
val tbl = tenv.fromDataStream(stream, 'w, 'ts.rowtime)
它编译,但抛出:
Exception in thread "main" org.apache.flink.table.api.TableException: Field reference expression requested.
at org.apache.flink.table.api.TableEnvironment$$anonfun$1.apply(TableEnvironment.scala:630)
at org.apache.flink.table.api.TableEnvironment$$anonfun$1.apply(TableEnvironment.scala:624)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186)
at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:241)
at scala.collection.mutable.ArrayOps$ofRef.flatMap(ArrayOps.scala:186)
at org.apache.flink.table.api.TableEnvironment.getFieldInfo(TableEnvironment.scala:624)
at org.apache.flink.table.api.StreamTableEnvironment.registerDataStreamInternal(StreamTableEnvironment.scala:398)
at org.apache.flink.table.api.scala.StreamTableEnvironment.fromDataStream(StreamTableEnvironment.scala:85)
在上面代码的最后一行。
EDIT2 :感谢@ fabian-hueske指出我的解决方法。 https://github.com/andrey-savov/flink-kafka
的完整代码答案 0 :(得分:0)
如果配置了时间特征EventTime,Flink的Kafka 0.10使用者会自动将Kafka消息的时间戳设置为生成记录的事件时间戳(参见docs)。
在您将Kafka主题摄取到DataStream
时,如果时间戳(仍然不可见)和分配的水印,您可以使用Table
方法将其转换为StreamTableEnvironment.fromDataStream(stream, fieldExpr*)
。 fieldExpr*
参数是描述生成的表的模式的表达式列表。您可以使用表达式mytime.rowtime
添加保存流的记录时间戳的字段,其中mytime
是新字段的名称,rowtime
表示从记录中提取值时间戳。请查看docs for details。
注意:正如@bfair指出的那样,原子类型DataStream
的转换(例如DataStream[String]
)失败,Flink 1.3.2和早期版本。该错误已报告为FLINK-7939,并将在下一版本中修复。