为高吞吐量时间序列存储设计可扩展且具成本效益的访问模式
Source: Dev.to
请提供需要翻译的正文内容,我才能为您进行简体中文翻译。
表结构与主键
| 属性 | 类型 | 角色 |
|---|---|---|
deviceId | String | 分区键 |
timestamp | String (ISO‑8601, e.g., 2025-12-04T12:34:56Z) | 排序键 |
temperature, humidity, pressure | Number | 负载 |
metadata | String (JSON) | 可选负载 |
ttl | Number (epoch seconds) | TTL属性(用于过期) |
为什么选择此主键?
所有设备的读取数据都存储在一起,使得能够高效地进行范围查询(deviceId = X AND timestamp BETWEEN …)。可以使用 ScanIndexForward=false 和 Limit=1 对最新读取进行单项查询。
索引策略
| 索引 | 分区键 | 排序键 | 用例 |
|---|---|---|---|
| 主表 | deviceId | timestamp | 按设备的点查询和范围查询 |
全局二级索引 (GSI) – DeviceLatestGSI | deviceId | timestamp(投影为 DESC) | 直接查询最新读数,无需扫描整个分区(Limit=1,ScanIndexForward=false) |
可选 GSI – MetricGSI | metricType(例如 "temperature" 常量) | timestamp | 跨设备的单一指标时间范围查询(较少使用) |
注意: 主表已经支持最新读数查询;该 GSI 为可选,仅在预计会有大量并发的“最新”读取,可能导致同一 deviceId 的热点分区读取时才考虑添加。大多数情况下,使用 Limit=1 的主表查询已足够。
容量模式与扩展
| 模式 | 何时使用 | 配置 |
|---|---|---|
| On‑Demand | 不可预测的峰值,快速启动,无需管理容量。 | 自动处理 10 k 写入/秒;按请求付费。 |
| Provisioned + Auto Scaling | 流量可预测,想要控制成本。 | 从 15,000 RCUs 和 5,000 WCUs 开始(每次写入 ≤ 1 KB 消耗 1 WCU)。启用自动扩展,目标 70 % 利用率。 |
成本比较(约,US East 1,2025 年 12 月):
- On‑Demand 写入:每百万写请求单元 $1.25 → 大约 $12.5 k/月,针对 10 k 写入/秒(≈ 26 M 写入/天)。
- Provisioned 5,000 WCUs ≈ $0.65 每 WCU‑小时 → $2.3 k/月,加上自动扩展缓冲。
On‑Demand 更简单;如果流量稳定,Provisioned 可能更便宜。
缓解热点分区风险
- Uniform
deviceIddistribution: 确保设备 ID 是随机的(例如 UUID 或哈希)。 - If a few devices dominate traffic: 使用 sharding ——在
deviceId前添加随机分片后缀(例如deviceId#shard01)。在一个小型配置表中存储分片数量;应用程序查询所有分片并合并结果。这样可以将写入容量分散到各个分区。
数据保留 (TTL)
-
添加一个数值属性
ttl = timestampEpoch + 30 days。 -
在此属性上启用 DynamoDB TTL;DynamoDB 会自动删除已过期的项目(通常在过期后 48 小时内)。
-
不需要额外的 Lambda,保持低成本。
读取性能优化
- Projection(投影): 仅在 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 cleanup) | 如果需要在 30 天后精确确定性删除,可以使用计划的 Lambda 查询即将到期的 ttl 项并删除它们,但通常 DynamoDB 的 TTL 已足够。 |
| Amazon CloudWatch Alarms | 监控 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. 最终一致性 | 强一致性读取成本翻倍;仅在需要即时新鲜度的情况下使用。 |
Bottom Line
通过此设计,你可以实现:
- 快速点查找 (
QuerywithdeviceId+Limit=1,ScanIndexForward=false). - 高效的时间范围查询 (
QuerywithdeviceIdandtimestamp BETWEEN …). - 自动 30 天过期 via DynamoDB TTL.
- 成本效益高的高吞吐写入 using on‑demand or provisioned capacity with auto‑scaling, plus optional sharding to avoid hot partitions.