Redis在项目中的应用(点评)

 一、缓存更新策略

主动更新策略

 先删除缓存时,由于更新数据库耗时较多,在此期间如有另一线程查询缓存/数据库并写入缓存,则当前线程更新数据库后会导致缓存和数据库数据不一致,而反之出现不一致的概率要小得多。

 二、缓存会出现的问题

1、缓存穿透

缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,于是缓存就永远不会生效,这些请求会被直接打到数据库上。

解决方案

2、缓存雪崩

缓存雪崩是指在同一时段大量的缓存key同时失效或者redis服务宕机,导致大量请求到数据库。

解决方案

3、缓存击穿

缓存击穿也叫热点key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。

解决方案

(1)示意图:

(2)优缺点对比

互斥锁保证了一致性,牺牲了可用性,逻辑过期则相反。

三、超卖问题

 解决方案

乐观锁的关键是判断之前得到的数据是否被修改过,常见的方式有版本号法和CAS法。乐观锁的缺点是失败率高,需要做业务控制,如改成where id=10 and stock>0即可。

注意:更新数据时才用乐观锁

 四、一人一单问题(防止一个用户抢多个券)

为了防止同一用户抢到多个券,可以先查询前查询当前用户-券的订单是否已经存在,但在多线程下,多个查询的结果可以均为0,然后做添加订单操作,这仍会导致部分用户抢到多个券。

 解决方案

单机情况下通过给用户加synchronized锁(内部维护锁监视器),但是集群模式下不行,多个JVM会有各自的锁,所以仍会出现一个用户抢了多个券的情况。解决方案是让多个JVM使用同一把锁,即分布式锁。

分布式锁:满足分布式系统或集群模式下多进程可见互斥的锁。

 基于redis的分布式锁

(1)可能出现的问题1

当线程1由于业务阻塞而锁时间到期释放锁,线程2就可以获取锁,在线程2执行业务时,线程1业务完成并释放了锁,就会出现新的并发问题。解决方案是在释放锁的时候,进行标识(线程id、uuid等)判断。

 

(2)可能出现的问题2

当线程1业务执行完并判断锁标识是否一致后,这时候却由于gc而出现阻塞,导致超时而释放了锁,于是线程2就可以获取锁。在线程2执行业务时,线程1的gc完成。由于线程1已经判断了锁因而可以直接释放锁,但此时redis锁是线程2的,这样就释放了线程2的锁,又会出现新的并发问题。

解决方案是在释放锁的时候,进行标识(线程id、uuid等)判断。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值