如何高效从WebSocket关联的Dynamodb Connections表获取在线用户总数?
高效实现在线用户总数统计的方案
核心思路:维护实时计数而非事后扫描
针对你的场景(5k-10k条连接数据),推荐两种低延迟、低成本的实时统计方案,完全规避之前方案的痛点:
方案一:DynamoDB Streams + Lambda维护计数表
- 实现逻辑:
- 给Connections表开启DynamoDB Streams,捕获所有新增/删除连接的事件
- 触发Lambda函数,每次事件发生时,更新一个单独的计数表(比如命名为
ConnectionCounts),表结构仅需主键(如type: online-users)和count字段 - UI通过轻量API端点(API Gateway + Lambda)读取这个计数表的
count值,单次查询为DynamoDB GetItem操作,成本极低
- 优势:
- 完全实时,连接状态变化立即同步计数
- 读取计数操作是O(1)复杂度,无扫描成本,UI刷新无压力
- 维护成本低,Lambda触发逻辑简单,无需定时任务
- 注意事项:
- 处理Lambda幂等性:使用DynamoDB的
UpdateItem操作,配合ADD count :delta语法,新增连接时delta设为1,删除时设为-1,即使同一条事件被多次触发,计数也不会出错 - 初始化计数:首次部署时,运行一次性Lambda扫描Connections表,初始化计数表的初始值
- 处理Lambda幂等性:使用DynamoDB的
方案二:使用ElastiCache Redis维护实时计数器
- 实现逻辑:
- 用户建立WebSocket连接时,存入DynamoDB的同时调用Redis的
INCR命令增加计数 - 连接断开(如WebSocket的
$disconnect路由触发)时,调用Redis的DECR命令减少计数 - UI通过API Gateway + Lambda读取Redis的
GET命令获取当前计数
- 用户建立WebSocket连接时,存入DynamoDB的同时调用Redis的
- 优势:
- 性能极致,Redis计数操作是内存级延迟,完全满足实时需求
- 适配未来连接数增长到更大规模的场景(如10w+)
- 注意事项:
- 处理异常断开:若用户直接关闭浏览器导致连接异常断开,可给Redis计数键设置TTL(如15分钟),同时在连接建立时定期用
EXPIRE刷新TTL;或结合DynamoDB Streams的过期清理逻辑(给Connections表的连接记录加TTL,过期后触发Lambda更新Redis计数) - 高可用:选择ElastiCache Redis的集群模式或主从模式,避免单点故障
- 处理异常断开:若用户直接关闭浏览器导致连接异常断开,可给Redis计数键设置TTL(如15分钟),同时在连接建立时定期用
对比原方案的优化点
- 替代方案1(扫描DynamoDB):将高成本的全表扫描替换为O(1)的单条查询,彻底解决刷新成本问题
- 替代方案2(定时统计):实现真正的实时计数,无需牺牲时效性
- 替代方案3(@connections端点):绕开CORS限制,用更可控的计数维护方式,无需依赖AWS WebSocket API的原生端点
内容的提问来源于stack exchange,提问作者Billy Criddle
相关产品推荐
相关产品推荐

