在 Flink 中生成具有当前时间戳的事件的最佳方法是什么?

What is the best way to produce events with current time timestamps in Flink?

我想了解在向 Kafka 生成新记录时使用 Flink 实现当前时间戳的最佳方法是什么

flink 会自动使用包含当前时间戳的元数据填充生成的事件吗?这是消费者的最佳实践,还是我们应该将当前时间放入事件中?

如果我真的想把一个已处理事件的当前时间放在Java中,我应该怎么做?我是 kubernetes 中的 运行 flink,所以我不知道简单的 current_time() 调用是否是理想的方式,因为任务管理器可能位于不同的节点中,而我不是确定他们每个人的时钟是否同步。

Does flink automatically fill the produced event with metadata containing the timestamp of the current time? Is that the best practice for the consumers or should we put the current time inside the event?

是的,时间戳设置为为该记录返回的任何值 TimestampAssigner。得益于此,Flink 转换可以保留原始记录时间戳。

I am running flink in kubernetes, so I don't know if a simple current_time() call would be the ideal way of doing it, because task managers may be in different nodes, and I am not sure if the clock in each of them are going to be in sync.

我可以向你保证它们不会同步。这就是为什么,为了简化分布式系统中的事情,我们并不真正依赖 wall-clock,而是依赖事件时间。

初始化 KafkaSink 时,您必须提供 KafkaRecordSerializationSchema, in the serialize method you can set the timestamp associated to each element when building the org.apache.kafka.clients.producer.ProducerRecord. The timestamp the serialize method receives will depend on your pipeline configuration. You can get more information about assigning timestamps and how Flink handles time in here: https://nightlies.apache.org/flink/flink-docs-release-1.15/docs/dev/datastream/event-time/generating_watermarks/

如果你不设置它,Kafka会在接收到每条记录时自动分配一个时间戳(摄取时间,基本上就是处理时间加上轻微的延迟)。

无论如何,在分布式应用程序中实现完美有序的处理时间时间戳将面临您描述的问题。不同的节点将有不同的时钟,即使所有节点都使用 NTP 同步。这是分布式系统中的一个大问题,需要付出大量努力才能解决(如果可能的话)。

一种可能足够好的实用方法是让属于同一键的所有记录都由同一节点标记时间戳,这样您将在大多数时间拥有完美有序的时间戳。请注意,时钟的重新平衡或更正(NTP 会定期执行)会时不时地破坏某些记录的每个密钥的这些完美排序的时间戳。如果你有一个 KeyedStream 并且你在键控 map 中分配时间戳或让 Kafka 这样做,你将获得每个键的这些 mostly-ordered 时间戳。