【redis】redis哨兵、集群、应用问题的简述

redis主从复制的原理

和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步增量同步

全量同步

Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。

例如:Slave宕机后,重启之后他从Slave变成了单机的Master,当把他再次设置为Slave时,需要重头复制主机的内容
补充:当Master宕机,重启之后还是Master,Slave还是Slave, 不受Master宕机的影响

步骤:

  1. 从服务器连接主服务器,发送SYNC命令;
  2. 主服务器接收到SYNC命名后,开始执行bgsave命令生成RDB文件 (持久化操作)并使用缓冲区记录此后执行的所有写命令
  3. 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
  4. 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
  5. 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
  6. 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

增量同步

增量复制的过程:Master每执行一个写命令就会向Slave发送相同的写命令,从服务器接收并执行收到的写命令。

主从模式缺点:

从上面可以看出,master节点在主从模式中唯一,若master挂掉,则redis无法对外提供写服务


哨兵模式

概念

假如Master宕机了,redis本身(以及其很多客户端)都没有实现自动进行主备切换,需要写命令设置新的Master服务,哨兵是一个独立的进程,作为进程,它会独立运行。

其特点是:

  • 哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。发现Master宕机立即 自动选举新的Master
  • 当上一任Master重启时,他会从Master变成Slave (与主从模式不同
  • sentinel最好不要和Redis部署在同一台机器,不然Redis的服务器挂了以后,sentinel也挂了

哨兵模式监控原理

  1. 每个Sentinel以 每秒钟 一次的频率,向它 所有的主服务器、从服务器以及其他Sentinel实例 发送一个 PING命令

  2. 如果一个 实例(instance)距离最后一次有效回复 PING命令的时间超过 down-after-milliseconds 所指定的值,那么这个实例会被 Sentinel标记为 主观下线

  3. 如果一个主服务器被标记为主观下线,那么正在监视这个主服务器的所有 Sentinel 节点,要以每秒一次的频率确认该主服务器是否的确进入了主观下线
    并且有足够数量的 Sentinel(至少要达到配置文件指定的数量)在指定的 时间范围内同意这一判断,那么这个该主服务器被标记为 客观下线

  4. 当没有 足够数量的 Sentinel 同意 主服务器下线时, 主服务器的 客观下线 状态就会被 移除
    主服务器重新向 Sentinel的PING命令返回有效回复 时,主服务器的 主观下线 状态就会被 移除

  5. 在一般情况下, 每个 Sentinel会以每10秒一次的频率,向它已知的所有 主服务器 和 从服务器 发送 INFO 命令
    当一个 主服务器被 Sentinel标记为 客观下线 时,Sentinel向下线主服务器的所有从服务器发送 INFO 命令的频率,会从10秒一次改为每秒一次。
    Sentinel和其他 Sentinel 协商 主节点的状态,如果 主节点处于 SDOWN状态,则投票自动选出新的主节点。所有从节点 指向 新的主节点 进行 数据复制


redis集群

当数据量过大到一台服务器存放不下的情况时,主从模式或sentinel模式就不能满足需求了,这个时候需要对存储的数据进行分片,将数据存储到多个Redis实例中。cluster模式的出现就是为了解决单机Redis容量有限的问题,将Redis的数据根据一定的规则分配到多台机器。
分配集群的原则:尽量保证每个主数据库、每个Mseter、Slave运行在不同的IP地址 (避免服务器挂掉,整个redis集群全军覆没)

cluster集群特点:

  • 多个redis节点网络互联,数据共享
  • 客户端可以连接任何一个主节点进行读写(各个节点可相互访问)
  • 所有的节点都是一主一从(也可以是一主多从),其中Slave不提供服务,仅作为备用
  • 支持在线增加、删除节点
  • 不支持同时处理多个key(如MSET/MGET),因为redis需要把key均匀分布在各个节点上(插槽),
    并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为
    插槽(redis插槽:0~16383个):集群中的多个master都会平均分配到一个插槽范围值,set时根据key去计算得出一个插槽数值,插槽数值在哪个redis范围中,就插入相应的redis服务
  • 优点:实现扩容,分摊压力,配置相对简单
    缺点: 多键操作、多键的redis事务、lua脚本不被支持

缓存穿透

场景: 非法的url,或者频繁使用 一个不存在的key去查询数据。
导致原因: 出于容错考虑,如果存储层查不到数据 则不写入缓存,这将导致这个不存在 的数据每次都要到存储层去查询,失去了缓存的意义。
解决方案:

  1. 对空值缓存 并设置过期时间最长不超过五分钟(不推荐)
  2. 设置白名单:使用bitMaps(redis新类型)类型定义一个可访问名单
  3. 采用布隆过滤器
  4. 进行实时监控,当监控到网址的命中率开始急速降低时,和运维人员配合 设置当前服务到黑名单

缓存击穿

导致原因: 大量并发时,redis的 某个key过期,但是还在大量访问这个key,导致数据库访问压力瞬时增加。
解决方案:

  1. 预先设置热门数据,并加长过期时间
  2. 使用锁:在缓存失效时 先判断拿出来的值是否为空,设置排它锁

缓存雪崩

导致原因: 数据库压力变大,在极少时间段,查询 大量key集中过期 情况
解决方案:

  1. 设置过期标志更新缓存,当key即将过期时,后台去更新实际key的缓存
  2. 将缓存失效时间分散开,这样每一个缓存的过期时间的重复率将会降低,就很难引发集体失效的事件

分布式锁

由于分布式系统多线程、多进程并且分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效。为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问。

// 常见设置锁的命令
 set [key] [val] nx ex [过期时间]
// nx : 当前key加锁,此时不释放锁,不能再对key进行操作
// ex : 当前key过期时间(自动释放)   不设置过期时间,只能手动 【del key释放锁】 

//------- UUID 使用场景 --------
  1.假设a,b两个服务竞争redis锁
  2.a获取锁,并且设置过期时间10s 
  4.a开始进行业务逻辑操作,中间服务卡顿导致延迟
  5.延迟时间超长,key已经超过10s 自动释放
  6.b此时看见a释放锁,b获取到锁  开始进行逻辑操作
  7.此时a服务恢复 完成业务操作 手动释放锁 *因为a、b的key是一样的 此时del删除的是b的锁(误删)*
  8.使用uuid作为val,释放锁时,先判断当前uuid和要释放锁uuid是否一样 防止误删
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值