• Redis详解(7)--主从复制


    Redis详解(7)--主从复制

    前面介绍Redis,我们都在一台服务器上进行操作的,也就是说读和写以及备份操作都是在一台Redis服务器上进行的,那么随着项目访问量的增加,对Redis服务器的操作也越加频繁,虽然Redis读写速度都很快,但是一定程度上也会造成一定的延时,那么为了解决访问量大的问题,通常会采取的一种方式是主从架构Master/SlaveMaster以写为主,Slave 以读为主Master 主节点更新后根据配置,自动同步到从机Slave 节点。

    接下来我们就来介绍如何进行主从架构的搭建。

    ps:这里我是在一台机器上模拟多个Redis服务器,与实际生产环境中相比,基本配置都是一样,仅仅是IP地址和端口号变化。

    1120165-20180609091604246-1031058549


    修改配置文件

    首先将redis.conf 配置文件复制三份,通过修改端口分别模拟三台Redis服务器。

    1120165-20180609085725666-1104732076

    然后我们分别对这三个redis.conf 文件进行修改。

    1. 修改 daemonize yes

      1120165-20180609091855397-2067943530

      表示指定Redis以守护进程的方式启动(后台启动)

    2. 配置PID文件路径 pidfile

      1120165-20180609092154310-1305076236

      表示当redis作为守护进程运行的时候,它会把 pid 默认写到 /var/redis/run/redis_6379.pid 文件里面

    3. 配置端口 port

      1120165-20180609092445295-1994256190

    4. 配置log 文件名字

      1120165-20180609092701160-1155649756

    5. 配置rdb文件名

      1120165-20180609092830634-1425851330

    依次将 6380redis.conf 、6381redis.conf 配置一次,则配置完毕。

    接下来我们分别启动这三个服务。

    1120165-20180609093944771-2019394726

    通过命令查看Redis是否启动:

    1120165-20180609094017041-86471770

    接下来通过如下命令分别进入到这三个Redis客户端:

    redis-cli -p 6379
    redis-cli -p 6380
    redis-cli -p 6381
    

    设置主从关系

    1. 通过 info replication 命令查看节点角色

      1120165-20180609101412335-153915154

      1120165-20180609101437538-230419038

      1120165-20180609101524636-615003527

      我们发现这三个节点都是扮演的 Master 角色。那么如何将 6380 和 6381 节点变为 Slave 角色呢?

    2. 选择6380端口和6381端口,执行命令:SLAVEOF 127.0.0.1 6379

      1120165-20180609101856672-864209230

      1120165-20180609101929567-1129365566

      我们再看 6379 节点信息:

      1120165-20180609102748989-1069185503

    这里通过命令来设置主从关系,一旦服务重启,那么角色关系将不复存在。想要永久的保存这种关系,可以通过配置redis.conf 文件来配置。

    slaveof 127.0.0.1 6379
    

    测试主从关系

    1. 增量复制

      主节点执行 set k1 v1 命令,从节点 get k1 能获取吗?

      1120165-20180609103015550-1540768100

      1120165-20180609103025375-1770149870

      1120165-20180609103035826-1776357162

      由上图可知是可以获取的。

    2. 全量复制

      通过执行 SLAVEOF 127.0.0.1 6379,如果主节点 6379 以前还存在一些 key,那么执行命令之后,从节点会将以前的信息也都复制过来吗?答案也是肯定的

    3. 主从读写分离

      主节点能够执行写命令,从节点能够执行写命令吗?

      1120165-20180609103401928-2080123469

      这里的原因是在配置文件 6381redis.conf 中对于 slave-read-only 的配置

      1120165-20180609103517626-624965587

      如果我们将其修改为 no 之后,执行写命令是可以的。

      1120165-20180609103818134-1183260636

      但是从节点写命令的数据从节点或者主节点都不能获取的。

    4. 主节点宕机

      主节点 Maste 挂掉,两个从节点角色会发生变化吗?

      1120165-20180609103955833-743445340

      1120165-20180609104125503-425233081

      上图可知主节点 Master 挂掉之后,从节点角色还是不会改变的。

    5. 主节点宕机后恢复

      主节点Master挂掉之后,马上启动主机Maste,主节点扮演的角色还是 Master 吗?

      1120165-20180609104846730-1063167999

      也就是说主节点挂掉之后重启,又恢复了主节点的角色。


    哨兵模式

    通过前面的配置,主节点Master 只有一个,一旦主节点挂掉之后,从节点没法担起主节点的任务,那么整个系统也无法运行。如果主节点挂掉之后,从节点能够自动变成主节点,那么问题就解决了,于是哨兵模式诞生了。

    哨兵模式就是不时地监控redis是否按照预期良好地运行(至少是保证主节点是存在的),若一台主机出现问题时,哨兵会自动将该主机下的某一个从机设置为新的主机,并让其他从机和新主机建立主从关系。

    Redis-Sentinel是redis官方推荐的高可用性解决方案,
    当用redis作master-slave的高可用时,如果master本身宕机,redis本身或者客户端都没有实现主从切换的功能。
    
    而redis-sentinel就是一个独立运行的进程,用于监控多个master-slave集群,
    自动发现master宕机,进行自动切换slave > master。
    

    1120165-20180609120427138-1351876841

    sentinel主要功能如下:

    • 不时的监控redis是否良好运行,如果节点不可达就会对节点进行下线标识
    • 如果被标识的是主节点,sentinel就会和其他的sentinel节点“协商”,如果其他节点也人为主节点不可达,就会选举一个sentinel节点来完成自动故障转义
    • 在master-slave进行切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换

    Redis Sentinel架构:

    redis的一个进程,但是不存储数据,只是监控redis

    1132884-20181124181822218-1125753774

    1132884-20180928115711245-1503702880

    1132884-20180928145626051-1360651849

    1132884-20180928145734973-1288883859

    哨兵模式搭建步骤:

    1. 在配置文件目录下新建 sentinel.conf 文件,名字绝不能错,然后配置相应内容

      1120165-20180609114532397-1341362330

      sentinel monitor 被监控机器的名字(自己起名字) ip地址 端口号 得票数
      

      1120165-20180609115554622-767506410

      分别配置被监控的名字,ip地址,端口号,以及得票数。上面的得票数为1表示表示主机挂掉后salve投票看谁接替成为主机,得票数大于1便成为主机

    2. 启动哨兵

      redis-sentinel /etc/redis/sentinel.conf
      

      启动界面:

    1120165-20180609115644617-2138551559

    接下来,我们干掉主机 6379,然后看从节点有啥变化

    1120165-20180609115951576-1912696729

    干掉主节点之后,我们查看后台打印日志,发现 6381投票变为主节点了

    1120165-20180609115939823-1544997489

    这时候我们查看从节点 6381的节点信息:

    1120165-20180609120102216-1580070378

    6381 节点自动变为主节点了。

    PS:哨兵模式也存在单点故障问题,如果哨兵机器挂了,那么就无法进行监控了,解决办法是哨兵也建立集群,Redis哨兵模式是支持集群的。


    主从复制原理

    Redis的复制功能分为同步(sync)命令传播(command propagate)两个操作。

    1. 旧版同步

      当从节点发出 SLAVEOF 命令,要求从服务器复制主服务器时,从服务器通过向主服务器发送 SYNC 命令来完成。该命令执行步骤:

      1. 从服务器向主服务器发送 SYNC 命令
      2. 收到 SYNC 命令的主服务器执行 BGSAVE 命令,在后台生成一个 RDB 文件,并使用一个缓冲区记录从开始执行的所有写命令
      3. 当主服务器的 BGSAVE 命令执行完毕时,主服务器会将 BGSAVE 命令生成的 RDB 文件发送给从服务器,从服务器接收此 RDB 文件,并将服务器状态更新为RDB文件记录的状态
      4. 主服务器将缓冲区的所有写命令也发送给从服务器,从服务器执行相应命令
    2. 命令传播

      当同步操作完成之后,主服务器会进行相应的修改命令,这时候从服务器和主服务器状态就会不一致。

      为了让主服务器和从服务器保持状态一致,主服务器需要对从服务器执行命令传播操作,主服务器会将自己的写命令发送给从服务器执行。从服务器执行相应的命令之后,主从服务器状态继续保持一致。

    总结:通过同步操作以及命令传播功能,能够很好的保证了主从一致的特性。

    但是我们考虑一个问题,如果从服务器在同步主服务器期间,突然断开了连接,而这时候主服务器进行了一些写操作,这时候从服务器恢复连接,如果我们在进行同步,那么就必须将主服务器从新生成一个RDB文件,然后给从服务器加载,这样虽然能够保证一致性,但是其实断开连接之前主从服务器状态是保持一致的,不一致的是从服务器断开连接,而主服务器执行了一些写命令,那么从服务器恢复连接后能不能只要断开连接的哪些写命令,而不是整个RDB快照呢?

    同步操作其实是一个非常耗时的操作,主服务器需要先通过 BGSAVE 命令来生成一个 RDB 文件,然后需要将该文件发送给从服务器,从服务器接收该文件之后,接着加载该文件,并且加载期间,从服务器是无法处理其他命令的。

    为了解决这个问题,Redis从2.8版本之后,使用了新的同步命令 PSYNC 来代替 SYNC 命令。该命令的部分重同步功能用于处理断线后重复制的效率问题。也就是说当从服务器在断线后重新连接主服务器时,主服务器只将断开连接后执行的写命令发送给从服务器,从服务器只需要接收并执行这些写命令即可保持主从一致。


    主从复制的缺点

    主从复制虽然解决了主节点的单点故障问题,但是由于所有的写操作都是在 Master 节点上操作,然后同步到Slave 节点,那么同步就会有一定的延时,当系统很繁忙的时候,延时问题就会更加严重,而且会随着从节点slave的增多而愈加严重。

  • 相关阅读:
    关联分析(Association analysis)
    Django简介
    YAML快速入门
    YAML 在Python中的应用
    抓包工具、日誌抓取、弱網測試
    实现轮询
    Dubbo-从入门到深入
    Spring Boot
    小程序自动生成图片的标签
    小程序上传图片的大坑
  • 原文地址:https://www.cnblogs.com/pankypan/p/11149942.html
Copyright © 2020-2023  润新知