zoukankan      html  css  js  c++  java
  • redis学习笔记06-主从复制和哨兵机制

    1.主从复制

    为了保证线上业务的持续运行,防止主节点因宕机而重启数据恢复消耗太长时间,通常会准备一个备用节点,备份主节点的数据,当主节点出问题时立马顶上。这种机制就叫做主从复制。在了解redis的主从复制之前,需要先了解一下现代分布式系统的理论基础--CAP原理。

    1.1 CAP原理

    • C(consistent) 一致性
    • A(availability) 可用性
    • P(partition tolerance) 分区容忍性

    一致性:所有服务端,客户端的数据保持同步一致。
    可用性:系统随时可用
    分区容忍性:分布式系统的节点分布在不同的机器上,即意味着必然存在网络断开的风险,这种网络断开的场景叫做网络分区。

    当允许网络分区发生时,分布式系统的两个节点之间无法通信,当一个节点数据发生改动时,另一个无法同步,即失去了一致性。如果强行保持一致就需要暂停分布式节点服务,这就丧失了可用性。其实这样看来,CAP原理就是:当网络分区发生时,一致性和可用性不可兼得。
    redis主从数据是异步同步的,从节点一直在追赶着同步主节点的数据,最后总能保持一致,这叫做最终一致性

    1.2 主从复制使用

    主从复制的配置只需要配置从机,语句如下:slaveof 主机ip 主机端口号 。默认从机只进行读操作,保证读写分离,增加效率,常用配置方式是一主二从。
    使用时有如下特点:

    1. 当主节点宕机时,两个从节点会一直等待主节点重连,重连后依然是主节点的从节点,数据继续同步。
    2. 当主节点宕机后,从节点执行命令 slaveof no one 可以成为一个主节点,摆脱从属关系。
    3. 可以再用一个节点设置成主节点的从节点的从节点,让数据一直传递下去,去中心化,减轻主机的负担。

    1.3 主从复制的复制原理
    ① 增量同步
    redis同步的是指令流,主节点会将那些对自己状态产生影响的指令记录在本地内存buffer中,然后异步将buffer中的指令同步到从节点,从节点一边执行同步的指令流,一边向主节点反馈同步的位置。内存中的buffer结构为一个定长的环形数组,如果环形数组满了就会从头开始覆盖之前的内容,如果网络状况差的时候,从节点与主节点长期未同步就有可能丢失数据,因此这时需要使用快照同步。
    ②快照同步
    它需要先在主节点上执行bgsave命令存盘,然后将快照内容全部传送到从节点。从节点接受完,立即执行一次全量加载,加载前将内存数据清空。这个过程需要大量的时间,如果内存的buffer过小,在同步期间增量指令在复制buffer中被覆盖,就会再次执行快照复制,极有可能造成快照复制的死循环。
    当新加入从节点时,会先执行一次快照同步,再执行增量同步。
    ③无盘复制
    由于快照同步很耗费时间,影响主节点的服务效率,因此在redis2.8.18版本之后引入无盘复制,其操作流程为主服务器直接通过套接字将快照内容发送到从节点,主节点一边遍历内存,一边将序列化的快照内容发送的从节点,从节点还是将接收的内容先保留在磁盘上,再进行一次性加载。

    1.4 补充内容

    redis的复制是异步进行的,在redis3.0之后可以用wait指令将异步复制改为同步复制,确保系统的强一致性(不严格)。
    wait有两个参数,第一个是从节点的数量N,第二个参数是时间t(毫秒),其作用为,等待wait指令之前的所有写操作同步到N个从节点,最多等待时间t,若t=0则表示一直等待,直到N个从节点都同步完成。
    值得注意的是,假如在同步时发生了网络分区,而wait的参数t=0,这会导致主从同步无法执行,wait指令会永远阻塞,redis服务器将丧失可用性。

    1. 哨兵机制(Sentinel)
      ===

    一主二从配置下,当主节点宕机时,从节点会一直等待主节点恢复,但是如果主节点长期未连接,而又需要继续执行业务怎么办?
    这时候就需要在从节点中选出一个主节点,代替原来的主节点执行业务,这种机制就是Sentinel。相当于一个哨兵,检测主机状态,当主节点宕机一定的时间后,推选出新的主节点。
    配置步骤如下:

    1. 主从复制集群搭建

    2. 新建sentinel.conf配置文件,文件内容:
        sentinel monital 被监控的主机的名字(自己命名) 被监控的ip 被监控的端口号 1
      最后的数字1,代表主机挂掉之后,从机得到的投票数高于1时,就可成为新的主机。

    3. 启动sentinel.conf配置文件 redis-sentinel sentinel.conf路径
      python客户端下的基本用法如下:>python客户端下的基本用法如下:

    from redis.sentinel import Sentinel
    
    sentinel = Sentinel([('localhost',26379)],socket_timeout=0.1)
    sentinel.discover_master('mymaster') #查询主节点地址 mymaster指的是自己命名的主机名字
    sentinel.discover_slaves('mymaster') #查询从节点地址
    
    #通过 xxx_for方法从连接池中获取一个链接使用
    master = sentinel.master_for('mymaster',socket_timeout=0.1)
    slave = sentinel.slave_for('mymaster',socket_timeout=0.1)
    
    master.set('foo','bar')
    slave.get('foo')
    

    当主节点变更后,连接池建立新的链接。建立连接时会去查询主节点地址,然后跟内存中的主节点地址进行比对,如果发生变更就断开所有连接,重新使用新地址建立链接。如果旧主节点挂掉了,所有正在使用的连接全部关闭,在重连时使用新地址。

    如果进行主动主从切换,而旧的主节点并没有挂掉还在继续使用中时,会产生一个异常,redis捕捉这个异常后,将旧的连接全部关闭,重新连接时使用新地址进行连接。

    主从切换后,之前的主节点变成从节点,它的所有的修改指令都会抛出异常。

  • 相关阅读:
    Leetcode Excel Sheet Column Number
    AlgorithmsI PA2: Randomized Queues and Deques Subset
    AlgorithmsI PA2: Randomized Queues and Deques RandomizedQueue
    AlgorithmsI PA2: Randomized Queues and Deques Deque
    AlgorithmsI Programming Assignment 1: PercolationStats.java
    hdu多校第四场 1003 (hdu6616) Divide the Stones 机智题
    hdu多校第四场 1007 (hdu6620) Just an Old Puzzle 逆序对
    hdu多校第四场1001 (hdu6614) AND Minimum Spanning Tree 签到
    hdu多校第三场 1007 (hdu6609) Find the answer 线段树
    hdu多校第三场 1006 (hdu6608) Fansblog Miller-Rabin素性检测
  • 原文地址:https://www.cnblogs.com/LLBoy/p/11593793.html
Copyright © 2011-2022 走看看