首页/新闻资讯/正文详情

Redis 实现播放量原子计数 + 定时任务同步 MySQL

发布时间:2026/9/25 21:37:58 来源:云帆数科 栏目:资讯中心
Redis 实现播放量原子计数 + 定时任务同步 MySQL
一、业务场景做音乐网站项目每一次用户点击歌曲播放就需要该歌曲播放数加一。 假设并发量上来如果每一次播放请求直接 update 修改 MySQL。大量访问会频繁触发数据库写操作数据库压力会很高。于是想到使用 Redis 做中间缓存。播放先写到 Redis隔一段时间批量同步回 MySQL减少直接操作数据库的次数。二、实现思路1.用户点击播放后端接收请求2. 使用 Redis INCR原子命令对对应歌曲 id 的播放计数自增 1INCR 是原子操作不用担心并发冲突3. 开启 SpringBoot 定时任务每隔一段时间读取 Redis 里面所有歌曲播放增量4. 将增量批量更新 MySQL同步完成之后清空 Redis 里面已经落库的增量数据。注意隐患如果服务器突然宕机。Redis 还没来得及同步的数据会有丢失风险。 解决思路可以开启 Redis 持久化 RDB/AOF 降低丢数概率或者缩短定时任务间隔时间。三、核心关键代码片段1.播放量自增接口使用 RedisTemplate//歌曲id播放一次计数1 // redisKey格式play:count:{songId} String key play:count: songId; redisTemplate.opsForValue().increment(key);2.定时任务Scheduled每 10 分钟执行一次同步逻辑Component EnableScheduling public class PlayCountSyncTask { Resource private RedisTemplateString,Object redisTemplate; Resource private SongMapper songMapper; Scheduled(fixedDelay 10 * 60 * 1000) public void syncPlayCountToMysql(){ //1.查询redis中所有play:count开头的key //2.循环取出歌曲id和增量 //3.批量update mysql播放数量 //4.同步成功删除redis里面这一批key } }定时任务不要写太短间隔频繁同步就失去 Redis 缓冲意义太长宕机丢数风险变大。四、Redis‑MySQL 缓存不一致问题我们这套方案Redis 暂存增量定时任务批量同步。这是异步更新天然就容易出现缓存和数据库不一致。4.1当前项目会出现不一致的两种场景1.还没到定时同步时间MySQL 直接修改歌曲播放量后台手动改数据库数值。Redis 里面还保留旧增量同步之后就会叠加造成播放数量出错。2.定时任务执行一半程序宕机定时任务遍历一批 key一部分同步成功入库还没来得及删除 Redis 里对应的 key服务宕机。服务重启后定时任务再次执行会把这部分增量再次同步一遍造成播放量重复累加数据变多。注意普通用户点击播放只会往 Redis 做 increment不会直接写 MySQL。普通播放不会产生不一致人为修改 MySQL 才是不一致主要来源。4.2几种解决思路方案 1业务约束业务上约定所有播放量修改只能走 Redis。后台不允许直接手动修改 MySQL 播放量字段。优点实现零代码改动。适合课程演示。缺点现实生产环境很难强制所有人不碰数据库。方案 2更新 MySQL 同时主动清理对应 Redis Key如果后台需要修改歌曲播放量管理员编辑修改 MySQL 播放数字立刻删除该歌曲对应的play:count:{songId}这个 Redis key。Redis 这条增量作废。下一次定时任务不会再把旧增量刷进去。优点简单好实现。缺点如果删除 Redis 网络超时失败不一致仍然会发生。方案 3记录增量日志不要直接用 Redis 存最终增量数字。Redis 只记录变更。或者数据库新建一张增量日志表。每次播放除了 Redis 自增插入一条增量日志。定时任务读取日志表同步同步完标记已处理。就算 Redis 宕机数据库日志还留存记录不会丢数据。优点解决宕机丢数减少不一致风险。缺点每一次播放都插入数据库又增加数据库 IO违背最开始减轻数据库压力初衷。五、强一致 vs 最终一致如果业务强行要求强一致性该怎么办本项目 Redis 暂存增量定时同步只能保障最终一致性。若业务场景余额等要求强一致优先方案放弃 Redis 做计数缓冲读写直接访问 MySQL。牺牲一部分吞吐量换取数据准确。分布式事务 Seata 理论可实现事务回滚但是 Redis 不支持 XA 协议工程落地麻烦很少用于解决 Redis‑MySQL 一致性。六、思考总结“不存在优雅、高性能的方案让 Redis 与 MySQL 保证强一致性。工业上的思路是业务选型规避这个难题。如果要求强一致就不要把写逻辑交给 Redis如果想用 Redis 扛住高并发写压力就要接受最终一致性。”如果非要强一致又想要高性能可以换专门组件例如 Redis 本身的 Redisson 的 RLock 只是锁锁只能减少并发冲突锁解决不了网络故障导致双写不一致。锁≠强一致。

相关推荐

ESLint插件在VSCode中不提示、不生效:TaoToken统一Key通道下的排查与配置骨架
ESLint插件在VSCode中不提示、不生效:TaoToken统一Key通道下的排查与配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 21:37:58

2026年06月06日最热门的开源项目(Github):用TaoToken统一Key跑通本地AI工具链
2026年06月06日最热门的开源项目(Github):用TaoToken统一Key跑通本地AI工具链

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 21:37:58

math round_down
math round_down

round_down 是 Linux 内核中与 round_up 配对的宏,用于将数值向下对齐到指定大小的整数倍。它同样定义在 include/linux/math.h(旧版本在 kernel.h)。定义与原理#define round_down(x, y) ({ \typeof(x) _x (x); \typeof(y) _y (y); \(void… · 2026/9/25 21:37:52

Canal实时同步原理与生产级部署实践
Canal实时同步原理与生产级部署实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 1:22:10

Visual Studio 字体配置深度指南:从连字对齐到中英文协同渲染
Visual Studio 字体配置深度指南:从连字对齐到中英文协同渲染

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 1:22:10

SAP SLT实时同步实战指南:从配置断层到生产排错
SAP SLT实时同步实战指南:从配置断层到生产排错

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 1:22:10

Tesseract-OCR 5.5.0在Windows 64位的安装与命令行识别
Tesseract-OCR 5.5.0在Windows 64位的安装与命令行识别

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 1:22:10

网站永久关闭背后:运营逻辑与用户数据保全指南
网站永久关闭背后:运营逻辑与用户数据保全指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 1:22:10

深入解析Linux内核NAPI机制:从中断风暴到轮询收包
深入解析Linux内核NAPI机制:从中断风暴到轮询收包

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 1:22:04

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码