当前位置:   article > 正文

Redis6.0.8源码解析五之(多机数据库)_redis 6.0.8 slaveof 不起作用

redis 6.0.8 slaveof 不起作用

部署集群步骤

在这里插入图片描述

主从复制

旧版复制功能实现

  • 同步:将从服务器数据更新至主服务器状态
  • 命令传播:MASTER修改,同步命令到Slave
    缺点:当slave中途断了和master的联系,当再次连上master时,master会dump所有命令到RDB文件,然后同步到从服务器.而实际上slave只需要同步断掉期间在master执行的命令.
    同步

客户端向服务器发送SLAVEOF命令,将当前服务器转变为指定服务器的从属服务器(slave server),期间从服务器同步主服务器数据.
步骤如下:

  • 从服务器发送SYNC到主服务器
  • 主服务器执行BGSAVE命令,生成RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令
  • BGSAVE完成,主服务器将RDB发送从服务器,从服务器载入RDB.
  • 主服务器将缓冲区记录发送从服务器,从服务器执行.
    在这里插入图片描述

新版复制功能实现

redis2.8之后,使用PSYNC代替SYNC命令执行复制时的同步操作
分别提供2种模式:

  • 完整重同步,同SYNC
  • 部分重同步,主要处理断线后重复制情况.当slave断线后重连上master,master将断线期间执行命令发送slave.
    在这里插入图片描述

部分重同步实现
从服务器连上主服务器后,会发送主服务器运行ID
主服务器查找运行ID是否与本机ID一致,找到则执行部分重同步,否则完全重同步.
连接成功后,slave向maste发送当前复制偏移量,若复制偏移量之后数据在master复制积压缓冲区中,则发送之后数据给slave.否则完全重同步.

在服务器同步slave时,会将命令放入复制积压队列缓冲区中.这个队列时固定的FIFO,也就是说当队列撑满后,后放入的数据会让first弹出去.
在这里插入图片描述
复制缓冲区构造
在这里插入图片描述
PSYNC执行流程:
在这里插入图片描述

实现流程

  1. 客户端发送SLAVEOF命令,slave将命令主服务器IP和端口保存,返回OK给客户端
  2. slave向master建立连接
  3. slave向master发送ping,检测主服务器是否正常
    在这里插入图片描述
  4. master返回pong给slave,slave发送auth 密码,进行权限校验.
    在这里插入图片描述
  5. 身份验证通过后,slave发送REPLCONF命令,向master发送slave监听端口.master保存端口信息
  6. 发送PSYNC,进行同步.在这一步,master会成为slave的客户端.
  7. 命令传播阶段,紧接着,每次当master接收命令都会传播slave.

心跳检测

在命令传播阶段,slave send commend to master 1s/time
REPLCONF ACK 从服务器当前偏移
具体功能如下:

  1. 检测主从是否可用.master 1s没接收到slave,则判断主从连接出问题.
  2. 辅助实现min-slaves配置,当向主设置min-slaves-to-write 3和min-slaves-max-lag 10,在slave数量<3,或三个slave延迟>=10,则master拒绝写入.
  3. 通过发送的从服务器当前偏移,检测命令是否丢失.丢失则补发丢失命令.跟部分重同步的区别在于是在slave没断线重连执行.在2.8之前丢失命令则丢失了.

通过主从复制,仅仅只能解决数据读压力和数据同步问题,但是当master宕机了,redis将不能提供写服务.解决办法sentinel进行主从切换.

sentinel

当master down之后,可通过手工和sentinel配置新的master
在这里插入图片描述

sentinel会对于每个被监控的服务器分别创建命令连接和订阅连接
在这里插入图片描述
sentinel在与其他sentinel连接时,只会创建命令连接.
在这里插入图片描述

sentinel 10S/次 向被监控服务器发送INFO命令获取主服务器的从服务器当前信息,然后为这些从服务器创建相应实例.

sentinel 2s/次发送订阅消息,其他sentinel接收到然后创建新的实例sentinel对象,以及与sentinel命令连接.

心跳检测以及选举sentinel

  1. sentinel 1s/次向所有连接发送ping,判断他们是否在线.在down-after-milliseconds时间没有连接上,修改该实例flags为SRI_S_DOWN标识,标识此服务器主观下线.
  2. 然后询问监控这服务器的其他sentinel,当达到monitor配置的quorum次数,则客观判断此下线,标记SRI_O_DOWN
  3. 监视下线服务器的每个sentinel选举头.每个sentinel向其他sentinel发送命令,谁发的早,接收消息的sentinel就将选举权给他.然后统计票数,超过1半,则头是他.
    参考Raft点击这里,还扩展了流言协议,2PC协议,3PC协议等

