需要有关在每个通道上以10分钟为单位批量存储时间序列数据的建议

时间:2018-07-16 06:57:11

标签: apache-kafka spark-streaming

我在卡夫卡有时间序列数据。模式非常简单-关键是通道名称,值是时间戳的Long / Double元组和值(实际上,这是一个自定义Avro对象,但归结为这个)。它们总是按正确的时间顺序排列。

所需的最终结果是以10分钟为单位打包的数据,每10分钟对齐一次(即00:00

我的想法是有两个Spark Streaming作业。第一个从Kafka主题中获取数据,并将其转储到Cassandra数据库中的表中,其中的键是时间戳和频道名称,并且每次这样的RDD达到10分钟的边界时,该边界都会发布到另一个主题,其边界被击中的通道旁边。 第二项工作侦听此“边界主题”,对于每10分钟的边界,从Cassandra中提取数据,完成诸如min,max,mean,stddev之类的一些计算,并将数据和这些结果打包到定义的输出中目录。这样,每个目录都包含来自一个通道和一个10分钟窗口的数据。

但是,这看起来有些笨拙,并且对我来说还需要做很多额外的工作。这是可行的解决方案,还是还有其他更有效的技巧,例如对Kafka数据进行自定义窗口化?

2 个答案:

答案 0 :(得分:0)

我同意您的直觉,认为此解决方案比较笨拙。简单地使用Streams DSL中内置的时间窗口功能怎么样?

http://kafka.apache.org/11/documentation/streams/developer-guide/dsl-api.html#windowing

最自然的输出是包含窗口聚合的新主题,但是如果您确实需要将其写入Kafka Connect应该可以的目录中。

答案 1 :(得分:0)

我使用Flink流处理,而不是Spark流,但是我想两者的编程概念是相同的。因此,假设数据按时间顺序排序,并且您希望每10分钟汇总一次数据,并对汇总后的数据进行一些处理,那么我认为最好的方法是使用 Streaming Window Functions 。我建议定义一个函数,以将每个传入数据的时间戳映射到最近10分钟:

12:10:24 ----> 12:10:00
12:10:30 ----> 12:10:00
12:25:24 ----> 12:20:00

因此您可以创建一个键控流对象,例如:

StreamObject<Long, Tuple<data>>

Long字段是每个消息的映射时间戳。然后,您可以应用一个窗口。您应该搜索哪种窗口更适合您的情况。

点::为数据流设置一个键将使窗口功能为每个键考虑一个逻辑窗口。

  • 在最简单的情况下,您应定义一个 10 分钟的时间窗口,并汇总该时间段内传入的所有数据。
  • 如果您知道数据的生成速率以及在10分钟的时间内将生成多少消息,则另一种方法是使用“计数窗口” 。例如,一个计数为20的窗口将侦听流,并在逻辑窗口中聚合具有相同键的所有消息,并仅在窗口中的消息数达到20时应用该窗口功能。

根据需要在窗口中聚合消息之后,您可以使用reduce函数或类似的操作来应用处理逻辑。