哨兵模式

如果redis的master宕机了,该如何解决?

  1. 关闭所有master与slave的服务
  2. 我们需要从slave中选择一个成为master
  3. 修改其他slave的配置,连接新的主
  4. 启动master和slave
  5. 全员复制N + 部分复制N
  6. 关闭期间的数据服务由谁来接管?
  7. 找一个新的master,怎么个找法?
  8. 修改配置后,原始的master恢复了怎么解决?

以上问题的解决方案,我们需要使用哨兵

哨兵

哨兵是一种分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的master并将所有的slave连接到新的master

首先,在redis中存在几个哨兵,哨兵会询问master和slave,通过ping,问他们是否宕机;也会询问其他哨兵是否存活(监控)。当一个哨兵询问master时,master并未给出回应,则他会认为该master已经宕机,也就是主观下线。他会把master未给出回应的消息通知给其他master,如果其他master在对master进行询问时,也没有回应,则说明master是真的宕机了,也别称为客观下线;

当master宕机时,需要从slave中选取一个slave来作为新的master。在这开始之前,哨兵之间会进行投票,且每个哨兵都是候选人,被选举的哨兵被称为话事人,由它来决定哪个slave称为新的master。

哨兵投票的机制: 首先哨兵会把自己的ip,端口号,竞选次数,以及自己的runid发送给其它哨兵。

在选举过程中,每个哨兵手里都有一票,且每个哨兵都想当话事人。那么哨兵就会开始抢夺,每个哨兵都会发出一条指令,告诉其他哨兵我想竞选。比如哨兵1与哨兵4发出竞选指令,哨兵2接收到指令后进行投票,那么投给谁呢。这里采用先到先得的原则,如果哨兵2最先接收到的是哨兵1的指令,则会投给哨兵1。反之,投给哨兵4。在这之间,票数最多的作为话事人,但需要注意的是,第一轮选举可能不会成功,所以可能会有第2轮,第3轮。

选取master的机制:

选举成功的哨兵会在salve中选择一个作为新的master

选取规则如下:

  • 不在线的不选取
  • 响应慢的不选取
  • 与原来的master断开时间久的不选取
  • 优先原则
  • 优先级
  • offset 数据多 更全
  • runid 最早启动,runid越大

当新的master被选举出来后,哨兵会发送指令给其他master:

  • 向新的master发送slaveof no one
  • 向其他slave发送新的master的ip和端口

总结:故障转移阶段

  1. 发现问题,主观下线与客观下线
  2. 竞选话事人
  3. 优选新的master
  4. 新的master上线,其他的salve切换master,原master作为slave故障恢复后连接

企业级解决方案

  • 5.1 缓存预热
    场景:“宕机”服务器启动时迅速宕机
    为什么会出现这种情况?
    当redis服务启动时,数据并没有完全加载,正在从master或mysql中同步数据,那么大量请求来到redis,就会造成reids的崩溃。

解决方案

  • 前置准备工作:
  1. 日常例行统计数据的访问记录,统计访问频度较高的热点数据
  2. 利用LRU数据的删除策略,构建数据留存队列。例如:storm和kafka配合
  • 准备工作:
  1. 将统计的数据按级别进行分类,并根据级别,redis优先加载级别较高的热点数据
  2. 利用分布式多服务器同时进行数据读取,提高数据加载过程
  3. 热点数据主从同时预热
  • 实施:
  1. 使用脚本程序固定触发数据预热过程
  2. 如果条件允许,使用CDN,效果会更好

