我最初的直觉是尽可能使用BatchWrite,但随着我对DynamoDB和lambda的熟悉程度越来越高,我认为如果DynamoDB吞吐量是你的主要瓶颈(很可能是这里的情况),它不应该有什么不同。
如果我有一个应用程序,我不关心个人写操作的延迟,不应该lambda只是扩大,直到DynamoDB的最大吞吐量达到不管它是BatchWrite或单个PutItem/UpdateItem调用?
如果出于任何其他原因单次写入是有利的(例如错误处理),那么为什么我不使用它们呢?我希望在总体吞吐量上没有区别。这个逻辑有错误吗?我还没测试呢
单个请求只会浪费资源。但是lambda的缩放非常好,你甚至可能看不到它。
长话短说,执行dynamoDB查询需要一些隐藏的计算。您必须准备好请求,验证它,并通过网络发送它。与使用两倍的有效负载(但只有一个报头)进行单个查询相比,执行两次将浪费CPU时间和网络带宽。
在某些情况下,触发单个请求的成本会更高,但很可能开销成本对您来说不是问题。这很可能取决于您的实际使用情况。
PutItem
您的PutItem
请求首先到达请求路由器,然后它将识别负责您的项目的三个存储节点(基于分区键),并将新数据发送到所有三个存储节点。只要三个存储节点中的两个确认写入,它就会响应您已写入该项。
BatchPutItem
这是一个有根据的猜测,据我所知,它没有正式的文档,但在我看来,它是有道理的。
当你发送一个BatchPutItem
请求时,这个请求也到达请求路由器,并且包含多个不同的条目要写。对于每一个单独的项目,路由器将识别相关的存储节点,写入它们,并等待其中两个存储节点确认写入。这很可能是以某种方式并行化的,而不是完全顺序的。一旦所有项目都被处理完(成功或不成功),您就会得到一个响应,DynamoDB将告诉您哪些项目失败了。
比较与权衡
当你必须写多个项目时,使用单独的PutItem
调用可能会导致建立到DynamoDB的更多网络连接从你的客户那里,这在时间上是很昂贵的。但是:现有的TCP连接通常会保留一段时间并将被重用,因此这种影响可能是有限的。对于BatchWriteItem
,网络请求较少,这应该可以改善网络延迟。
正如@aherve在他们的回答中正确指出的那样,在向DynamoDB发送请求时,客户端也会有一些开销。您需要对数据进行编码,计算一些校验和并使用您的凭据对请求签名,这需要CPU时间,因此最小化请求的数量可能对您的客户端有益。
对于您编写的每个项目,无论您是使用BatchPutItem
还是多个PutItem
调用,DynamoDB都将消耗每个项目所需的写容量单位。在已消耗的写容量方面没有区别.
在检查身份验证时,DynamoDB可以在内部进行一些优化,但我不希望这将是很多,因为DynamoDB仍然需要验证每个单独的写,因为您可以使用IAM条件。
在错误处理方面,单个PutItem
调用非常简单:如果写失败,调用失败,您可以修复数据并重试。BatchPutItem
需要更复杂的错误处理,因为即使写部分失败,调用也会成功。您需要检查失败项的响应,并自行重试它们。这增加了复杂性,您需要维护。