zoukankan      html  css  js  c++  java
  • redis-07主从复制

    转 https://www.jianshu.com/p/06ab9daf921d https://www.jianshu.com/p/06ab9daf921d

    1.基本说明

      我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slver机制,Master以写为主,Slave以读为主。读写分离,容灾恢复。

    2.结构说明

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

    3.全量同步
    Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下: 
    -  从服务器连接主服务器,发送SYNC命令; 
    -  主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令; 
    -  主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令; 
    -  从服务器收到快照文件后丢弃所有旧数据,载入收到的快照; 
    -  主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令; 
    -  从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

    完成上面几个步骤后就完成了从服务器数据初始化的所有操作,从服务器此时可以接收来自用户的读请求。

    4.增量同步
    Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 
    增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
     
    5.Redis主从同步策略
    主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
     
    6.注意点
    如果多个Slave断线了,需要重启的时候,因为只要Slave启动,就会发送sync请求和主机全量同步,当多个同时出现的时候,可能会导致Master IO剧增宕机。

    Redis主从复制的配置十分简单,它可以使从服务器是主服务器的完全拷贝。需要清除Redis主从复制的几点重要内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    1)Redis使用异步复制。
    2)一个主服务器可以有多个从服务器。
    3)从服务器也可以接受其他从服务器的连接。除了多个从服务器连接到一个主服务器之外,多个从服务器也可以连接到一个从服务器上,形成一个
       图状结构。
    4)Redis主从复制不阻塞主服务器端。也就是说当若干个从服务器在进行初始同步时,主服务器仍然可以处理请求。
    5)主从复制也不阻塞从服务器端。当从服务器进行初始同步时,它使用旧版本的数据来应对查询请求,假设你在redis.conf配置文件是这么配置的。
       否则的话,你可以配置当复制流关闭时让从服务器给客户端返回一个错误。但是,当初始同步完成后,需要删除旧的数据集和加载新的数据集,在
       这个短暂的时间内,从服务器会阻塞连接进来的请求。
    6)主从复制可以用来增强扩展性,使用多个从服务器来处理只读的请求(比如,繁重的排序操作可以放到从服务器去做),也可以简单的用来做数据冗余。

     

       

    7.全量同步和部分同步

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    全量同步:
    master服务器会开启一个后台进程用于将redis中的数据生成一个rdb文件,与此同时,服务器会缓存所有接收到的来自客户端的写命令(包含增、删、改),当后台保存进程
    处理完毕后,会将该rdb文件传递给slave服务器,而slave服务器会将rdb文件保存在磁盘并通过读取该文件将数据加载到内存,在此之后master服务器会将在此期间缓存的
    命令通过redis传输协议发送给slave服务器,然后slave服务器将这些命令依次作用于自己本地的数据集上最终达到数据的一致性。
     
    部分同步:
    即使主从连接中途断掉,也不需要进行全量同步。部分同步的实现依赖于在master服务器内存中给每个slave服务器维护了
    一份同步日志和同步标识,每个slave服务器在跟master服务器进行同步时都会携带自己的同步标识和上次同步的最后位置。当主从连接断掉之后,slave服务器隔断时间
    (默认1s)主动尝试和master服务器进行连接,如果从服务器携带的偏移量标识还在master服务器上的同步备份日志中,那么就从slave发送的偏移量开始继续上次的同步
    操作,如果slave发送的偏移量已经不再master的同步备份日志中(可能由于主从之间断掉的时间比较长或者在断掉的短暂时间内master服务器接收到大量的写操作),则
    必须进行一次全量更新。在部分同步过程中,master会将本地记录的同步备份日志中记录的指令依次发送给slave服务器从而达到数据一致。

    8.主从同步中需要注意几个问题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    1)在上面的全量同步过程中,master会将数据保存在rdb文件中然后发送给slave服务器,但是如果master上的磁盘空间有限怎么办呢?那么此时全部同步对于master来说
    将是一份十分有压力的操作了。此时可以通过无盘复制来达到目的,由master直接开启一个socket将rdb文件发送给slave服务器。(无盘复制一般应用在磁盘空间有限但是网
    络状态良好的情况下)
     
    2)主从复制结构,一般slave服务器不能进行写操作,但是这不是死的,之所以这样是为了更容易的保证主和各个从之间数据的一致性,如果slave服务器上数据进行了修改,那么要保证所有主从服务器都能一致,可能在结构上和处理逻辑上更为负责。不过你也可以通过配置文件让从服务器支持写操作。(不过所带来的影响还得自己承担哦。。。)
     
    3)主从服务器之间会定期进行通话,但是如果master上设置了密码,那么如果不给slave设置密码就会导致slave不能跟master进行任何操作,所以如果你的master服务器
    上有密码,那么也给slave相应的设置一下密码吧(通过设置配置文件中的masterauth);
     
    4)关于slave服务器上过期键的处理,由master服务器负责键的过期删除处理,然后将相关删除命令已数据同步的方式同步给slave服务器,slave服务器根据删除命令删除
    本地的key。

     

     

    9.复制偏移量:master_repl_offset | slave_repl_offset

     

    主节点每次处理完写操作,会把命令的字节长度累加到master_repl_offset中。

     

    从节点在接收到主节点发送的命令后,会累加记录子节点偏移量信息slave_repl_offset,同时,也会每秒钟上报自身的复制偏移量到主节点,以供主节点记录存储。

     

    在实际应用中,可以通过对比主从复制偏移量信息来监控主从复制健康状况

     

    10.当主服务器不进行持久化时复制的安全性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    在进行主从复制设置时,强烈建议在主服务器上开启持久化,当不能这么做时,比如考虑到延迟的问题,应该将实例配置为避免自动重启。
     
    为什么不持久化的主服务器自动重启非常危险呢?
    为了更好的理解这个问题,看下面这个失败的例子,其中主服务器和从服务器中数据库都被删除了。
     
    设置节点A为主服务器,关闭持久化,节点B和C从节点A复制数据。
    这时出现了一个崩溃,但Redis具有自动重启系统,重启了进程,因为关闭了持久化,节点重启后只有一个空的数据集。
    节点B和C从节点A进行复制,现在节点A是空的,所以节点B和C上的复制数据也会被删除。
    当在高可用系统中使用Redis Sentinel,关闭了主服务器的持久化,并且允许自动重启,这种情况是很危险的。
    比如主服务器可能在很短的时间就完成了重启,以至于Sentinel都无法检测到这次失败,那么上面说的这种失败的情况就发生了。
     
    如果数据比较重要,并且在使用主从复制时关闭了主服务器持久化功能的场景中,都应该禁止实例自动重启。
       
       

    11.怎么用

      如现在有两个redis,主和从

        我们只需要在从redis配置 slaveof 192.168.1.1 6379   slaveof ip 端口   如果主服务器有密码,还需要配置密码 masterauth 密码

        如果不使用哨兵模式,直接使用命令slaveof 192.168.1.1 6379这样子虽然配置了主从,如果主redis挂了,从redis可以继续工作。当主redis重新起来了,他们的主从关系不会变,这样子就会存在问题,主机挂了,从机只能读,不能写。当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。

    12.哨兵模式 

      哨兵模式概述

    哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

    Redis哨兵

    这里的哨兵有两个作用

    • 通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。

    • 当哨兵监测到master宕机,会自动将某个slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换到新的主机。

    然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

    用文字描述一下故障切换(failover)的过程。假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作,选举出新的主机

      Redis多哨兵模式

    配置3个哨兵和1主2从的Redis服务器来演示这个过程。

    服务类型是否是主服务器IP地址端口
    Redis 192.168.11.128 6379
    Redis 192.168.11.129 6379
    Redis 192.168.11.130 6379
    Sentinel - 192.168.11.128 26379
    Sentinel - 192.168.11.129 26379
    Sentinel - 192.168.11.130 26379
      多哨兵监控Redis说明

     1) 从服务器需要配置:

      # 指定主服务器 slaveof 192.168.11.128 6379  slaveof  主redis ip + 端口

      # 主服务器密码(主服务器存在密码需要)  masterauth 123456

     2) 哨兵配置

        每个哨兵的配置都是一样的,有几个哨兵就配置sentinel.conf

        新建sentinel.conf文件,名字决不能错(或者-Redis安装目录下有一个sentinel.conf文件,copy一份进行修改)

        
        
        port 26379
        protected
    -mode no    # 禁止保护模式     sentinel monitor zhu_6379 127.0.0.1 6379 2  # 配置监听的主服务器,这里sentinel monitor代表监控,zhu_6379 代表服务器的名称,可以自定义,127.0.0.1代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作。     sentinel auth-pass zhu_6379 573875306 # 定义服务的密码,zhu_6379 是服务名称,573875306 是Redis服务器密码 sentinel auth-pass <master-name> <password>
     
      3)启动几个redis和哨兵
      # 启动Redis服务器进程 ./redis-server ../redis.conf
      # 启动哨兵进程 ./redis-sentinel ../sentinel.conf
      注意启动的顺序。首先是主机(192.168.11.128)的Redis服务进程,然后启动从机的服务进程,最后启动3个哨兵的服务进程。
     

    #Redis单哨兵模式使用实例

      主机6379不许修改配置

      redis的从机(有两个6380 和 6381)配置一样的,需要接入配置

    slaveof 127.0.0.1 6379   #主机地址
    masterauth  "admin.123"    #主机密码

       哨兵的配置,只需要一个sentinel.conf文件,配置如下  

        port 26379
        protected-mode no    # 禁止保护模式
        sentinel monitor zhu_6379 127.0.0.1 6379 1  # 配置监听的主服务器,这里sentinel monitor代表监控,zhu_6379 代表服务器的名称,可以自定义,127.0.0.1代表监控的主服务器,6379代表端口
        sentinel auth-pass zhu_6379 573875306        # 定义服务的密码,zhu_6379 是服务名称,573875306 是Redis服务器密码   sentinel auth-pass <master-name> <password>

      这里sentinel monitor zhu_6379 127.0.0.1 6379 后面是1,上面最后一个数字1,表示主机挂掉后slave投票看让谁成为主机,得票数多的成为主机

      

      然后按顺序启动主机 、 从机、哨兵  (redis-server 配置文件路径)

      

      查看角色:客户端连接redis-cli,连接成功后,输入命令role可以查看当前redis的角色

      角色切换slaveof NO ONE:redis从属服务器执行命令 SLAVEOF NO ONE 将使得这个从属服务器关闭复制功能,并从从属服务器转变回主服务器,原来同步所得的数据集不会被丢弃

     

    哨兵常用命令

    登录哨兵

    redis-cli -p 26379

    查看redis主的信息

    sentinel master larry-master        ----  sentinel master +主机名称(可以正则表达式)

     

    3、查看redis从

    sentinel slaves larry-master  --- sentinel slaves + 主机名称(可以正则表达式)

     
     
    更多Sentinel介绍:http://redisdoc.com/topic/sentinel.html 
       
       
  • 相关阅读:
    位运算
    LeetCode(230):二叉树中的第K小元素
    LeetCode(69):二分法求平方根
    TCP如何保证传输可靠性
    2种方法(递归+BFS)求二叉树的最小/最大深度
    自动生成Mapper文件(基于Mybatis Maven插件)
    Git的使用
    Java关键字及其作用详解
    Vagrant安装Centos/7
    java servlet 几种页面跳转的方法及传值
  • 原文地址:https://www.cnblogs.com/jthr/p/14500683.html
Copyright © 2011-2022 走看看