我看到 Amazon DynamoDB 请求的响应时间有所增加,但我不知道为什么会增加。
简短描述
端到端延迟涉及 DynamoDB 服务端延迟和用户客户端延迟之间的共同责任。
SuccessfulRequestLatency Amazon CloudWatch 指标仅测量 DynamoDB 完全处理 API 请求所需的时间。DynamoDB 不测量应用程序连接到 DynamoDB 端点或从端点下载结果所花费的时间。
解决方法
分析延迟时,最佳做法是检查 average latency(平均延迟)而不是 max latency(最大延迟)值。延迟偶尔会出现峰值是正常的。如果平均延迟很高,则可能存在潜在的问题。
对于大多数原子操作(例如 GetItem 和 PutItem),平均延迟以个位数毫秒为单位。Query、Scan、BatchGetItem 和 BatchWriteItem 等非原子操作的延迟取决于许多因素。这些因素包括结果集的大小、插入的记录数量以及查询条件和筛选器的复杂性。
高延迟的常见原因
不频繁访问
为避免延迟,DynamoDB 中的所有前端主机都维护本地缓存。当请求速率较低时,前端实例集可能一度无法接收请求,从而导致缓存生存时间 (TTL) 到期。如果请求在缓存到期后到达主机,则主机必须从内部 DynamoDB 组件获取数据。主机填充缓存,然后主机可以响应。获取和填充数据所花费的时间可能会导致延迟增加。
如果分区拆分或领导权发生变化,则缓存可能会过时,并可能导致前几次调用的延迟延长。DynamoDB 引用多个缓存来检索分区信息、签名验证以及有关每个请求的其他信息。当请求速率较低时,缓存不会保持在热状态,并且前几个请求的延迟通常会更高。
如果请求塑料较高且传入流量一致,则每个请求都会持续到达前端实例集,不会造成任何延迟峰值。为避免因不频繁访问而出现问题,请让客户端向 DynamoDB 表发送虚拟流量。
强一致性读取
GetItem、Query 和 Scan 等读取操作提供了可选的 ConsistentRead 参数。如果您将 ConsistentRead 设置为 true,则 DynamoDB 将返回包含最新数据的响应。该数据反映了之前所有成功写入操作的更新,但可能导致更高的延迟。
DynamoDB 架构在一个分区中有一个领导者节点和两个副本节点。DynamoDB 使用领导者节点为强一致性读取请求提供服务,但不为只读副本提供服务。由于 DynamoDB 必须找到领导者节点,然后将请求重定向到服务,因此您可能会遇到一些延迟。
如果您的应用程序不需要强一致性读取,请使用最终一致性读取。
减少延迟的方法
减少请求超时设置
调整 requestTimeOut 和 clientExecutionTimeout 客户端 SDK 参数,使其更快地超时和失败,例如在 50 毫秒之后。这种更快的超时会导致客户端在指定的时间段后放弃高延迟请求。然后,客户端发送第二个请求,该请求的完成速度通常比第一个请求快得多。有关详细信息,请参阅为延迟感知 Amazon DynamoDB 应用程序调整 AWS Java SDK HTTP 请求设置。
缩短客户端和 DynamoDB 端点之间的距离
如果您的用户分散在全球,请使用全球表来指定您希望表格可用的 AWS 区域。您还可以使用 DynamoDB 网关端点来避开互联网流量。
使用缓存
如果您的读取流量很大,请使用缓存服务来降低延迟,例如 Amazon DynamoDB Accelerator (DAX)。
连接重用
建立新连接时,必须对连接进行身份验证和验证。此外,在处理请求之前,DynamoDB 必须从内部系统获取表的元数据。DynamoDB 前端实例集维护用于存储此信息的缓存。如果重用连接,则使用缓存为请求提供服务。
由于 AWS Key Management Service (AWS KMS) 用户的 DynamoDB 请求需要额外的跃点才能进行身份验证,因此延迟可能会增加。AWS KMS 密钥每 5 分钟刷新一次。如果未重用客户端连接,则必须为每个请求建立新的 TCP 连接。这些请求的连接包括 TCP 握手和确认等进程,并会导致客户端延迟。
由于每个新连接都需要身份验证,缓存无法使用,从而导致服务器端延迟。要重用连接,请使用 TCP keep-alive 参数。另外,请使用能够保证连接对象单一实例的设计模式。有关详细信息,请参阅 Amazon CloudGuru 网站上的未在 Lambda 函数中重用的 AWS 客户端。
相关信息
SuccessfulRequestLatency
了解 Amazon DynamoDB 延迟
查询和扫描数据的最佳实践