我有一个Lambda函数,它由dynamoDB(表" A")触发,并且对于每个检索执行计数和聚合到另一个dynamoDB表(表" B")。 我的用例需要一个原子计数器图,
让我们假设一个在dynamoDB表中的项目" A"看起来像:
Item 1: {'user': 'foo', 'letter': 'a'}
Item 2: {'user': 'foo', 'letter': 'b'}
Item 3: {'user': 'foo', 'letter': 'b'}
Item 4: {'user': 'foo', 'letter': 'c'}
Item 5: {'user': 'bar', 'letter': 'a'}
Item 6: {'user': 'bar', 'letter': 'd'}
(注意:我的真实用例有数千个用户',每个用户有数千个项目,而我的"字母"范围是~400)
因此,我希望表" B"看起来像:
Item 1: {'user': 'foo', letter_map {'a' : 1, 'b' : 2, 'c': 1}, total_letters : 4}
Item 2: {'user': 'bar', letter_map {'a': 1, 'd': 1}, total_letters : 2}
我有一个AWS Lambda函数,用于处理表格#34; A"中的dynamoDB流。并创建一个put_item到表" B"使用以下UpdateExpression
:
UpdateExpression: 'ADD letter_map.#letter :val, total_letters :val',
ExpressionAttributeNames: { '#letter' : RetreivedTableAItem['letter']}
ExpressionAttributeValues: {':val': 1}
问题是表A上的put_items可以同时发生,我希望原子计数器能帮助我解决并发问题,但我发现total_letters
计数器确实是原子的并且表现良好,而letter_map
计数器如果我对同一个用户进行并发写入,则会重置计数器映射,
注意:在创建用户时,我创建一个空的letter_map
,以处理提到的here限制。
我也尝试将所有可用字母的整个letter_map
初始化为0,但也没有。
这是正常行为还是错误?
如果是正常的,有关如何实现计数器地图任务的任何建议吗?
答案 0 :(得分:0)
如果您的哈希键是'用户',则put_item在表格' B'同一个用户不能同时发生(通过lambda)。每个lambda可以在一个dynamo数据库分片上工作,并且在每个分片上它按顺序处理项目(以保护排序)。所以,如果'用户'是你的哈希键,而不是保证用户' X'将永远在同一个碎片上。
我认为,如果您遇到此类问题(重置),请查看您的代码中的其他错误。
来自aws doc的:
每个分片严格序列化发送到您的AWS Lambda函数的Amazon Kinesis和DynamoDB Streams记录。这意味着如果将两个记录放在同一个分片中,Lambda保证在使用第二个记录调用Lambda函数之前,将使用第一个记录成功调用它。如果一个记录的调用超时,受到限制或遇到任何其他错误,Lambda将重试直到成功(或记录达到其24小时到期),然后再转到下一个记录。不保证跨不同分片的记录顺序,并且每个分片的处理并行发生。