Redis主从/哨兵模式/codis

1.1主从同步

  • redis主从同步介绍
  1. 和MySQL主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。

  2. 为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构。

  3. Redis主从复制可以根据是否是全量分为全量同步和增量同步。

    :redis主节点Master挂掉时,运维让从节点Slave接管(redis主从默认无法自动切换,需要运维手动切换)
    在这里插入图片描述

  • RDB全量同步(快照同步)

    • redis把磁盘中原有数据全部丢弃,然后把redis内存中数据全部重新写入磁盘(每隔一定时间给内存照一个快照,将内存中的数据写入文件(rdb文件))
      :Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下
      • 从服务器连接主服务器,发送SYNC命令;
      • 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
      • 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
      • 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
      • 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
      • 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
      • 完成上面几个步骤后就完成了从服务器数据初始化的所有操作,从服务器此时可以接收来自用户的读请求。
        在这里插入图片描述
    • 缺点
      • 会丢失数据(当磁盘数据丢弃,正在写入时如果出现故障会导致数据丢失)
    • 优点
      • 整个Redis数据库将只包含一个文件,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。
      • 性能最大化,它仅需要fork出子进程,由子进程完成持久化工作,极大的避免服务进程执行IO操作了。
  • AOF增量同步

  1. 主节点会将那些对自己状态产生修改性影响的指令记录在本地内存buffer中,然后异步将buffer中指令同步到从节点

  2. 从节点一边执行同步指令达到主节点状态,一边向主节点反馈自己同步到哪里(偏移量)

  3. 当网络状态不好时,从节点无法和主节点进行同步,当网络恢复时需要进行快照同步

    • 缺点
      • 对于相同数量的数据集而言,AOF文件通常要大于RDB文件,RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
      • OF在运行效率上往往会慢于RDB
    • 优点 :
      • 数据安全性高,Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步
  • Redis主从同步策略
  1. 主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。

  2. 当然,如果有需要,slave 在任何时候都可以发起全量同步。

  3. redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

  • 注意点
  1. 如果多个Slave断线了,需要重启的时候,因为只要Slave启动,就会发送sync请求和主机全量同步,当多个同时出现的时候,可能会导致Master IO剧增宕机。

1.2 哨兵模式----sentinel

  • sentinel作用

    • 当用Redis做主从方案时,假如master宕机,Redis本身无法自动进行主备切换

    • 而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。

  • sentinel原理

  1. sentinel负责持续监控主节点的健康,当主节挂掉时,自动选择一个最优的从节点切换成主节点
  2. 从节点来连接集群时会首先连接sentinel,通过sentinel来查询主节点的地址
  3. 当主节点发生故障时,sentinel会将最新的主节点地址告诉客户端,可以实现无需重启自动切换redis
  • Sentinel支持集群
  1. 只使用单个sentinel进程来监控redis集群是不可靠的,当sentinel进程宕掉后sentinel本身也有单点问题

  2. 如果有多个sentinel,redis的客户端可以随意地连接任意一个sentinel来获得关于redis集群中的信息。

  • 运行sentinel两种方式(效果相同)
    法1redis-sentinel /path/to/sentinel.conf
    法2redis-server /path/to/sentinel.conf --sentinel
  1. 以上两种方式,都必须指定一个sentinel的配置文件sentinel.conf,如果不指定,将无法启动sentinel。

  2. sentinel默认监听26379端口,所以运行前必须确定该端口没有被别的进程占用。

  • sentinel.conf配置文件说明
  1. 配置文件只需要配置master的信息就好啦,不用配置slave的信息,因为slave能够被自动检测到

  2. 需要注意的是,配置文件在sentinel运行期间是会被动态修改的,例如当发生主备切换时候,配置文件中的master会被修改为另外一个slave。

  3. 这样,之后sentinel如果重启时,就可以根据这个配置来恢复其之前所监控的redis集群的状态。

# sentinel.conf 配置说明
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
  • sentinel.conf配置文件注释

'''1、sentinel monitor mymaster 127.0.0.1 6379 2'''
#1)sentinel监控的master的名字叫做mymaster,地址为127.0.0.1:6379
#2)当集群中有2个sentinel认为master死了时,才能真正认为该master已经不可用了

'''2、sentinel down-after-milliseconds mymaster 60000'''
#1)sentinel会向master发送心跳PING来确认master是否存活,如果master在60000毫秒内不回应PONG 
#2)那么这个sentinel会单方面地认为这个master已经不可用了

'''3、sentinel failover-timeout mymaster 180000'''
#1)如果sentinel A推荐sentinel B去执行failover,B会等待一段时间后,自行再次去对同一个master执行failover,
#2)这个等待的时间是通过failover-timeout配置项去配置的。
#3)从这个规则可以看出,sentinel集群中的sentinel不会再同一时刻并发去failover同一个master,
#4)第一个进行failover的sentinel如果失败了,另外一个将会在一定时间内进行重新进行failover,以此类推。

'''4、sentinel parallel-syncs mymaster 1'''
#1)在发生failover主备切换时,这个选项指定了最多可以有多少个slave同时对新的master进行同步
#2)如果这个数字越大,就意味着越多的slave因为replication而不可用,这个数字越小,完成failover所需的时间就越长。
#3)可以通过将这个值设为 1 来保证每次只有一个slave处于不能处理命令请求的状态。

1.3 codis

  • 为什么会出现codis
  1. 在大数据高并发场景下,单个redis实例往往会无法应对

  2. 首先redis内存不易过大,内存太大会导致rdb文件过大,导致主从同步时间过长

  3. 其次在CPU利用率中上,单个redis实例只能利用单核,数据量太大,压力就会特别大

  • 什么是codis
  1. codis是redis集群解决方案之一,codis是GO语言开发的代理中间件

  2. 当客户端向codis发送指令时,codis负责将指令转发给后面的redis实例来执行,并将返回结果转发给客户端

  • codis部署方案
  1. 单个codis代理支撑的QPS比较有限,通过启动多个codis代理可以显著增加整体QPS

  2. 多codis还能起到容灾功能,挂掉一个codis代理还有很多codis代理可以继续服务
    在这里插入图片描述

  • codis分片的原理
  1. codis负责将特定key转发到特定redis实例,codis默认将所有key划分为1024个槽位

  2. 首先会对客户端传来的key进行crc32计算hash值,然后将hash后的整数值对1024进行取模,这个余数就是对应的key槽位

  3. 每个槽位都会唯一映射到后面的多个redis实例之一,codis会在内存中维护槽位和redis实例的映射关系

  4. 这样有了上面key对应的槽位,那么它应该转发到那个redis实例就很明确了

  5. 槽位数量默认是1024,如果集群中节点较多,建议将这个数值大一些,比如2048,4096

  • 不同codis槽位如何同步
  1. 如果codis槽位值存在内存中,那么不同的codis实例间的槽位关系得不到同步

  2. 所以codis还需要一个分布式配置存储的数据库专门来持久化槽位关系

  3. codis将槽位关系存储在zookeeper中,并且提供一个dashboard可以来观察和修改槽位关系

发布了48 篇原创文章 · 获赞 17 · 访问量 4477

猜你喜欢

转载自blog.csdn.net/Hanmin_hm/article/details/105029829