发布时间:2022-10-26 文章分类:编程知识 投稿人:李佳 字号: 默认 | | 超大 打印

把黑马的redis实战看了将近一半,自己也做了挺多思考,现在对于Redis的使用,以及业务方面的思考,有了更深刻的理解。

但是,使用缓存之后,就有许多问题需要解决,包括业务场景的考虑。

1. 缓存和数据库一致性的问题
2. 缓存击穿问题
3. 缓存穿透问题
4. 缓存雪崩问题

分析一个具体的业务场景
用户抢优惠券,要满足条件:一人一单
要考虑并发时出现的问题。
1.首先要查该用户是否有券,如果没有就能让它去抢,否则就不允许
2.如果该用户没券,就去执行抢券逻辑

在查券的时候,如果同一个用户发来了很多请求,这是一个并发问题。
如果说线程1判断无券,那么就去执行抢券逻辑。如果这时候线程2进来了,也会判断无券,又会执行它的抢券逻辑。
所以需要加一个锁,即使同一个用户发来多次请求,此时也是串行的,只有等他执行完抢券逻辑,才会释放锁。那么如果该用户的其他的抢券请求进来,也不会去执行抢券。
同时,抢券逻辑也在这个锁的锁定范围内,也避免了超卖的问题。

这里的锁需要使用分布式锁,比如redis的setnx()。

分析:我们采用的锁对象是,user.getId()。在单体项目之下,对于一个用户的多个请求进来,该锁对象确实是唯一的。

但是如果将该项目做成集群的形式,由于每个Tomcat都有自己的JVM,那么此时的锁就不是同一吧了,而是这台服务器认为他的这把锁是唯一的,那台服务器认为他的这把锁是唯一的。这样子就做不到唯一锁。所以我们这里需要使用分布式锁。

但是分布式锁也会遇到一些问题,比如说误删锁问题,以及删锁时的原子性问题。