35、商户查询缓存(利用互斥锁解决缓存击穿)

商户查询缓存(利用互斥锁解决缓存击穿)

 

案例:

35、商户查询缓存(利用互斥锁解决缓存击穿)_第1张图片

我们这里如何模拟互斥锁:

1、我们用redis的setnx命令来模拟锁,他的逻辑是如果不存在这个key的时候才改变。如果key存在就无法改变

35、商户查询缓存(利用互斥锁解决缓存击穿)_第2张图片

 

  1. redis如何来释放这个锁呢我们就直接del删除这个key就ok了

35、商户查询缓存(利用互斥锁解决缓存击穿)_第3张图片

 

  1. 若是忘记(或者程序出错)无法删除key,就无法释放锁,所以我们最好给他设置个超时时间。

第一步:(我们先设置两个方法分别设置锁和释放锁)

 

 这里我们不直接返回这个flag。因为它的类型是Boolean,而他的方法是一个boolean(一个Boolean的包装类)我们如果直接拆箱的话可能会出现空指针。我们用Booleanuntil工具类。

设置锁:

 

释放锁:

 

第二步:改变逻辑(再写一个解决缓存击穿的方法)

我们是通过这个去调用是解决缓存击穿还是缓存穿透(这里我们调用的是缓存击穿)

35、商户查询缓存(利用互斥锁解决缓存击穿)_第4张图片

 

  1. 改变缓存穿透的返回(再封装一下)

 

 

35、商户查询缓存(利用互斥锁解决缓存击穿)_第5张图片

 

 

 

  1. 写缓存击穿的逻辑方法+

 

说一下我们的逻辑:

这里我们的4缓存重建。我们怎么缓存重建呢,我们要去访问我们的数据库资源再写回redis而我们就需要再我们访问数据库资源之前给他加一个互斥锁,再判断下锁是否存在才能去查询我们的数据库资源再写到redis,完了再释放掉锁,返回数据再结束。

35、商户查询缓存(利用互斥锁解决缓存击穿)_第6张图片

 

4.1、获取互斥锁

35、商户查询缓存(利用互斥锁解决缓存击穿)_第7张图片

 

4.2、判断是否成功获取锁

 

4.3、失败,则休眠并重试(我们这里就直接递归前面的了)

35、商户查询缓存(利用互斥锁解决缓存击穿)_第8张图片

 

4.4、成功,根据id查询数据库(这里我们获取到锁后并且查到有锁后我们应该再次检测一下redis缓存是否存在(前面没命中可能不是他没有只是没有命中罢了),若是存在我们就无须再重建缓存了)

35、商户查询缓存(利用互斥锁解决缓存击穿)_第9张图片

 

我们再给前面4.3的sleep做个抛异常try/catch加上7后加8

35、商户查询缓存(利用互斥锁解决缓存击穿)_第10张图片

 

35、商户查询缓存(利用互斥锁解决缓存击穿)_第11张图片

 

35、商户查询缓存(利用互斥锁解决缓存击穿)_第12张图片

 

35、商户查询缓存(利用互斥锁解决缓存击穿)_第13张图片

 

高并发模拟我们使用apache JMeter

35、商户查询缓存(利用互斥锁解决缓存击穿)_第14张图片

 

35、商户查询缓存(利用互斥锁解决缓存击穿)_第15张图片

 

35、商户查询缓存(利用互斥锁解决缓存击穿)_第16张图片

 

结果:(控制台确只有一条sql)

35、商户查询缓存(利用互斥锁解决缓存击穿)_第17张图片

 

你可能感兴趣的:(redis,数据库,缓存,redis,中间件,nosql)