针对任何的高并发架构,就记住四个字:分而治之
高并发系统架构
小红书-内卖秒杀项目总结_yuyanggo的博客-CSDN博客
1)守住数据库的底线:MySQL订单入库限流,避免MySQL被压垮
2)将商品数据提前初始化到redis中,利用redis缓存在实际下单前做好各种校验
3)用isMember函数(Set),记录用户已经购买过哪些商品,购买过的不许再次购买
高并发下秒杀商品,必须知道的9个细节 - hanease - 博客园
一、瞬时高并发
二、页面静态化
三、秒杀按钮 1、秒杀按钮设计
四、读多写少
五、缓存问题 1、缓存击穿 2、缓存穿透
六、库存问题 1、预扣库存 2、数据库扣减库存 3、redis扣减库存 4、 lua脚本扣减库存
七、分布式锁
八、mq异步处理 1、消息丢失问题 2、重复消费问题 3、垃圾消息问题 4、延迟消费问题
九、如何限流 1、对同一用户限流 2、对同一ip限流 3、对接口限流 4、加验证码 5、提高业务门槛
【去哪儿网技术系列课】高并发解决方案_哔哩哔哩_bilibili
数据一致性
高并发系统不可避免的一个问题就是,数据一致性问题
1. 缓存一致性
a. 用的最广泛的就是,先更新数据库再删除缓存
为什么不先操作缓存,因为相对而言操作数据库是更慢的,多线程访问下,就更容易造成数据库和缓存数据不一致
删除缓存可能存在失败的情况,就需要重试补偿机制,讲删除失败的key发给mq,让异步再重试删除
b. canal伪装成数据库slave,同步binlog删除缓存
另外需要注意的是,还应该隔离事务与缓存,确保数据库入库后再进行缓存的删除操作。比如考虑到数据库的主从架构,主从同步及读从写主的场景下,可能会造成读取到从库的旧数据后便更新了缓存,导致缓存落后于数据库的问题,这就要求对缓存的删除应该确保在数据库操作完成之后。所以,基于 binlog 增量日志进行数据同步的方案,可以通过选择解析从节点的 binlog,来避免主从同步下删除缓存过早的问题。
注:由于线程 1 和 线程 2 的执行不确定性导致数据库和缓存的不一致。这种由于线程竞争导致的缓存不一致,可以通过分布式锁解决,保证对缓存和数据库的操作仅能由同一个线程完成。对于没有拿到锁的线程,一是通过锁的 timeout
时间进行控制,二是将请求暂存在消息队列中顺序消费。
另在,在 Write-Through 模式下,不管是先更新缓存还是先更新数据库,都存在更新缓存或者更新数据库失败的情况,上面提到的重试机制和补偿机制在这里也是奏效的
分布式事务
解决分布式事务的最好的方法就是:不要有分布式事务,而解决分布式事务的绝大部分落地方案都是:最终一致性。
1)如何用2组CountDownLatch,来实现:主线程,等5个子线程分别执行结束,主线程再根据各个子线程的执行结果来指导子线程们如何进行下一步动作。
2)如何利用编程式事务 + 两阶段提交2PC,来实现多线程事务
3)解释了2PC,可能无法保证最终一致性的一个隐患情况
常见分布式事务解决方案
2.1. 分布式事务模型
2.2. 二将军问题和幂等性
2.3. 两阶段提交(2PC) & 三阶段提交(3PC)方案
2.4. TCC 方案
2.5. 事务状态表方案
2.6. 基于消息中间件的最终一致性事务方案
高可用
raft协议实现主从自动切换