You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于DynamoDB构建高负载广告系统事件聚合服务方案问询

Ad-tech频次控制与统计场景下的DynamoDB实践解答

针对你开发的百万级用户Ad-tech系统需求,结合200K RPM的吞吐量、按天的查询粒度要求,逐个解答你的疑问:

1. DynamoDB是否适配该场景?

完全适配。DynamoDB原生支持高吞吐量写入(200K RPM的写入量在其承载范围内,可通过预置/自动扩缩容的WCU满足),且能提供亚毫秒级的查询延迟,符合你“响应极快”的要求。另外,其TTL(时间到了自动删除)功能可以自动清理超过统计周期(如Y天)的旧数据,正好匹配按天的时间单位需求。

2. 是否应为每种事件类型(点击/浏览/关闭等)单独建表?

不建议。除非不同事件类型的量级差几个数量级、或有完全独立的存储/生命周期规则,否则单独建表会增加运维复杂度(多表配置、重复设置TTL等)。更优的方式是把事件类型作为主键/排序键的一部分,或者作为Item的属性字段,统一放在一张主表中管理。

3. 主键最优配置方式?你设想主键为user id,排序键为ad id+当日日期{dd/mm/yyyy}组合。

你这个设计能很好支撑用户维度的查询(比如查用户Y天内某广告的浏览/点击次数),但无法高效满足广告/广告组维度的统计需求(比如查某广告近40天的浏览用户数)。建议采用**双表+GSI(全局二级索引)**的组合设计:

  • 用户维度主表:分区键设为user_id,排序键设为event_type#ad_id#date(例:view#ad_1001#2024-05-20),属性存event_count(事件次数)。该表用来快速判断用户是否触发频次上限。
  • 广告维度GSI:在主表上创建GSI,分区键设为ad_id#event_type,排序键设为date#user_id。通过这个GSI可以快速查询某广告某事件类型下,指定日期范围内的所有用户,进而统计用户数和总次数。

如果广告组的统计需求频繁,还可以再建一个以ad_group_id#event_type为分区键的GSI。

4. 使用ADD操作递增特定日期下用户广告事件计数器是否昂贵?有无替代方案?

DynamoDB的UpdateItem中使用ADD操作是原子递增,成本和普通写入操作(单条Item<1KB时占1个WCU)几乎一致,不算昂贵,完全可以支撑200K RPM的写入量。

替代方案的话,如果对实时性要求稍低,可以攒一批事件(比如10秒内的同用户同广告事件)再批量更新,但这会导致频次控制有延迟,不符合广告实时拦截的需求。所以ADD原子操作是最优选择。如果是统计类的非实时数据,可以用DynamoDB Streams+Lambda做异步汇总,但实时频次控制还是得依赖ADD的实时计数。

5. 如何实现按广告、广告组查询(如查询某广告组所有用户浏览量、近40天广告浏览量)?

分两种场景实现:

  • 按广告查询:利用上面提到的ad_id#event_type分区键的GSI,执行Query操作时指定分区键(如ad_1001#view),并设置排序键的范围(如2024-04-10#到2024-05-20#),通过Select=COUNT可以快速得到总用户数;如果需要总浏览次数,可以在GSI中包含event_count属性,查询后累加得到总数,或者单独建一个广告日汇总表(分区键ad_id#event_type#date,属性存total_count和unique_user_count),通过Lambda异步更新。
  • 按广告组查询:有两种方式:一是建以ad_group_id#event_type为分区键的GSI,逻辑同广告查询;二是在广告日汇总表中增加ad_group_id属性,再建一个以ad_group_id#event_type#date为分区键的GSI,直接查询广告组的日汇总数据,效率更高。

另外,统计唯一用户数时,也可以采用“每个用户每天在广告维度下只存一条记录”的方式:建一张广告用户日表,分区键ad_id#event_type#date,排序键user_id,写入时用PutItem加条件(仅当Item不存在时写入),这样查询该分区的Item数量就是唯一用户数。

6. 还需考虑哪些其他事项?

  • TTL配置:所有按天存储的Item都要设置TTL,过期自动删除,避免表无限膨胀,同时降低存储成本。
  • 热点规避:如果某广告/广告组的流量特别大,单一分区键(如ad_id#event_type)会造成热点,导致吞吐量瓶颈。可以在分区键后加随机后缀(如ad_id#event_type#rand_1-10),查询时遍历10个分区再汇总,或者按广告组+广告ID的组合分散流量。
  • 强一致性读取:频次控制是强一致性需求,查询用户的事件计数时必须开启ConsistentRead=true,避免读到旧数据导致错误展示广告。
  • 吞吐量规划:按200K RPM的写入量计算WCU(单条ADD操作占1个WCU,若Item<1KB),建议采用预置WCU+自动扩缩容,比按需模式更稳定,成本也更低。
  • 错误重试:ADD操作失败(如网络抖动)必须重试,确保计数准确,否则会导致频次控制失效。可以用指数退避策略重试。
  • 成本控制:GSI会额外消耗读写容量,要根据实际查询需求权衡是否创建;TTL自动删除旧数据能有效降低存储成本。
  • 峰值测试:提前模拟200K RPM的写入流量,测试系统的延迟、吞吐量和热点场景下的表现,确保上线后稳定运行。

内容的提问来源于stack exchange,提问作者Tal Humy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 15:48:28