总结:缓存预热指在系统启动前,提前将相关的缓存数据加载到redis中。避免了用户直接访问数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据

  • 5.2 缓存雪崩
    408:请求超时
  • 场景:数据库服务器崩溃,以下场景随之而来
  1. 系统在平稳过程中,突然数据库的连接量激增
  2. 导致WebServic服务器崩溃,请求无法及时处理
  3. 返回用户408,500等错误页面
  4. 客户反复刷新页面
  5. 数据库服务器崩溃
  6. 应用服务器崩溃
  7. 重启应用服务器无效
  8. Redis服务器崩溃
  9. Redis集群崩溃
  10. 重启数据库后再次被瞬间流量倒放
  • 问题产生的原因:短时间范围内,大量的Key集中过期
  1. 在一个相对较少的时间内,Redis存在大量过期的key
  2. 此时客户端请求Redis中过期的数据,Redis未命中,Redis向数据库中获取数据
  3. 数据库访问量激增,导致数据库无法及时处理
  4. Redis中大量请求被积压,不能处理,响应出现超时现象
  5. 数据库访问量激增,数据库崩溃
  6. 重启后Redis中仍无数据可用
  7. Redis服务器资源被严重占用,Redis服务器崩溃
  8. Redis集群崩溃
  9. 应用服务器无法接收到数据的响应,来自客户端的请求数量越来越多,应用服务器崩溃,大量408 500 爆出
  10. Redis,应用服务器,数据库重启,效果不理想
  • 解决方案:
  1. LRU与LFU切换
    通过数据淘汰策略,清除Redis中不常用或用的次数少的数据
    LRU可以在这种情况下有效地淘汰那些最久没有被访问的失效缓存项,从而释放资源,避免进一步的雪崩
    LFU可以在这种情况下有效地淘汰那些低访问频率的缓存项,从而降低它们对系统资源的占用,使高频访问的数据能够获得更好的响应时间。
  2. 数据有效策略调整
    根据业务数据的有效期进行分类错峰,比如买手机类90分钟,食品类80分钟,化妆品类70分钟
    将过期时间设置为固定时间+随机时间,稀释集中到期的key的数量,避免过期的key集中
  3. 超热数据永久key
    对于相对来说很热门的业务数据,我们将key设置为永久状态,这样客户端访问时,不会造成key过期的现象
  4. 定期维护(自动+人工)
    对即将过期的数据做访问量分析,确认是否延时,配合访问量统计,做热点数据的延时
  5. 加锁(慎用)
  • 5.3 缓存击穿
  • 场景:
    数据库服务器崩溃,但是跟之前的场景有点不一样
  1. 系统平稳运行过程中
  2. 数据库连接量瞬间激增
  3. Redis服务器中无大量key过期
  4. Redis内存平稳,无波动
  5. Redis服务器CPU正常
  6. 数据库崩溃
  • 问题产生的原因:
  1. Redis中某个key过期,且访问该key的数据量过大
  2. 多个数据请求从服务器直接压到Redis中,均未命中
  3. Redis在短时间内发起了大量对数据库中同一数据的访问

总结:单个key访问量过大,且key过期

  • 解决方案:
  1. 预先设定
    通俗点说就是延长key的过期时间。比如:商家的主打商品,在购物期间,加大此类信息key的过期时长。
    注意:购物节不仅仅指当天,包括后续若干天,访问值呈逐渐降低
  2. 现场调整
    现场进行检测,对流量激增的数据设置延长过期时间或设置永久key
  3. 后台刷新数据
    启动定时服务,高峰期来临之前,刷新数据有效期,确保不丢失
  4. 二级缓存
    设置不同的失效时间,保障不会被同时淘汰就行
  5. 加锁
    分布式锁,防止被击穿,但是要注意性能瓶颈,慎用

总结:缓存击穿就是单个高热数据过期的瞬间,访问量过大,未命中Redis,直接访问数据库,导致数据库压力过大,造成数据库系统的崩溃

  • 5.4 缓存穿透
  • 场景:
    数据库崩溃,但和其他场景不一样
  1. 系统平稳运行过程中
  2. 应用服务器流量随时间逐渐增大
  3. Redis的命中率随时间逐渐降低
  4. Redis内存平稳,无压力
  5. Redis服务器CPU占用激增
  6. 数据库服务器压力激增
  7. 数据库崩溃
  • 问题排查:
  1. Redis中大面积出现未命中
  2. 出现非正常的URL访问
  • 问题分析:
  1. 获取的数据在数据库中也不存在,数据库查询未得到对应数据
  2. Redis获取到null数据未进行持久化,直接返回
  3. 下次此类数据到达重复上述过程
  4. 出现黑客服务器
  • 解决方案:
  1. 缓存null
    对查询结果为null的数据进行缓存(长期使用,定期清理),设定短时限,例如30-60秒,最高5分钟
  2. 白名单策略
    提前预热各种分类数据id对应的bitmaps,id作为bitmaps的offset,相当于设置了数据白名单。当加
    载正常数据时放行,加载异常数据时直接拦截(效率偏低)
    使用布隆过滤器(有关布隆过滤器的命中问题对当前状况可以忽略)
  3. 实施监控
    实时监控redis命中率(业务正常范围时,通常会有一个波动值)与null数据的占比
    非活动时段波动:通常检测3-5倍,超过5倍纳入重点排查对象
    活动时段波动:通常检测10-50倍,超过50倍纳入重点排查对象
    根据倍数不同,启动不同的排查流程。然后使用黑名单进行防控(运营)
  4. key加密
    问题出现后,临时启动防灾业务key,对key进行业务层传输加密服务,设定校验程序,过来的key校验。例如每天随机分配60个加密串,挑选2到3个,混淆到页面数据id中,发现访问key不满足规则,驳回数据访问