如何在DynamoDB中统计指定时间段内的API调用总次数
DynamoDB 时间范围调用量统计实现方案
方案1:复用原始日志表新增GSI(推荐,无需修改现有写入逻辑)
这是成本最低、灵活度最高的实现方式,仅需对已有的EpgApiStatistics表新增全局二级索引即可:
- 按查询需求创建对应GSI:
- 支持按API用户查询:创建GSI,分区键为
apiUserKey,排序键为dateAccessed - 支持按渠道查询:创建GSI,分区键为
channelId,排序键为dateAccessed
- 支持按API用户查询:创建GSI,分区键为
- 索引投影属性可按需选择:如果仅需要统计调用量,选择仅投影键属性即可,大幅降低索引存储成本
- 注意
dateAccessed字段需要存储为Unix时间戳或者ISO 8601格式的字符串(如2024-11-10T00:00:00Z),保证排序逻辑符合时间顺序 - 查询逻辑:需要统计指定时间范围的调用量时,直接对对应GSI发起Query请求,设置
KeyConditionExpression为apiUserKey = :targetUser AND dateAccessed BETWEEN :startTime AND :endTime,同时开启Select=COUNT参数,DynamoDB会直接返回匹配条目总数,无需拉取全量数据,性能可达毫秒级。
方案2:优化现有累加计数表适配时间范围查询
如果你的查询频率极高、需要更低的查询成本,可以修改现有两张累加计数表的结构,预聚合不同时间粒度的调用量:
- 修改表的键结构:
- 用户维度累加表:分区键改为
apiUserKey#时间粒度标识,比如userA#2024-11代表2024年11月的用户统计项,排序键为具体的日期(如2024-11-10),每条记录存储当日该用户的总调用量 - 渠道维度累加表:分区键改为
channelId#时间粒度标识,排序键为具体的日期,存储逻辑同上
- 用户维度累加表:分区键改为
- 写入逻辑调整:每次从DataDog拉取日志写入原始表时,同时对累加表的对应时间粒度条目执行原子累加操作,示例命令为
UpdateItem SET callCount = callCount + :incr,避免并发写入导致的计数错误 - 查询逻辑:统计指定时间范围的调用量时,只需拉取该范围内的所有预聚合条目,对
callCount字段求和即可,查询仅涉及少量预计算数据,性能远高于扫描原始日志。
选型建议
- 若统计需求灵活,需要支持任意时间范围的临时查询,优先选择方案1,无需调整写入逻辑,上线速度最快
- 若统计场景固定(仅按天/周/月查询)、查询QPS高,优先选择方案2,查询成本仅为方案1的几十分之一
内容的提问来源于stack exchange,提问作者rashidkhan
相关产品推荐
相关产品推荐

