在DynamoDB中聚合符合我们访问模式的数据



我目前正在尝试聚合加速度计数据,因为它已加载到我们的发电机表中。我想在每个用户的基础上在5分钟的时间窗口内进行聚合,并将聚合结果插入另一个dynamo表中。因为我对Dynamo或Lambda不是很熟悉,所以如果我忽视了更好的解决方案,我希望有人能引导我朝着不同的方向前进。

我认为最好的方法是利用DynamoDB Streams,并有一个Lambda来处理数据,在数据输入时进行聚合,这样我们就不必每5分钟查询一次每个用户的DynamoDB表。后者当然使Lambda更简单,但我认为这将占用我们读取容量的很大一部分,也会导致Lambda执行时间更长。

因此,我的想法是在每1000条记录触发一次的lambda中处理流,并让它在一天中每5分钟的时间窗口(从午夜开始,时间为0)按每个用户在新表中重新启动一条记录。如果在该时间窗口内不存在用户的记录,则将插入该记录。如果记录确实存在,它将有条件地更新聚合。

该表将由作为分区键的用户id组成,格式为<\公司id>|<\user id>,将作为排序键的窗口开始时间(<\date>00:00、00:05、00:10等),我正在聚合的数据的总和,以及用于计算该总和的记录数和平均值。

有了这种结构,我相信可以在我在查询中指定的时间范围内,按用户提取特定公司的数据。

这似乎是用Dynamo解决数据聚合的正确方法吗?从lambda的角度或流的角度来看,我是否需要注意可能导致可伸缩性问题或基于我上面概述的结构的查询问题?

谢谢!

这里有几点需要注意。

我认为这将占用我们读取容量的很大一部分,也会导致Lambda执行时间更长Dynamodb流由旧数据和新数据组成,因此您不会去dyanamodb获取数据。因此没有额外的容量消耗。

对于上面的问题,你有这样的数据库模式

|PK       |  SK             | timesegment    |
|mike     | event#12334     | 12330#12330    | some metadata about this event.
|mike     | event#12336     | 12335#12340    | some metadata about this event.
|mike     | metadata        |                | some metadata about mike completely optional
|tim      | event#12339     | 12335#12340    | some metadata about this event.

其中PK是用户ID,SK是关于该行的信息。

现在有两个问题

  1. 在哪里存储聚合?

    您可以选择更适合您需求的发电机或云表。

  2. 如何计算聚合?

    为了运行聚合,您需要以下

    1. 所有用户在过去5分钟内更改了什么(因为显然我们不会进行表扫描。)

      有多种方法可以回答这个问题,

      a。在5分钟的历元时间上进行GSI。从这个GSI表中获取所有PK,以了解所有用户的变化。现在,您可以对所有用户进行迭代,以聚合他们的数据。

      Pros

      • 您将所有数据放在一个表中,如果出现问题,您实际上可以回放所有数据。这在使用流时是不可能的

      Cons

      • GSI会非常热,因为在5分钟的时间间隔内,所有的写入都将只进入一个分区

      b。在向dynamodb写入时,将用户信息存储在另一个表中,这样我们就不必使用GSI来获取用户列表。

      Pros

      • 不会有任何热分区

      Cons

      • 回放功能不易实现
  3. 如何运行聚合

    您可以让cloudwatch事件触发lambda函数来进行聚合,而不是让dynadb流,如果您看到lambda超时(聚合需要超过15分钟),您可以创建一个父lambda函数,该函数只计算更改的PK并将其放入SQS。然后有一个lambda函数订阅给SQS,SQS为每个userid 进行计算

最新更新