5

秒杀中的常见问题

 2 years ago
source link: https://segmentfault.com/a/1190000040764508
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

固定窗口算法:时间节点无法动态更新,即 set key expire 10s(1-11秒,2-12秒)处理不好

滑动窗口算法: zset member id score 10 解决时间节点问题 score即时间戳,可以动态获取(currentTime - score)时间内的总访问量,借此判断是否达标

漏桶算法:redis中好像有类似实现

令牌桶算法:Guava RateLimiter

2.降级(也叫做熔断)

spring cloud sentinel

3.1缓存一致性问题

A. 先更新Db,再delete redis

两个问题:

a .更新Db成功,删除缓存失败。导致redis中有脏数据(可以借助rocketmq不断重试解决)

b.1)缓存刚好失效

(2)请求A查询数据库,得一个旧值

(3)请求B将新值写入数据库

(4)请求B删除缓存

(5)请求A将查到的旧值写入缓存(根据耗时情况可以推算出概率比较低)

B 先删除缓存,再更新Db

​ (1)A线程删除缓存,写db更新为data2

​ (2)b线程查询发现缓存不存在

​ (3)b线程同步当前d b最新数据da ta1到redis

​ (4)a线程将数据data2写入DB .脏数据发生

3.2 解决方案

A.延时双删

先删除缓存,再更新DB,再异步删除缓存(通过rocketmq异步重试机制,确保删除成功)

B.订阅binLog机制

阿里开源的canal

3.3应用 秒杀实现

限流:zset滑动窗口限流

降级:spring cloud sentinel+open Feign熔断

延时双删策略

1.库存扣减问题

提交订单时

提交订单时预先扣减库存,超时回复:定时任务轮训数据库没有付款的订单,超时订单归还库存

2.热点数据缓存

延时双删策略

3.库存防止超卖问题

乐观锁机制 update

update stock
   sale = sale + 1,
   version = version + 1,
  WHERE id = #{id,jdbcType=INTEGER}
  AND version = #{version,jdbcType=INTEGER}

或者
 
  update stock
   sale = sale + 1
  WHERE id = id
  AND sale={#sale}

悲观锁机制

在Service层给更新表添加一个事务,这样每个线程更新请求的时候都会先去锁表的这一行(悲观锁),更新完库存后再释放锁。可这样就太慢了,1000个线程可等不及。

beginTranse(开启事务)

try{

    //quantity为请求减掉的库存数量
    $dbca->query('update s_store set amount = amount - quantity where amount>=quantity and postID = 12345');

}catch($e Exception){

    rollBack(回滚)

}

commit(提交事务)
  • 在系统初始化时,将商品的库存数量加载到Redis缓存中;
  • 接收到秒杀请求时,在Redis中进行预减库存,当Redis中的库存不足时(库存<0可以在内存中设置一个标志量boolean=已经卖光,就不需要再去请求redis增加网络开销了,分布式情况下通过zookeeper获得相应通知),直接返回秒杀失败,否则继续进行第3步;
  • 将请求放入异步队列中,返回正在排队中;
  • 服务端异步队列将请求出队,出队成功的请求可以生成秒杀订单,减少数据库库存(失败就会回滚,并且会恢复redis中的库存数据即加1),返回秒杀订单详情。
  • 当后台订单创建成功之后可以通过websocket向用户发送一个秒杀成功通知。前端以此来判断是否秒杀成功,秒杀成功则进入秒杀订单详情,否则秒杀失败。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK