如何解决redis缓存击穿?
程序员文章站
2022-03-03 20:27:37
背景缓存击穿,是指对那些会失效的key有高并发的请求,然后在失效的那一瞬间,高并发请求来了,读不到redis的值,全都会把请求打到数据库,导致数据库压力过大解决方案1、分布式锁当发现缓存失效的时候,先使用setnx设置分布式锁,只有获取锁成功的那个线程可以查数据库并回写缓存。优点:能解决问题。缺点:1、如果不支持原子操作的话,这个setnx的分布式锁可能会发生死锁。2、性能一般2、本地锁同上,只是使用本地锁,解决死锁问题。优点:没有死锁问题缺点:有多少个机器实例,最多就有多少个“查数...
背景
缓存击穿,是指对那些会失效的key有高并发的请求,然后在失效的那一瞬间,高并发请求来了,读不到redis的值,全都会把请求打到数据库,导致数据库压力过大
解决方案
1、分布式锁
当发现缓存失效的时候,先使用setnx设置分布式锁,只有获取锁成功的那个线程可以查数据库并回写缓存。
优点:能解决问题。
缺点:
1、如果不支持原子操作的话,这个setnx的分布式锁可能会发生死锁。
2、性能一般
2、本地锁
同上,只是使用本地锁,解决死锁问题。
优点:没有死锁问题
缺点:有多少个机器实例,最多就有多少个“查数据库然后回写redis”的操作
3、软过期
把过期时间写在value中,当读到的时候,发现过期的时候,立马更新过期时间,然后再读数据库、回写。
优点:没有死锁问题
缺点:所谓的“立马”更新过期时间,其实也不是原子性的,高并发的时候会有大量的线程认为过期,然后去读数据库。其实也没完全解决大量查数据库的问题,只是减少了查数据库的量。
选择
考虑到实际请求,我们选用方案二:本地锁。这样可以减轻数据库的压力,数据库的压力不会太大
参考
本文地址:https://blog.csdn.net/waltonhuang/article/details/107638961
上一篇: 谈谈PHP中的多进程消费队列