如何用 Redis 处理重复请求,并划分 Redis 与 MySQL 的数据存储职责?
未标记
考查重点:业务幂等与缓存、持久化分工。查询缓存可复用结果,写请求靠业务幂等键和数据库约束;Redis 存热点与短状态,MySQL 保存事务性权威记录
本题目录
参考答案
本答案基于相关资料,由 AI 辅助编写,供学习与面试准备参考。如有疏漏,欢迎反馈指正。
核心回答
先区分重复请求的目的:重复查询可用Redis缓存结果、合并并发回源;重复写入则需要业务幂等,不能只靠缓存。Redis适合保存热点结果、短期去重标记和任务状态等快速访问数据;MySQL通常保存需要事务、约束和长期查询的权威业务记录。
两层存储的价值是让高频读取更快,同时由数据库守住持久业务事实。代价是增加过期、同步和故障恢复问题,所以只有数据库已能满足需求时,也可以先不增加Redis。
处理重复写入
客户端为同一次业务意图沿用幂等号,服务端把它与用户、接口及请求摘要绑定。Redis可用带过期的原子条件写标记“处理中”,短路重复并发请求;完成后可缓存结果,后来的相同请求返回已有结果。
但标记会过期,Redis可能故障或被清理,工作进程也可能在数据库提交后、结果缓存前退出。因此,重要写入还需MySQL唯一约束、幂等记录或状态条件更新兜底,并尽量与业务结果在同一事务提交。重复请求和参数不同但幂等号相同的请求,应分开处理。
数据职责怎样划分
例如订单和支付流水放MySQL,订单展示快照和短期请求结果可放Redis。聊天记录需长期检索时保存到数据库,Redis可保存近期活跃窗口。Redis本身支持持久化,但持久化、异步复制、内存成本及查询能力不同,不能仅凭“支持落盘”判断它与关系数据库可互换。
追问
- 分布式锁能防重复扣款吗? 只能串行化同时到达的请求;前一次释放后重试仍可能重复扣款,仍要业务幂等。
Redis里查不到就是没执行吗? 不是,还应查询权威业务状态。- 两层不一致怎么办? 明确数据库权威,提交后可靠失效缓存,并用
TTL与补偿限制陈旧窗口;严格判断走数据库约束。
参考资料
- 国内:JavaGuide / Snailclimb:接口幂等性设计详解:幂等键和去重表的例子说明超时后重新投递时,怎样避免业务被执行两次。
- 国内:JavaGuide / Snailclimb:三种常用缓存读写策略:提交后失效、删除失败和旧值回填的时序帮助区分不同不一致窗口。
- 国内:JavaGuide / Snailclimb:缓存基础常见面试题:借鉴缓存和权威存储分离的说明,解释正文中 Redis 承接高频读取、MySQL 保存持久业务事实的分工与一致性成本。
- 国外:AWS Builders’ Library:Making retries safe with idempotent APIs:客户端请求标识及原子记录的设计说明“未收到响应”为何不等于“未执行成功”。
- 国外:Redis:SET command:条件写与过期选项说明短期占位如何避免拆成多条命令的竞争,但它不等于数据库业务幂等。
