Redis的主从复制和哨兵模式

Posted Later

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis的主从复制和哨兵模式相关的知识,希望对你有一定的参考价值。

搭建主从复制

  • 简介
    主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,mester以写为主,slaver以读为主。原则上是配从不配主。

  • 搭建主从复制

    • 新建三个文件夹:redis8000、redis8001、redis8002

    • 将redis.conf复制到redis8000

    • 配置redis.conf

      	1.bind 192.168.100.110   指定本机ip
      	2.port 8000    端口
      	3.daemonize yes
      	4.pidfile /yangk/redis/redis8000/redis_8000.pid 
      	5.dir /yangk/redis/redis8000
      	6.requirepass 123456
      
    • -将8000文件里面的redis.conf复制到redis8001,redis8002

      		8001和8002都需要替换成自己的端口
      		使用  :%s/8000/8001/g    批量替换
      		    // 下面这两个是重点,不然从机无法挂到主机下面
      		replicaof 192.168.100.110 8000
      		masterauth 123456
      
    • 启动8000.8001,8002实例

      	./redis-server  ../redis8000/redis.conf 
      	
      	./redis-server  ./redis8001/redis.conf 
      	
      	./redis-server  ./redis8002/redis.conf 
      
    • 客户端连接

      		./redis-cli -h 192.168.100.110 -p 8000 -a 123456
      
      		./redis-cli -h 192.168.100.110 -p 8001 -a 123456
      
      		./redis-cli -h 192.168.100.110 -p 8002 -a 123456
      
    • info replication 查看配置
      技术图片

  • 主从复制优缺点

    • 优点

      • 同一个Master可以同步多个Slaves。
      • Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。因此我们可以将Redis的Replication架构视为图结构。
      • Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave 同步期间,客户端仍然可以提交查询或修改请求。
      • Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据
      • 为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成。即便如此,系统的伸缩性还是得到了很大的提高。
      • Master可以将数据保存操作交给Slaves完成,从而避免了在Master中要有独立的进程来完成此操作。
      • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。
    • 缺点

      • 由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。
      • 当主机宕机之后,将不能进行写操作,需要手动将从机升级为主机,从机需要重新制定master
      	slaveof no one   从机变成主机
      	slaveof 192.168.100.110 8001   从机从新指定主机
      
  • 总结

    • 一个master可以有多个Slave,一个slave只能有一个master,数据流向是单向的,只能从主到从
    • Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
    • 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
    • Redis的主从复制采用全量复制,复制过程中主机会fork出一个子进程对内存做一份快照,并将子进程的内存快照保存为文件发送给从机,这一过程需要确保主机有足够多的空余内存。若快照文件较大,对集群的服务能力会产生较大的影响,而且复制过程是在从机新加入集群或者从机和主机网络断开重连时都会进行,也就是网络波动都会造成主机和从机间的一次全量的数据复制,这对实际的系统运营造成了不小的麻烦。
    • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

Redis哨兵模式

  • 简介
    redis2.8版本之后引入的,核心功能就是主节点的自动故障转移。
    监控(Monitoring): 哨兵会不断地检查主节点和从节点是否运作正常。
    自动故障转移(Automatic Failover): 当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
    配置提供者(Configuration Provider): 客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。
    通知(Notification): 哨兵可以将故障转移的结果发送给客户端。其中,监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移;而配置提供者和通知功能,则需要在与客户端的交互中才能体现。
    哨兵节点: 哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的Redis节点,不存储数据。
    数据节点: 主节点和从节点都是数据节点。

  • 搭建哨兵模式

    • 基于主从复制搭建哨兵模式:Redsi连接密码须保持一致
      1.复制sentinel.conf
      	cp sentinel.conf ../sentinel/sentinel7000.conf
      	2.修改配置
      		bind 0.0.0.0
      		port 7000
      		daemonize yes
      		pidfile /yangk/redis/redis/sentinel/redis-sentinel7000.pid
      		logfile "sentinel7000.log"
      		dir /yangk/redis/redis/sentinel
      		//意思是要对那个主机进行监控  2:的意思是有几个哨兵认为主机挂了,那这个主机就是挂了(主观宕机)一般配置的数据是哨兵数量/2+1
      		//# sentinel monitor master-name ip redis-port quorum
      		sentinel monitor mymaster 192.168.100.110 8000 2
      		//name要和上面一致,后面是密码
      		sentinel auth-pass mymaster 123456
      		将改完的sentinel7000.conf 复制两份
      		使用  :%s/7000/7001/g    批量替换
      		使用  :%s/7001/7002/g    批量替换
      	3.	启动哨兵
      	./redis-sentinel  ../sentinel/sentinel7000.conf 
      	./redis-sentinel  ../sentinel/sentinel7001.conf 
      	./redis-sentinel  ../sentinel/sentinel7002.conf 
      
  • 使用Jedis监控故障转移

 public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(SentinelPool.class);
        Set<String> set = new HashSet<>();
        set.add("192.168.100.110:7000");
        set.add("192.168.100.110:7001");
        set.add("192.168.100.110:7002");
        JedisSentinelPool jedisSentinelPool = new JedisSentinelPool("mymaster", set, "123456");
        while (true) {
            Jedis jedis = null;
            try {
                jedis = jedisSentinelPool.getResource();
                String s = UUID.randomUUID().toString();
                jedis.set("k" + s, "v" + s);
                System.out.println(jedis.get("k" + s));
                Thread.sleep(1000);
            } catch (Exception e) {
                logger.error(e.getMessage());
            } finally {
                if (jedis != null) {
                    jedis.close();
                }
            }
        }
    }
  • 哨兵模式原理
    来源:https://cloud.tencent.com/developer/article/1409270
    哨兵启动后会与要监控的主数据库建立两条连接
    技术图片
    ??和主数据库连接建立完成后,哨兵会使用连接2发送如下命令:
    1.每10秒钟哨兵会向主数据库和从数据库发送INFO 命令
    2.每2秒钟哨兵会向主数据库和从数据的_sentinel_:hello频道发送自己的消息。
    3.每1秒钟哨兵会向主数据、从数据库和其他哨兵节点发送PING命令。
    ??首先,发送INFO命令会返回当前数据库的相关信息(运行id,从数据库信息等)从而实现新节点的自动发现,前面提到的配置哨兵时只需要监控Redis主数据库即可,因为哨兵可以借助INFO命令来获取所有的从数据库信息(slave),进而和这两个从数据库分别建立两个连接。在此之后哨兵会每个10秒钟向已知的主从数据库发送INFO命令来获取信息更新并进行相应的操作。
    ??接下来哨兵向主从数据库的_sentinel_:hello 频道发送信息来与同样监控该数据库的哨兵分享自己的信息。发送信息内容为:
	<哨兵的地址>,<哨兵的端口>,<哨兵的运行ID>,<哨兵的配置版本>,
	<主数据库的名字>,<主数据库的地址>,<主数据库的端口>,<主数据库的配置版本>