选举master以及主从同步

  1. 根据选举策略选出Master后,任意一台slave设置slaveof no one,表示角色更换为master.

选举策略如下:

  1. 接着sentinel 1S/次向master发送info(平常10S/次),观察role是否变更为master,变更后则说明切换成功.
  2. sentinel通知slave发送slaveof向master注册.

在这里插入图片描述

  1. 注册成后,将已下线主服务器,设置为从服务器.当服务器上线,sentinel则向他发送slaveof,让他成为从服务器.

通过sentinel弥补了主从的局限性,但是当数据量过大,会出现单台服务器存不下问题,解决办法分片.也就是集群模式.跟数据库分库分表差不多.解决容量上限问题.

集群

开启集群以及访问

  1. 配置文件设置cluster-enabled yes,表示是否开启服务器集群模式,并启动节点,
    在这里插入图片描述

  2. 使用cluster meet连接其他节点加入集群.期间会将clusterNode(节点信息)加入clusterState.nodes中.然后使用流言协议散播其他集群其他节点,让其他节点与新加入节点握手.
    通讯过程如下:
    在这里插入图片描述

  3. 通过cluster addsloats 给每个节点指派槽,然后每个节点同步其他节点的槽信息,紧接着就上线了.
    在这里插入图片描述

  4. 客户端使用集群方式访问
    在这里插入图片描述

重新分片以及期间访问流程

通过redis-trib软件负责
分片规则如下:
在这里插入图片描述
执行流程如下:
在这里插入图片描述
倘若这时,有客户端访问节点,流程如下:
在这里插入图片描述
具体判断是否在迁移槽如下:

  1. 当执行CLUSTER_SETSLOT [i] IMPORTING [source_id]
    时,会将目的节点的importing_slots_from[i]的值设置为source_id的clusterNode

cluster.h

typedef struct clusterState {
    // 记录要从源节点迁移到本节点的槽,以及进行迁移的源节点
    // importing_slots_from[i] = NULL 表示槽 i 未进行导入
    // importing_slots_from[i] = clusterNode_A 表示正从节点 A 中导入槽 i
    clusterNode *importing_slots_from[CLUSTER_SLOTS];
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 当执行CLUSTER SETSLOT [i] MIGRATING
    [target_id]时,会将源节点migrating_slots_to设置为目的节点.
typedef struct clusterState {
    // 记录要从当前节点迁移到目标节点的槽,以及迁移的目标节点
    // migrating_slots_to[i] = NULL 表示槽 i 未被迁移
    // migrating_slots_to[i] = clusterNode_A 表示槽 i 要从本节点迁移至节点 A
    clusterNode *migrating_slots_to[CLUSTER_SLOTS];
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 节点先找key找不到,看migrating_slots_to是否有,有的话就向客户端发送ASK错误,让他去migrating_slots_to节点去找.
  2. 到目标节点找key时,首先需要发送asking命令.这个命令主要打开REDIS_ASKING标识,当随后执行一个命令后,就会关闭.
    在这里插入图片描述

复制以及故障转移

添加从节点

CLUSTER REPLICATE node_id:将接收命令的节点称为node_id的从节点,并开始复制.
具体步骤如下:

  1. 将clusterState.myself.slaveof指向clusterState.nodes[node_id],记录当前节点的主节点.
  2. 修改clusterState.myself.flags=REDIS_NODE_SLAVE,表示为从节点
  3. 向主节点复制.同SLAVEOF命令
  4. 集群所有节点都会修改代表主节点的slaves和numslaves值

故障检测

  1. 集群中每个节点都定期向集群其他节点发送PING,若A节点没在规定时间响应,则B节点clusterState.nodes找到A节点,标记flags为REDIS_NODE_PFALL.
  2. 通知其他主节点,A疑似下线了.其他节点修改A节点fail_reports为B节点的下线报告.

在这里插入图片描述

  1. 超过一半主节点觉得A掉线,则标记A为掉线的主节点群发其他节点,A掉线.

故障转移

  1. 从节点中选择主节点,新主节点执行SLAVEOF no one,成为新主节点
  2. 主节点将下线节点槽给自己.
  3. 主节点广播发送PONG,通知其他节点,自己成为主节点了,而且接管了槽.
  4. 处理有关槽命令

选举新节点

在这里插入图片描述

消息

在这里插入图片描述
一条消息由消息头+正文组成:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/586174
推荐阅读
相关标签
  

闽ICP备14008679号