为高吞吐量时间序列存储设计可伸缩、成本效益高的访问模式

发布: (2025年12月4日 GMT+8 17:39)
6 min read
原文: Dev.to

Source: Dev.to

表结构 & 主键

属性类型角色
deviceIdString分区键
timestampString (ISO‑8601,例如 2025-12-04T12:34:56Z)排序键
temperature, humidity, pressureNumber负载
metadataString (JSON)可选负载
ttlNumber (epoch 秒)用于过期的 TTL 属性

为什么使用这个主键?
同一设备的所有读数会被存放在一起,便于高效的范围查询(deviceId = X AND timestamp BETWEEN …)。通过 ScanIndexForward=false 并设置 Limit=1,可以对最新读数执行单项查询。

索引策略

索引分区键排序键使用场景
主表deviceIdtimestamp按设备的点查询 & 范围查询
全局二级索引 (GSI) – DeviceLatestGSIdeviceIdtimestamp(投影为 DESC直接查询最新读数,无需扫描整个分区(Limit=1, ScanIndexForward=false
可选 GSI – MetricGSImetricType(例如 "temperature" 常量)timestamp跨设备的单一指标时间范围查询(较少使用)

注意: 主表已经支持最新读数查询;该 GSI 为可选,仅在预期大量并发“最新”读取可能导致同一 deviceId 热分区时才考虑。大多数情况下,使用 Limit=1 的主表查询即可。

容量模式 & 扩展

模式适用场景配置
按需 (On‑Demand)不可预测的流量峰值,快速启动,无需管理容量自动处理 10 k 写入/秒;按请求付费
预置 + 自动扩展流量可预测,想要控制成本初始 15,000 RCUs5,000 WCUs(每写入 ≤ 1 KB 消耗 1 WCU)。开启自动扩展,目标 70 % 利用率

成本对比(约算,US East 1,2025 年 12 月):

  • 按需写入:$1.25 每百万写请求单元 → 约 $12.5 k/月(10 k 写入/秒 ≈ 26 M 写入/天)。
  • 预置 5,000 WCUs ≈ $0.65 每 WCU‑小时 → $2.3 k/月,加上自动扩展缓冲。

按需模式更简单;如果流量稳定,预置模式可能更便宜。

缓解热点分区风险

  • 均匀的 deviceId 分布: 确保设备 ID 随机(如 UUID 或哈希)。
  • 若少数设备占据大部分流量: 使用 分片——在 deviceId 前加随机分片后缀(如 deviceId#shard01)。在一个小配置表中保存分片数量;应用查询所有分片并合并结果。这样可以将写容量分摊到多个分区。

数据保留 (TTL)

新增数值属性 ttl = timestampEpoch + 30 days
在该属性上启用 DynamoDB TTL,DynamoDB 会自动删除过期项(通常在过期后 48 小时内完成)。

  • 无需额外 Lambda,成本保持低。

读取性能优化

  • 投影: 在 GSI 中仅保留需要的属性(如 temperature, humidity, pressure, timestamp),降低读取大小和费用。
  • 强一致 vs. 最终一致读取: 大多数查询使用 最终一致(更便宜,4 KB 读取消耗 0.5 RCU)。对“最新读数”且对新鲜度要求高的场景使用 强一致 读取(4 KB 读取消耗 1 RCU)。
  • BatchGetItem:一次调用获取多个设备的最新读数。

辅助服务(可选)

服务目的
AWS Kinesis Data Streams缓冲入站传感器数据,平滑突发写入,并通过 Lambda 消费写入 DynamoDB。
AWS Lambda (TTL 清理)若需在恰好 30 天时删除,可使用计划 Lambda 查询即将过期的 ttl 项并删除,但 DynamoDB TTL 通常已足够。
Amazon CloudWatch 警报监控 ConsumedWriteCapacityUnits, ThrottledRequests, SystemErrors,触发扩容或告警。
AWS Glue / Athena对导出到 S3 的历史数据(通过 DynamoDB Streams → Lambda → S3)进行即席分析。

权衡总结

权衡点影响
按需 vs. 预置按需简化运维,但在稳定 10 k 写入/秒时可能贵约 30 %。预置需要容量规划,但配合自动扩展可更省钱。
分片 vs. 简单性分片消除热点分区风险,但查询逻辑更复杂(每个设备可能涉及多个分片)。
TTL vs. Lambda 清理TTL 成本低,删除有延迟(最多 48 小时)。Lambda 可实现精确删除,但会产生计算费用。
GSI 用于最新读数在高负载下保证 O(1) 读取延迟,但会增加写入成本(每次写入都要更新 GSI)。若 Limit=1 的主表查询已足够,通常不必使用。
强一致 vs. 最终一致强一致读取费用翻倍;仅在必须立即获取最新数据时使用。

结论

采用本方案可实现:

  • 快速点查询Query + deviceId + Limit=1ScanIndexForward=false)。
  • 高效时间范围查询Query + deviceId + timestamp BETWEEN …)。
  • 通过 DynamoDB TTL 自动 30 天过期
  • 成本效益高的高吞吐写入,可选按需或预置并自动扩展,必要时使用分片避免热点分区。
Back to Blog

相关文章

阅读更多 »

开源邮件预热:完整指南

引言 开源电子邮件预热是逐步与邮箱提供商建立信任的过程,使您的邮件进入收件箱,而不是垃圾邮件文件夹....