Redis二:哨兵模式与缓存问题
哨兵模式
哨兵模式即自动版谋权篡位,哨兵作为一个独立进程后台监督主机,主机一旦宕机,会在从机中选出新的主机(选举模式),原理:哨兵通过发送命令,等待Redis服务器响应,从而监控多个Redis服务
多哨兵集群
每个哨兵除了监督主机和从机,也会在哨兵间互相监督
操作
这是哨兵服务,Running in sentinel mode代表这是一个哨兵
启动哨兵服务端监控一主二从,此时我们可以得出信息,哨兵检测主机,并指导谁是从机(6380主机,6381,6382从机),一段时间后,我们手动把80服务挂掉,通过观察 9:17分和9:32分我们简单浏览,哨兵检测到主机挂了(通过failover),把6381设置成了主机,6382成了6381的从机,此时我们观察下图,发现不止6382,连最开始的主机6380也成了6381的从机,重新启动6380,发现6381有了两个slave(谋朝篡位,听懂掌声),redis-sentinel的配置文件sentinel.conf也发生了改变。
优点
1.哨兵基于主从复制模式,所有的主从复制优点他都有
2.主从自动切换,故障可以转移,系统的可用性就会更好
3.主从模式的升级,从手动切换主机,到自动选举出一个从机成为主机,更加健壮
1) 主观下线
主观下线,适用于主服务器和从服务器。如果在规定的时间内(配置参数:down-after-milliseconds),Sentinel 节点没有收到目标服务器的有效回复,则判定该服务器为“主观下线”。比如 Sentinel1 向主服务发送了PING
命令,在规定时间内没收到主服务器PONG
回复,则 Sentinel1 判定主服务器为“主观下线”。(我理解为退位)
2) 客观下线
客观下线,只适用于主服务器。 Sentinel1 发现主服务器出现了故障,它会通过相应的命令,询问其它 Sentinel 节点对主服务器的状态判断。如果超过半数以上的 Sentinel 节点认为主服务器 down 掉,则 Sentinel1 节点判定主服务为“客观下线”。(我理解为主机被架空被迫下台)
3) 投票选举
投票选举,所有 Sentinel 节点会通过投票机制,按照谁发现谁去处理的原则,选举 Sentinel1 为领头节点去做 Failover(故障转移)操作。Sentinel1 节点则按照一定的规则在所有从节点中选择一个最优的作为主服务器,然后通过发布订功能通知其余的从节点(slave)更改配置文件,跟随新上任的主服务器(master)。至此就完成了主从切换的操作。
缓存穿透与雪崩
缓存的使用流程
缓存穿透(查不到导致)
缓存穿透是指当用户查询某个数据时,Redis 中不存在该数据,也就是缓存没有命中,此时查询请求就会转向持久层数据库 MySQL,结果发现 MySQL 中也不存在该数据,MySQL 只能返回一个空对象,代表此次查询失败。如果这种类请求非常多,或者用户利用这种请求进行恶意攻击,就会给 MySQL 数据库造成很大压力,甚至于崩溃,这种现象就叫缓存穿透。
解决方案
1.缓存空对象
当 MySQL 返回空对象时, Redis 将该对象缓存起来,同时为其设置一个过期时间。当用户再次发起相同请求时,就会从缓存中拿到一个空对象,用户的请求被阻断在了缓存层,从而保护了后端数据库,但是这种做法也存在一些问题,虽然请求进不了 MSQL,但是这种策略会占用 Redis 的缓存空间。
- 布隆过滤器
我们知道,布隆过滤器判定不存在的数据,那么该数据一定不存在,利用它的这一特点可以防止缓存穿透。
缓存击穿(数据量太大了)
缓存击穿是指用户查询的数据缓存中不存在,但是后端数据库却存在,这种现象出现原因是一般是由缓存中 key 过期导致的。比如一个热点数据 key,它无时无刻都在接受大量的并发访问,如果某一时刻这个 key 突然失效了,就致使大量的并发请求进入后端数据库,导致其压力瞬间增大。这种现象被称为缓存击穿
解决方案
1.设置热点数据key,永不过期
2.分布式锁:使用分布式锁,保证对于每个key同一时间只有一个线程能去查询后端服务,其他线程只能等待,等待分布式锁被释放,这种方式把高并发的压力转移到了分布式多,对分布式锁的考验很大
缓存雪崩
缓存雪崩是指缓存中大批量的 key 同时过期,而此时数据访问量又非常大,从而导致后端数据库压力突然暴增,甚至会挂掉,这种现象被称为缓存雪崩。它和缓存击穿不同,缓存击穿是在并发量特别大时,某一个热点 key 突然过期,而缓存雪崩则是大量的 key 同时过期,因此它们根本不是一个量级。
解决方案
1.redis高可用
增设几台redis,搭建集群
2.限流降级
在缓存失败后,通过加锁或者队列来控制数据库写缓存的线程数量,比如某个key只允许一个线程查询数据和写缓存,其他线程等待
3.数据预热
在项目正式部署之前,我们先把数据都访问一遍,大量访问数据先加载到缓存中,手动加载缓存不同的key,设置不同的过期实践,让缓存失败的时间点尽量均匀
分布式多,对分布式锁的考验很大
缓存雪崩
缓存雪崩是指缓存中大批量的 key 同时过期,而此时数据访问量又非常大,从而导致后端数据库压力突然暴增,甚至会挂掉,这种现象被称为缓存雪崩。它和缓存击穿不同,缓存击穿是在并发量特别大时,某一个热点 key 突然过期,而缓存雪崩则是大量的 key 同时过期,因此它们根本不是一个量级。
解决方案
1.redis高可用
增设几台redis,搭建集群
2.限流降级
在缓存失败后,通过加锁或者队列来控制数据库写缓存的线程数量,比如某个key只允许一个线程查询数据和写缓存,其他线程等待
3.数据预热
在项目正式部署之前,我们先把数据都访问一遍,大量访问数据先加载到缓存中,手动加载缓存不同的key,设置不同的过期实践,让缓存失败的时间点尽量均匀
要明白三者的区别,不要混淆,
缓存穿透,属于恶意访问,该数据无论缓存还是数据库都没有
缓存击穿,缓存中热点key过期,导致大量的请求集中到了存储层数据库造成了巨大的压力
缓存雪崩,大量的热点key同时失效,可以理解为超大量级的缓存击穿