技术图片
??哨兵通过监听的_sentinel_:hello频道接收到其他哨兵发送的消息后会判断哨兵是不是新发现的哨兵,如果是则将其加入已发现的哨兵列表中并创建一个到其的连接(哨兵与哨兵只会创建用来发送PING命令的连接,不会创建订阅频道的连接)。
??实现了自定发现从数据库和其他哨兵节点后,哨兵要做的就是定时监控这些数据和节点运行情况,每隔一定时间向这些节点发送PING命令来监控。间隔时间和down-after-milliseconds选项有关,down-after-milliseconds的值小于1秒时,哨兵会每隔down-after-milliseconds指定的时间发送一次PING命令,当down-after-milliseconds的值大于1秒时,哨兵会每隔1秒发送一次PING命令。例如:

					// 每隔1秒发送一次PING命令
						sentinel down-after-milliseconds mymaster 60000
						// 每隔600毫秒发送一次PING命令
					sentinel down-after-milliseconds othermaster 600
  • 主观下线
    ??当超过down-after-milliseconds指定时间后,如果被PING的数据库或节点仍然未回复,则哨兵认为其主观下线(subjectively down),主观下线表示从当前的哨兵进程看来,该节点已经下线。
  • 客观下线
    ??在主观下线后,如果该节点是主数据库,则哨兵会进一步判断是否需要对其进行故障恢复,哨兵发送SENTINEL is-master-down-by-addr 命令询问其他哨兵节点以了解他们是否也认为该主数据库主观下线,如果达到指定数量时,哨兵会认为其客观下线(objectively down),并选举领头的哨兵节点对主从系统发起故障恢复。这个指定数量就是前面配置的 quorum参数。
sentinel monitor mymaster 192.168.100.110 8000 2

该配置表示只有当至少有两个Sentinel节点(包括当前节点)认为该主数据库主观下线时,当前哨兵节点才会认为该主数据库客观下线。接下来选举领头哨兵。

  • 选举领头哨兵
    ??当前哨兵虽然发现了主数据客观下线,需要故障恢复,但故障恢复需要由领头哨兵来完成。这样来保证同一时间只有一个哨兵来执行故障恢复,选举领头哨兵的过程使用了Raft算法,具体过程如下:
    1.发现主数据库客观下线的哨兵节点(A)向每个哨兵节点发送命令,要求对象选择自己成为领头哨兵
    2.如果目标哨兵节点没有选过其他人,则会同样将A设置为领头哨兵
    3.如果A发现有超过半数且超过quorum参数值的哨兵节点同样选择自己成为领头哨兵,则A成功成为领头哨兵
    4.当有多个哨兵节点同时参选领头哨兵,则会出现没有任何节点当选的可能,此时每个参选节点将等待一个随机事件重新发起参选请求进行下一轮选举,直到选举成功。
  • 故障恢复
    ?选出领头哨兵后,领头哨兵将会开始对主数据库进行故障恢复。步骤如下
    1.首先领头哨兵将从停止服务的主数据库的从数据库中挑选一个来充当新的主数据库。
序号 挑选依据
1 所有在线的从数据库中,选择优先级最高的从数据库。优先级通过replica-priority参数设置
2 优先级相同,则复制的命令偏移量越大(复制越完整)越优先
3 如果以上都一样,则选择运行ID较小的从数据库

2.选出一个从数据库后,领头哨兵将向从数据库发送SLAVEOF NO ONE命令使其升格为主数据库,而后领头哨兵向其他从数据库发送 SLAVEOF命令来使其成为新主数据库的从数据库,最后一步则是更新内部的记录,将已经停止服务的旧的主数据库更新为新的主数据库的从数据库,使得当其恢复服务时自动以从数据库的身份继续服务

  • 哨兵模式优缺点
    • 优点
      • 哨兵集群模式是基于主从模式的,所有主从的优点,哨兵模式同样具有。
      • 主从可以切换,故障可以转移,系统可用性更好。
      • 哨兵模式是主从模式的升级,系统更健壮,可用性更高。
    • 缺点
      • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。
      • 配置复杂

以上是关于Redis的主从复制和哨兵模式的主要内容,如果未能解决你的问题,请参考以下文章

Redis集群模式1-主从复制+哨兵机制

NoSQL 之Redis主从复制哨兵和集群介绍及详细搭建步骤

Redis 主从复制-哨兵-集群 相关部署

Redis主从复制和哨兵模式

Redis 大型攻略之主从复制哨兵模式群集模式

Redis 大型攻略之主从复制哨兵模式群集模式