通过 Amazon DynamoDB Accelerator (DAX) 实现微秒级延迟 - 内存缓存设计

解说通过 DAX 加速 DynamoDB 读取、缓存策略和集群设计。

DAX 概述

DAX 是 DynamoDB 的内存缓存,将读取延迟从毫秒缩短到微秒。与 ElastiCache(Redis/Memcached)不同,它提供 DynamoDB 兼容的 API,只需将 SDK 端点更改为 DAX 集群即可完成迁移。DAX 集群部署在 VPC 内,集群中的每个节点保存相同缓存数据的副本。主节点处理写入,副本节点分散读取负载,主节点故障时副本自动提升为主节点。

缓存策略与集群设计

项目缓存缓存 GetItem 和 BatchGetItem 的结果,通过 TTL(默认 5 分钟)自动失效。查询缓存缓存 Query 和 Scan 的结果集。通过写透(Write-Through),执行 PutItem 或 UpdateItem 时缓存也会更新,降低读取时返回旧数据的风险。集群推荐最少 3 节点(多可用区),节点类型根据缓存数据量选择。dax.r5.large(内存 13.5 GB)适合中等规模工作负载,dax.r5.xlarge(内存 27 GB)适合拥有大量热数据集的场景。

缓存策略与一致性

DAX 通过项目缓存和查询缓存两层管理缓存。项目缓存以 TTL(默认 5 分钟)保持 GetItem 和 BatchGetItem 的结果。查询缓存保持 Query 和 Scan 的结果。写入操作(PutItem、UpdateItem、DeleteItem)通过写透同时反映到 DAX 和 DynamoDB。最终一致性读取从缓存返回,强一致性读取直接访问 DynamoDB。TTL 设置过短会降低缓存命中率,设置过长会降低数据新鲜度,存在权衡。 学习 DynamoDB 缓存性能优化时,相关书籍(Amazon)可供参考。

DAX 与 ElastiCache 的比较

DAX 是 DynamoDB 专用缓存,最大优势在于只需替换 DynamoDB SDK 端点即可引入。应用程序端无需实现缓存失效逻辑或键设计,写透自动维持一致性。而 ElastiCache (Redis) 可以缓存 DynamoDB 以外的数据源(RDS、外部 API 响应),并能利用 Pub/Sub 和有序集合等数据结构。DAX 的查询缓存通过参数完全匹配判定命中,因此 Query 过滤条件频繁变化的工作负载命中率会下降。此时使用 ElastiCache 在应用端设计缓存键更为高效。DAX 不缓存事务 API(TransactGetItems / TransactWriteItems),因此对于以事务为主的工作负载效果有限。

设计陷阱与运维注意事项

DAX 集群必须部署在 VPC 内。从 Lambda 连接时,需将 Lambda 放在同一 VPC 中或通过 VPC 端点访问。将 Lambda 放入 VPC 会增加冷启动时间,建议结合 Provisioned Concurrency 使用。DAX 节点故障时,客户端 SDK 自动重试,但故障转移期间(数秒)读取延迟会回到毫秒级。应用程序应设计为容许这种暂时性延迟增加。项目缓存和查询缓存的 TTL 可独立设置。对写入频繁的表,应将项目缓存 TTL 缩短至 1 分钟以下,查询缓存 TTL 设得更短以维持数据新鲜度。集群扩展(添加节点)可在线执行,但缩减(删除节点)涉及缓存数据重新分布,应在低流量时段进行。

DAX 的费用

DAX 按节点小时计费,dax.r5.large 每小时约 0.269 美元(月费约 194 美元)。推荐最少 3 节点(多可用区)配置,月费约 582 美元。比较 DynamoDB 读取容量单位(RCU)的成本削减效果与 DAX 节点成本,判断在读取密集型工作负载中引入 DAX 是否有利。缓存命中率达 90% 以上时,可大幅削减 DynamoDB 的 RCU,预期削减效果超过 DAX 成本。

总结

DAX 是 DynamoDB 的内存缓存,实现微秒级读取延迟的服务。通过写透缓存维持写入一致性,同时通过项目缓存和查询缓存两层大幅减轻读取负载。DynamoDB 的 RCU 成本削减效果在缓存命中率 90% 以上时显著,最适合读取密集型工作负载。