我在卡夫卡有时间序列数据。模式非常简单-关键是通道名称,值是时间戳的Long / Double元组和值(实际上,这是一个自定义Avro对象,但归结为这个)。它们总是按正确的时间顺序排列。
所需的最终结果是以10分钟为单位打包的数据,每10分钟对齐一次(即00:00 我的想法是有两个Spark Streaming作业。第一个从Kafka主题中获取数据,并将其转储到Cassandra数据库中的表中,其中的键是时间戳和频道名称,并且每次这样的RDD达到10分钟的边界时,该边界都会发布到另一个主题,其边界被击中的通道旁边。
第二项工作侦听此“边界主题”,对于每10分钟的边界,从Cassandra中提取数据,完成诸如min,max,mean,stddev之类的一些计算,并将数据和这些结果打包到定义的输出中目录。这样,每个目录都包含来自一个通道和一个10分钟窗口的数据。 但是,这看起来有些笨拙,并且对我来说还需要做很多额外的工作。这是可行的解决方案,还是还有其他更有效的技巧,例如对Kafka数据进行自定义窗口化?
答案 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字段是每个消息的映射时间戳。然后,您可以应用一个窗口。您应该搜索哪种窗口更适合您的情况。
点::为数据流设置一个键将使窗口功能为每个键考虑一个逻辑窗口。
根据需要在窗口中聚合消息之后,您可以使用reduce函数或类似的操作来应用处理逻辑。