Redis入门第五天

Redis入门第五天:主要介绍了Redis哨兵机制以及Redis Cluster集群和缓存穿透、缓存击穿、缓存雪崩

Redis

Redis Sentinel哨兵机制

简介

​ Sentinel(哨兵)进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用,其已经被集成在redis2.6+的版本中,Redis的哨兵模式到2.8版本之后就稳定了下来。

哨兵进程的作用

  • 监控:哨兵(Sentinel)会不断地检查你的Master和Slave是否运作正常。
  • 提醒:当被监控的某个Redis节点出现问题时,哨兵(Sentinel)可以通过API向管理员或者其他应用程序发送通知。
  • 自动故障迁移:当一个Master不能正常工作时,哨兵(Sentinel)会开始一次自动故障迁移操作。
    • 它会将失效Master的其中一个Slave升级为新的Master,并让失效Master的其他Slave改为复制新的Master;
    • 当客户端视图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效的Master。
    • Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即Master主服务器的redis.conf配置文件中会多一行Slave的配置,sentinel.conf的监控目标会随之调换。

哨兵进程的工作方式

  • 每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器Slave从服务器以及其他Sentinel(哨兵)进程发送一个PING命令
  • 如果一个实例(instance)距离最后一次有效回复PING命令的时间超过down-after-milliseconds选项所指定的值,则这个实例会被Sentinel(哨兵)进程标记为主观下线(SDOWN)。
  • 如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器确实进入主观下线状态
  • 当有足够数量的Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN),则Master主服务器会被标记为客观下线(ODOWN)
  • 在一般情况下,每个Sentinel(哨兵)进程会以每10秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送INFO命令。
  • 当Master主服务器被Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的Master主服务器的所有Slave从服务器发送INFO命令的频率会从10秒一次改为每秒一次。
  • 若没有足够数量的Sentinel(哨兵)进程同意Master主服务器下线,Master主服务器的客观下线状态就会被移除。若Master主服务器重新向Sentinel(哨兵)进程发送PING命令返回有效回复,Master主服务器的主观下线状态就会被移除。

实现

修改从机的sentinel.conf
sentinel monitor mymaster  192.168.127.129 6379 1
启动哨兵服务器
redis-sentinel

Redis Cluster集群

redis-cluster框架图

框架细节

  • 所有的redis节点彼此互联(PING-PING机制),内部使用二进制协议优化传输速度和带宽

  • 节点的fail是通过集群中超过半数的几点检测失效时才生效

  • 客户端与redis节点直连,不需要中间proxy层,客户端不需要连接集群所有节点。连接集群中任何一个可用节点即可

  • redis-cluster把所有的物理节点映射到【0-16383】slot上,cluster负责维护node<->slot<->value

    ​ Redis集群中内置了16385个哈希值,当需要在Redis群中放置一个key-value时,redis先对key使用crc16算法算出一个结果,然后把结果对16384求余数,这样每个key都会对应一个编号在0-16384之间的哈希槽,redis会根据节点数量大致均等的将哈希槽映射到不同节点。

redios-cluster投票:容错

  • 集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超过(cluster-node-timeout),认为该master节点挂掉。
  • 什么时候整个集群不可用(cluster_state:fail)?
    • 如果集群任意master挂掉,且当前master没有slave,则集群进入fail状态。也可以理解成集群的[0-16384]slot映射不完全时进入fail状态。
    • 如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态。

缓存穿透、缓存击穿、缓存雪崩

缓存数据步骤

  • 查询缓存,如果没有数据,则查询数据库
  • 查询数据库,如果数据不为空,就将结果写入缓存

缓存穿透

介绍

​ 一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查询。如果key对应的value是一定不存在的,并且对key并发请求量很大,就会对后端系统造成很大的压力,这就叫做缓存穿透。

解决
  • 对于查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对象的数据insert了以后再清楚缓存
  • 对于一定不存在的key进行过滤。可以把所有的可能存在的key放在一个大的Bitmap中,查询时通过该Bitmap过滤(布隆表达式)

缓存雪崩

介绍(很多key)

​ 当缓存服务器重启或者大量缓存集中中某一时间段失效,这样在失效的时候,也会给后端系统带来很大的压力

解决
  • 缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待
  • 不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀
  • 做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期

缓存击穿

介绍(一个key)

​ 对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,这个时候就需要缓存被击穿的问题。

​ 缓存在某个时间点过期的时候,恰在这个时间点对这个key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会把后端DB压垮

解决

​ 使用redis的setnx互斥锁先进行判断,这样其他线程就处于等待状态,保证不会有大并发操作去操作数据库

if(redis.setnx()=1){
    //查询数据
    //加入线程
  
}
发布了47 篇原创文章 · 获赞 35 · 访问量 3233

猜你喜欢

转载自blog.csdn.net/issunmingzhi/article/details/103985168