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

如何降低每次API请求更新last_activity产生的数据库调用频次

可行实现方案

下面是3种落地性强的方案,可根据你的业务流量规模选择:

方案1:缓存时间窗口拦截(最常用)

  • 依赖Redis(分布式场景)或本地内存缓存(单实例场景),给每个会话ID生成一个缓存键,比如activity_updated:{session_id}
  • 每次API请求到达时,先尝试给对应缓存键设置当前时间,同时设置过期时间等于你设定的更新窗口(比如60秒),使用原子写入操作(Redis用SETNX,本地缓存用带原子性的putIfAbsent方法)
  • 如果写入缓存成功,说明当前时间窗口内没有执行过更新,再触发数据库的last_activity字段更新;如果写入失败,说明窗口内已经更新过,直接跳过数据库操作
  • 优势:可以拦截99%以上的无效数据库请求,实现简单,性能损耗极低

方案2:数据库条件更新(零额外依赖)

  • 直接改写你的更新SQL,添加时间判断条件,不需要引入任何外部组件:
UPDATE user_sessions 
SET last_activity = CURRENT_TIMESTAMP 
WHERE session_id = '当前会话ID' 
AND last_activity < CURRENT_TIMESTAMP - INTERVAL 60 SECOND;
  • 数据库会自动判断如果该会话的last_activity距离当前不足60秒,就不会执行实际的写入操作,执行效率远高于无条件更新
  • 优势:不需要修改业务架构,代码改动最小;适合流量规模中等,不想额外维护缓存组件的场景

方案3:异步批量更新(超高流量场景)

  • 所有API请求触发last_activity更新时,仅将会话ID写入本地队列或消息队列,不直接操作数据库
  • 后台启动一个定时任务,比如每60秒执行一次:取出队列中所有的会话ID去重后,批量执行数据库更新操作,完成后清空队列
  • 优势:数据库写入次数降到最低,即使每秒数万请求也只会每分钟执行1次批量更新;适合用户量极大、并发极高的场景
注意事项
  • 时间窗口长度可以根据你的活跃用户统计精度要求调整,比如统计日活的话窗口设为1小时都没问题,统计分钟级活才需要设更小的窗口
  • 用缓存方案时一定要用原子写入操作,避免并发请求同时穿透缓存触发多次数据库更新

内容的提问来源于stack exchange,提问作者Saurabh Gangamwar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 23:18:00