基于时间跨度的AWS Kinesis流聚合

时间:2017-09-30 17:24:00

标签: algorithm amazon-web-services aggregate-functions amazon-kinesis

我目前有一个Kinesis流,其中填充了以下形式的JSON消息:

{"datetime": "2017-09-29T20:12:01.755z", "payload":"4"}
{"datetime": "2017-09-29T20:12:07.755z", "payload":"5"}
{"datetime": "2017-09-29T20:12:09.755z", "payload":"12"}
etc...

我想在这里尝试完成的是按时间块聚合数据。在这种情况下,我想将平均值分组为10分钟的跨度。例如,从12:00开始; 12:10,我想平均有效载荷值并将其保存为12:10值。

例如,上述数据会产生:

Datetime: 2017-09-29T20:12:10.00z
Average: 7

我想到的方法是在服务级别使用缓存,然后使用某种方式跟踪时间。如果消息进入下一个10分钟的时间跨度,我会对缓存的数据进行平均,将其存储到数据库中,然后删除该缓存值。

目前,我的服务每分钟会看到20,000封邮件,预计未来会有更高的邮件量。我有点坚持如何实现这一点,以保证我从Kinesis获得该10分钟时间段的所有值。那些对Kinesis和AWS更熟悉的人,有一个简单的方法可以解决这个问题吗?

这样做的原因是缩短来自大时间跨度的数据的查询时间,例如1年。我不想抓住数百万的价值,而是想要几个聚合值。

编辑:

我必须同时跟踪许多不同的平均值。例如,上述JSON可能仅适用于一个“集合”,例如10分钟时间内每个城市的平均温度。这需要我跟踪每个时间跨度的每个城市平均值。

Toronto (12:01 - 12:10): average_temp
New York (12:01 - 12:10): average_temp
Toronto (12:11 - 12:20): average_temp
New York (12:11 - 12:20): average_temp
etc...

这可能适用于全球任何城市。如果新的温度到达,多伦多它与12:01 - 12:10时间有关,我必须重新计算并存储该平均值。

1 个答案:

答案 0 :(得分:2)

我就是这样做的。感谢有趣的问题。

Kinesis Streams - > Lambda(事件插入器) - > DynamoDB(Streams) - > Lambda(计数和值增量) - > DynamoDB(流) - >平均值(更新程序)

DynamoDB表结构:

{ 
Timestamp: 1506794597
Count: 3
TotalValue: 21
Average: 7
Event{timestamp}-{guid}: { event }
}

timestamp -- timestamp of the actual event
guid -- avoid any collision on a timestamp that occurred at same time
Event{timestamp}-{guid} -- This should be removed by (count and value incrementor)

如果该时间戳的第四条记录到了,

获得接近10分钟时间的时间,增加计数,增加总值。 Neve读取值和增量,除非你使用强一致性(非常昂贵读取),否则将导致错误。而是使用原子增量执行增量操作。

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.AtomicCounters

从上表创建DynamoDB流,侦听另一个lambda,现在计算平均值并更新值。

计算平均值时,请勿从表中执行读取操作。相反,数据将通过流提供,您只需计算平均值并更新它。 (覆盖以前的平均值)。

这将适用于任何规模和高可用性。

希望它有所帮助。

<强> EDIT1:

由于OP不熟悉AWS服务,

Lambda文档:

https://aws.amazon.com/lambda/

DynamoDB文档:

https://aws.amazon.com/dynamodb/

用于解决方案的AWS云服务。