缓存雪崩,是指在某一个时间段,缓存集中过期失效。
例子:线上订单投注,获取奖期对应的drowId,将drowId放入redis进行缓存,将所有奖期的缓存设置相同的过期时间,导致业务启动时,大量请求在同一时间从后台获取drowId后放入缓存,缓存会在同一时间过期,导致大量请求又被发送到后台。
解决方案:为不同的redis缓存设置不同的过期策略
- (Least recently used)为热点数据设置更长的过期时间
- 批量获取的数据,放入redis时,设置不同的过期时间
- (Least Frequently Used)算法根据数据的历史访问频率来淘汰数据
缓存穿透:
用户使用不当数据,导致该数据无法在缓存查找到正常请求,每次都向后发送查询请求。
例子:用户在获取奖期对应drowId时,传入奖期数据有误,无法在缓存中找到对应奖期的drowdId,每次都向后台发送查询请求。
解决方案:将错误的奖期也在缓存中设置相应的缓存,可能缓存数据为null,进行判断后返回错误。可以防止前端恶意错误请求数据导致的每次查询缓存无相应数据发向后台。
缓存击穿:
非集群配置的redis,使用非一致性hash算法进行运算分库,导致当其中一台redis宕机时,现有的数据缓存无效。
非一致性hash算法典型: MD5(key)% N
例子:有5台redis,算法为MD5(用户号)%5,那么当其中一台宕机后,算法改为MD5(用户号)%4
导致其中4台的大部分缓存。
解决方案:采用一致性hash算法 (FVNhash chord KAD)
推荐文章(https://blog.csdn.net/doleria/article/details/78685531)
对reids集群模式影响:无影响(采用redis集群,本身高可用,使用slot槽算法,当其中一个主失效时,由从顶上),但是当一个主从集群崩溃时,这部分key对应槽不可用。
redis集群槽分配 slot
集群中分配槽
./redis-trib.rb reshard 127.0.0.1:6380 (集群中任意节点)
会提示:
移动多少槽:
节点接受这些槽(node ID)
从哪些节点移动槽(可选all全部)
redis-cli -h 127.0.0.1 -p 6379 -a xxxx cluster addslots {8400…11954}
查看redis key对应的槽
方法1:redis -cli -c 下get 方法会提示
方法2:127.0.0.1:6379> CLUSTER KEYSLOT “test”
(integer) 6918
redis hash key的计算方案
如果想让redis key 固定落在某个集群节点上。
- 利用crc16 计算出redis的hash值,再模以16384计算出槽值
ps: redis为了将分片计算的值 与 业务值分开,有2种不同的计算方式:
1-> key 形式 “test” ,以"test" 本身作为数据源进行槽运算
2-> key形式 “[prefix]test”,以括号内的prefix进行槽运算,忽视key本身做到分片规则运算与实际key值无关,达到指定该key存放的redis节点,(该节点可以单独开启特殊数据持久化) - 利用将该槽redis-cli -h 127.0.0.1 -p 6379 -a xxxx cluster addslots {槽id}分配给指定redis节点