砍材农夫砍材农夫
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • nodejs
    • npm
    • webpack
    • 微信
    • 正则
    • uniapp
  • java

    • java基础
    • jdk体系
    • jvm
    • spring
    • spring_cloud
    • spring_boot
    • 分库分表
    • zookeeper
  • python

    • python基础
    • python高级
    • python框架
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • docker
  • k8s
  • devops
  • nginx
  • 元宇宙
  • 区块链
  • 物联网
  • linux
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • nodejs
    • npm
    • webpack
    • 微信
    • 正则
    • uniapp
  • java

    • java基础
    • jdk体系
    • jvm
    • spring
    • spring_cloud
    • spring_boot
    • 分库分表
    • zookeeper
  • python

    • python基础
    • python高级
    • python框架
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • docker
  • k8s
  • devops
  • nginx
  • 元宇宙
  • 区块链
  • 物联网
  • linux
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • 常见案例分析

    • 分布式ID
    • 分布式锁
    • 订单超时取消
    • 库存扣减问题
    • 幂等接口设计
    • 接口限流设计
    • 接口防刷设计
    • 多级缓存设计
  • 相关拓展知识

    • TCP和UDP区别
    • 签名算法
    • 身份认证令牌
    • 如何防止class类被反编译
    • 消息队列
    • maven如何统一指定jdk
    • maven常用插件
  • 算法|数据结构

    • 二叉树
    • 红黑树
    • 快速比较两棵树查找相同节点方法
  • 主要解决问题
  • 问题一:性能瓶颈问题
    • 减少锁的竞争
    • 降低数据库行锁开销
    • 雪崩
  • 问题二:数据一致性问题
    • 原子扣减(双重保障)
    • 异步落库的一致性保障
    • 幂等处理
    • 库存回滚
  • 问题三:缓存和数据库双写不一致问题
    • 延时双删(针对先删缓存、再更新数据库的优化)
    • 基于消息队列的异步更新(最终一致性)
    • 强一致性方案(分布式锁 / 读写锁)
  • 问题四:其他相关业务问题
    • 幂等性设计
    • 库存扣减补偿机制

主要解决问题

锁粒度 性能瓶颈问题
    锁竞争、数据库行锁开销、雪崩
事务ACID 数据一致性问题
    超卖、少卖、库存不一致
缓存和数据库双写不一致问题
    数据不一致、库存预热与回退问题
高并发 其他相关业务问题
    重复扣款、下单、恶意请求

问题一:性能瓶颈问题

减少锁的竞争

  • 库存分片,通过hash或轮询随机算法等将库存数据分片存储到不同的数据库实例中
如库存总量 1000,分为 10 个段,每段 100)
  • 锁粒度(乐观锁代替悲观锁)
数据库层面使用版本号(version)或 CAS(Compare And Set)方式,避免长事务持有行锁
UPDATE stock SET count = count - #{num}, version = version + 1 
WHERE id = #{id} AND version = #{oldVersion} AND count >= #{num}

降低数据库行锁开销

  • 缓存预热 + 异步同步

将库存预热到 Redis,扣减请求先在 Redis 中完成,然后通过消息队列(如 RocketMQ、Kafka)异步将最终结果落库

请求到达 → Redis 扣减(Lua 脚本保证原子性) → 返回成功
发送“库存扣减成功”消息到 MQ
消费端批量消费消息,合并更新数据库(如每 100 条一次批量 update)
  • 数据库行锁优化
确保扣减 SQL 走索引(如主键或唯一索引),避免表锁或间隙锁
使用 SELECT ... FOR UPDATE 时,务必在事务中尽快提交,减少锁持有时间

雪崩

限流->将请求拦截在系统前端,避免直接冲击数据库
  (使用令牌桶、漏桶算法,限制单位时间内的请求量,保护后端系统)
熔断降级->当依赖的 Redis 或数据库出现超时、异常时,启动熔断器
多级缓存->

问题二:数据一致性问题

异步落库(导致数据库库存未扣减)
重复扣减
部分失败(扣减库存后,后续业务(如创建订单)失败)
缓存与数据库同步延迟(期间查询可能出现不一致)

原子扣减(双重保障)

Redis Lua 脚本
数据库乐观锁:落库时再次校验库存,防止异步过程中出现超卖

异步落库的一致性保障

本地消息表:在业务数据库中建一张消息表,将扣减记录和消息状态放在同一本地事务中
事务消息

幂等处理

全局唯一流水号:每次扣减操作生成唯一 ID(如订单号+商品ID),在消费端根据流水号去重
Redis 预检查:消费前先查 Redis 是否已处理过该流水号

库存回滚

消息驱动回滚:发送“库存回滚”消息,消费端执行库存增加
定时对账补偿:扫描超时未支付的订单,调用回滚接口
TCC 分布式事务:若业务要求强一致性

通常秒杀场景可接受短暂不一致(最终一致),优先保证高并发

问题三:缓存和数据库双写不一致问题

延时双删(针对先删缓存、再更新数据库的优化)

允许短时间不一致,但希望最终一致

先删除缓存。
更新数据库。
延时一段时间(如 500ms),再次删除缓存
redis.delete(key);
database.update(data);
// 延迟执行,可采用线程池或消息队列
executor.schedule(() -> redis.delete(key), 500, TimeUnit.MILLISECONDS);

基于消息队列的异步更新(最终一致性)

对一致性要求较高,可接受短暂不一致,但需保证最终一致

更新数据库后,发送一条“更新缓存”的消息到消息队列,由消费者异步更新缓存。
    若更新失败,可重试
解耦,可靠性高(消息持久化),重试机制保证最终一致性
@Transactional
public void updateData(Data data) {
    database.update(data);
    // 事务提交后发送消息
    transactionSynchronization.registerSynchronization(new TransactionSynchronization() {
        public void afterCommit() {
            mqSender.send("cache_update", data);
        }
    });
}
// 消费者
@RabbitListener
public void handleCacheUpdate(Data data) {
    redis.set(data.getId(), data);
}

强一致性方案(分布式锁 / 读写锁)

对一致性要求极高(如金融交易),但并发量较低

对同一数据的读写操作加分布式锁,保证同一时刻只有一个线程能读写数据

问题四:其他相关业务问题

幂等性设计

全局唯一流水号:每次扣减请求携带唯一标识(如订单号、业务流水号),在服务端记录已处理的流水号

Redis 去重:使用 Redis SETNX 命令,将流水号作为 key 存储,
    设置合理过期时间,重复请求直接拒绝。
数据库去重表:建一张去重表,以流水号作为唯一索引,
    扣减前先插入,若主键冲突则说明已处理。

业务状态机:订单状态流转(如待支付、已支付、已取消),只有在特定状态才允许扣减库存,避免重复操作

库存扣减补偿机制

  • 定时任务扫描
定期扫描超时未支付的订单,调用库存服务回滚接口(增加库存)。注意要处理并发问题,避免重复释放
  • 延迟消息
下单成功后发送一条延迟消息
  • 状态机驱动
订单状态变更时(如取消、超时关闭),主动触发库存回滚
最近更新: 2026/2/28 16:31
Contributors: kcnf
Prev
订单超时取消
Next
幂等接口设计