| 缓存雪崩 | 指的是缓存服务器中大量数据同时失效,导致大量数据直接打到数据库中,导致数据库压力增加。 |
| 缓存穿透 | 指的是大量请求访问一个不存在的数据,数据库中不存在缓存中也不可能存在,导致大量请求打到数据库上。 |
| 缓存击穿 | 指缓存中热点数据失效,导致访问这个热点数据的大量数据同时打到数据库上。 |
一、缓存雪崩解决方法:
1.缓存中设置随机过期时间,使得不会出现大量数据同时失效的情况。
2.使用分布式缓存架构,redis中有三种方案:
(1)主从复制,即一个主节点和几个从节点,主节点主要负责写操作,而从节点负责读操作和备份数据,减少缓存压力提高可用性。
(2)哨兵模式,即一个主节点和多个哨兵节点,哨兵节点监视主节点并备份数据,一旦主节点失效,哨兵节点中会重新选举出一个主节点,增加了可用性。
(3)redis cluster redis集群,即一份数据分成几份,分别交由几个缓存节点进行存储,每个节点负责一部分数据的操作,缓存节点之间会互相备份数据来保证数据冗余,节点之间通过互相通信来达到故障检测、数据转移的目的。同时每个缓存节点也可以有多个从节点,行为类似主从复制。
二、缓存穿透解决办法:
1.缓存空值,在一个无效数据访问到数据库中后,会在缓存中记录这个数据并且设置空值,这样下一次同样无效数据访问后就会在缓存中直接返回空值,而传不到数据库中。
2.布隆过滤器,布隆过滤器有一个位数组,其长度根据你设置的故障率和存值数量来确定,位数组中所有值默认设为0,当往数据库中存一个数据时,会先在布隆过滤器经过三个(不一定,只是举例)哈希函数计算,计算出三个位数组上的位置,然后将这三个位置的值设为1。等到下次要查一个数据的时候,就会先在布隆过滤器通过三个哈希函数计算出三个位置,再检查这三个位置的值是否为1。如果都为1,就很可能(如果故障率设为0.01,就是99%的概率)存在数据库,如果有一个值为0,那么绝对不在数据库中,这个请求自然也被过滤。
三、缓存击穿解决办法:
1.将热点数据设置为永不过期,自然也不会失效,适用于一些热点数据较为固定和波动不大的情况。
2.使用redis的set if not exists即setnx命令,set <key> <vlue> nx ex <expireTime>,这个命令分别设置键,值(一般是1),还要过期时间。只有当key不存在时才会设置,返回1说明加锁成功,返回0说明key已经存在,锁在别的进程手上。
主要流程是:请求在缓存未查询数据->获得锁->数据库同步数据到缓存中->请求获得数据->释放锁->下一个请求查询数据
但是如果比如说一个进程A设置过期时间为10s,10s之后A的锁过期,但A还没执行完,B进程获得锁,设置key为1,11sA执行完,删除锁,这时候删除的是B进程的锁。所以要给每个进程获得锁时用雪花算法或者UUID生成一个id,删除锁是看一下是否是自己的锁。
还可以设置一个守护线程,在A进程获得锁时创建一个守护线程,比如说设置过期时间为10s,如果第9秒A进程没有执行完,守护线程会给这把锁续期10s,直到A进程执行完释放锁。
个人笔记,如有错误欢迎指正。
543

被折叠的 条评论
为什么被折叠?



