我刚刚开始讨论实时流数据处理框架的主题,但是我有一个问题,到目前为止我还没有找到任何确凿的答案:
通常的可疑对象(Apache的Spark,Kafka,Storm,Flink等)是否支持处理事件时间分辨率为纳秒(甚至皮秒)的数据?
大多数人和文档都谈论毫秒或微秒的分辨率,但是如果可以实现更高的分辨率或出现问题,我将无法找到确切的答案。我推断唯一具有此功能的框架是influxData的Kapacitor框架,因为他们的TSDB influxDB似乎以纳秒的分辨率存储时间戳。
在座的任何人都可以对此提供一些见解,甚至可以提供一些有根据的事实吗?提供此功能的替代解决方案/框架?
任何事情将不胜感激!
感谢和问候,
西蒙(Simon)
我的问题的背景:我正在一个环境中工作,该环境具有许多用于数据存储和处理的专有实现,并且目前正在考虑一些组织/优化。我们正在使用许多不同的诊断/测量系统,以不同的采样率进行等离子体物理实验,现在达到“每秒Giga样本以上”。我们系统中的一个普遍事实/假设是每个样本的确记录了事件时间(以纳秒为单位)。当尝试使用已建立的流(或批处理)处理框架时,我们必须保持此时间戳解析度。甚至走得更远,因为我们最近在某些系统上突破了1 Gsps阈值。因此,我的问题。
答案 0 :(得分:0)
如果不清楚,请注意事件时间与处理时间之间的差异:
事件时间-从源头生成事件的时间
处理时间-处理引擎中事件执行的时间
src:Flink docs
AFAIK Storm不支持事件时间,Spark的支持有限。这样一来,就可以考虑使用Kafka Streams和Flink。
Flink使用长类型作为时间戳。 docs中提到该值是自1970-01-01T00:00:00Z以来的毫秒数,但是AFAIK,当您使用事件时间特征时,唯一的进度度量是事件时间戳。因此,如果您可以将值放在较长的范围内,那么它应该是可行的。
编辑:
通常,水印(基于时间戳)用于测量窗口,触发器等中事件时间的进度。因此,如果您使用:
AssignerWithPeriodicWatermarks ,那么即使在使用事件时间特性的情况下,也会在处理时域中在config(自动水印间隔)中定义的间隔中发射新的水印。有关详细信息,请参见org.apache.flink.streaming.runtime.operators.TimestampsAndPeriodicWatermarksOperator#open()
方法,其中注册了处理时间计时器。因此,如果将自动水印设置为500ms,则每500ms的处理时间(从System.currentTimeMillis()
中获取)会发出一个新的水印,但是水印的时间戳基于事件的时间戳。
AssignerWithPunctuatedWatermarks ,则可以在文档中找到org.apache.flink.streaming.api.datastream.DataStream#assignTimestampsAndWatermarks(org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks<T>)
的最佳描述:
为数据流中的元素分配时间戳,并创建水印以根据元素本身发出事件时间进度的信号。
此方法仅基于流元素创建水印。对于通过
AssignerWithPunctuatedWatermarks#extractTimestamp(Object, long)
处理的每个元素,将调用AssignerWithPunctuatedWatermarks#checkAndGetNextWatermark(Object, long)
方法,并发出新的水印,如果返回的水印值是非负数并且大于前一个水印。当数据流嵌入水印元素或某些元素带有可用于确定当前事件时间水印的标记时,此方法很有用。 此操作使程序员可以完全控制水印的生成。用户应注意,过于激进的水印生成(即每秒生成数百个水印)会降低性能。
要了解水印的工作原理,强烈建议您阅读以下内容:Tyler Akidau on Streaming 102
答案 1 :(得分:0)
尽管Kafka Streams使用毫秒级分辨率,但运行时实际上是不可知的。最后只是多头。
话虽如此,“问题”是时间窗口的定义。如果您将时间窗口指定为1分钟,但是时间戳分辨率小于毫秒,则窗口将小于1分钟。解决方法是,您可以将窗口增大,例如,微秒级或纳秒级分辨率为1000分钟或1,000,000分钟。
另一个“问题”是,经纪人仅了解毫秒级的解决方案,而保留时间是基于此的。因此,您需要将保留时间设置得更高一些,以“欺骗”代理,并避免它过早地删除数据。