仅将列入白名单的项目写入 DynamoDB
Writing only whitelisted items to DynamoDB
我有一组 (~1.000.000) 可以发送消息的设备,每个设备都有一个 ID 并且可以发送多条消息。设备的一个子集 (~10.000) 应该能够使用我的服务,并且 ID 被放入白名单 (DynamoDB table)。
给定一个持续不断的消息流,我只希望白名单中的一次被保存在 DynamoDB table.
我一直在看的东西如下:
- 天真的方法是在 lambda 将数据写入 DynamoDB 时在代码中进行过滤,不确定这会扩展到什么程度,因为我首先需要查询白名单 table 以检查我可以接收哪些消息写。
- 我想做的是使用 DynamoDB 条件写入(或者如果有其他一些智能功能)来指定 “仅当它存在于 table白名单 并让 DynamoDB 引擎负责过滤。
我的问题是在 DynamoDB 中是否有一些聪明的方法可以做到这一点?
一般情况下,条件更新无法满足您的需求。条件更新只能引用正在修改的同一项目的内容——不能引用其他项目或其他表。这不是缺少的功能——这确实是“免费”无法完成的事情:当 DynamoDB 写入一个项目时,它可以“免费”检查该项目的先前值,作为同一操作的一部分。但是没有“免费”的方式来阅读 不同的 项目。它基本上相当于另一个读取操作。因此,如果您想读取其他项目,您可以通过读取操作自己完成 - DynamoDB 无法真正比额外读取请求更有效地执行此读取操作。
在某些情况下,如果您只为每个 ID 保留一个项目,那么有一个简单的解决方案可以解决您的问题 - 只需向该项目添加另一个属性,说明它是否已列入白名单,然后在有条件的更新中使用这个新属性。但是如果每个 id 有很多项目,则不能这样做(例如,id 是一个分区键,而你有一个额外的排序键)。 CQL(Cassandra 和 Scylla)具有“静态行”(属于整个分区的项目,而不属于分区内的排序键)的概念,但 DynamoDB 没有此功能。即使这样做了,对静态行的额外读取可能比另一次读取更便宜,但它不是免费的。
这既是 DynamoDB 的祝福也是诅咒 - 起初,它是一种痛苦,但不久之后 DDB 的简单性开始闪耀 - 你可以在短时间内学习它的全部 API。
每个问题都是不同的,你在问题中问了一些问题,所以我只提供一些希望能有所帮助的要点:
- 你不能在 DDB 中 query/reference 另一个 table,所以没有“聪明”的方法来做到这一点。
- DDB 非常快,所以我不会担心数据库端的扩展问题。
- 写前查询是一个完美的acceptable模型,只要确保你有一个有效的索引并且你正在使用
GetItem
或Query
- 换句话说,做不使用 Scan
.
- 如果您真的想尽量减少调用,那么您可以考虑创建一个简单的 in-memory 白名单 ID 缓存。这可能会导致扩展复杂性,具体取决于您的基础架构,但这很容易解决。如果这是您正在考虑的事情,那么我建议您将 DDB Streams 视为一种确保缓存是最新的方法。但说实话,除非你真的有吞吐量问题,否则这个选项就太过分了。
我有一组 (~1.000.000) 可以发送消息的设备,每个设备都有一个 ID 并且可以发送多条消息。设备的一个子集 (~10.000) 应该能够使用我的服务,并且 ID 被放入白名单 (DynamoDB table)。 给定一个持续不断的消息流,我只希望白名单中的一次被保存在 DynamoDB table.
我一直在看的东西如下:
- 天真的方法是在 lambda 将数据写入 DynamoDB 时在代码中进行过滤,不确定这会扩展到什么程度,因为我首先需要查询白名单 table 以检查我可以接收哪些消息写。
- 我想做的是使用 DynamoDB 条件写入(或者如果有其他一些智能功能)来指定 “仅当它存在于 table白名单 并让 DynamoDB 引擎负责过滤。
我的问题是在 DynamoDB 中是否有一些聪明的方法可以做到这一点?
一般情况下,条件更新无法满足您的需求。条件更新只能引用正在修改的同一项目的内容——不能引用其他项目或其他表。这不是缺少的功能——这确实是“免费”无法完成的事情:当 DynamoDB 写入一个项目时,它可以“免费”检查该项目的先前值,作为同一操作的一部分。但是没有“免费”的方式来阅读 不同的 项目。它基本上相当于另一个读取操作。因此,如果您想读取其他项目,您可以通过读取操作自己完成 - DynamoDB 无法真正比额外读取请求更有效地执行此读取操作。
在某些情况下,如果您只为每个 ID 保留一个项目,那么有一个简单的解决方案可以解决您的问题 - 只需向该项目添加另一个属性,说明它是否已列入白名单,然后在有条件的更新中使用这个新属性。但是如果每个 id 有很多项目,则不能这样做(例如,id 是一个分区键,而你有一个额外的排序键)。 CQL(Cassandra 和 Scylla)具有“静态行”(属于整个分区的项目,而不属于分区内的排序键)的概念,但 DynamoDB 没有此功能。即使这样做了,对静态行的额外读取可能比另一次读取更便宜,但它不是免费的。
这既是 DynamoDB 的祝福也是诅咒 - 起初,它是一种痛苦,但不久之后 DDB 的简单性开始闪耀 - 你可以在短时间内学习它的全部 API。
每个问题都是不同的,你在问题中问了一些问题,所以我只提供一些希望能有所帮助的要点:
- 你不能在 DDB 中 query/reference 另一个 table,所以没有“聪明”的方法来做到这一点。
- DDB 非常快,所以我不会担心数据库端的扩展问题。
- 写前查询是一个完美的acceptable模型,只要确保你有一个有效的索引并且你正在使用
GetItem
或Query
- 换句话说,做不使用Scan
. - 如果您真的想尽量减少调用,那么您可以考虑创建一个简单的 in-memory 白名单 ID 缓存。这可能会导致扩展复杂性,具体取决于您的基础架构,但这很容易解决。如果这是您正在考虑的事情,那么我建议您将 DDB Streams 视为一种确保缓存是最新的方法。但说实话,除非你真的有吞吐量问题,否则这个选项就太过分了。