分布式锁#
分布式锁,顾名思义,分布式锁就是分布式场景下的锁,比如多台不同机器上的进程,去竞争同一项资源,就是分布式锁。
setnx key value如果key不存在,则会将key设置为value,并返回1;如果key存在,不会有任务影响,返回0。
set key value nx ex secondsnx表示具备setnx特定,ex表示增加了过期时间,最后一个参数就是过期时间的值。
分布式锁需要满足谁申请谁释放原则,不能释放别人的锁,也就是说,分布式锁,是要有归属的。
Redis➕Lua,可以说是专门为解决原子问题而生。有了Lua的特性,Redis才真正在分布式锁、秒杀等场景
RedLock
消息队列#

PUB/SUB,不需要ACK,不需要持久化,可用
Stream,需要ACK,需要消费组,需要持久化,可用
Stream功能最全,但是相对完备的消息队列中间件比如Kafka,可靠性还是很大差距,不支持至少一次语意,因为Redis本身的数据持久化都是有时间空隙的,如果对数据的可靠要求比较强,还是需要用完整的消息中间件。
Redis这三种,是三种不同功能要求下的消息传递手段,Stream相对来说在轻量级里相对完善。
秒杀#
第一点 高并发:海量请求,服务要能扛住。 我们可以先将库存名额预加载到Redis,然后在Redis中进行扣减,扣减成功的再通过消息队列,传递到MySQL做真正的订单生成。

第二点,不能超卖。 第一步,判断库存名额是否充足; 第二步,减少库存名额,扣减成功就是抢到。 如果第一步判断的时候还有库存,但是由于是并发操作,实际调用的时候,可能已经没有库存了,这样就会造成超卖。使用lua
第三点,避免少卖。 1. 上面提到的,减少库存操作超时,但实际是成功的,因为超时并不会进入生成订单流程 2. 在Redis操作成功,但是向Kafka发送消息失败,这种情况也会白白消耗Redis中的库存。 3. 在投递Kafka失败的情况下,增加渐进式重试;
第四点,保证触达到用户而不是黄牛。
- 为了性能,我们还是将限制逻辑加入到Redis中,所以我们的Lua脚本中,第一步查询库存,第二步扣减库存,需要优化为第一步查询库存,第二步查询用户已购买个数,第三步扣减库存,第四步记录用户购买数。
限流器#
| 算法 | 核心思想 |
|---|---|
| 固定窗口 | 每段时间计数 |
| 滑动窗口 | 最近一段时间计数 |
| 漏桶 | 固定速度处理请求 |
| 令牌桶 | 固定速度发放通行证 |
