不为难自己,迟早会委屈自己!

Redis设计与实现-主从、哨兵与集群

主从
  1. 从机使用slaveof 命令来复制主机的缓存数据,包括同步sync与命令传播两个操作;
  2. 从机同步sync命令给主机,主机收到后执行需要耗费大量cpu、内存和磁盘IO资源的bgsave命令来生成rdb文件,并发送给从服务器,期间会耗费大量网络资源,因此,同步的代价是很大的;
  3. 从机载入rdb文件后,主机再把执行bgsave后记录在缓冲区里的所有写命令发送给从服务器实现主从当前状态的同步;
  4. redis 2.8之前的版本在复制是如果出现了断网,则会重新全部重新复制,效率低,2.8版以后使用psync <runid> <offset>命令,根据主机维护的复制积压缓冲区以及主从间各自维护的偏移量来确定是完整重同步还是部分重同步;
  5. 每个运行的redis服务器都有一个唯一识别的运行ID,初次复制从机会记录主机的运行ID,当断线重连是会先检测记录的主机ID与当前连接的主机ID是否一致,如果不一致则说明主机重启过,此时将执行完整重同步;
  6. 复制实现过程:
    • 从机保存主机的ip、port到redisServer数据结构里;
    • 主从建立套接字进行连接;
    • 从机发送ping命令给主机对主机进行状态监测;
    • 主机对从机进行身份密码验证;
    • 从机给主机发送监听的端口号;
    • 从机向主机发送psync同步;
    • 命名传播
  7. 从机默认每一秒向主机发送replconf ACK <replication_offset>,用于检测主从服务器网络连接状态、辅助实现最小从机数配置、根据偏移量检测命令丢失并进行适当重发。

以上文字来自Dimmacro,转载请说明来源:http://www.cnblogs.com/dimmacro/ 

哨兵
  1. sentinel由一个或多个sentinel实例组成系统监视多个主服务器以及所属的从服务器;
  2. sentinel本质是一个运行在特殊模式下的redis服务器,只支持ping、sentinel、info、subscribe、unsubscribe、psubscribe、punsubscribe共7个命令;
  3. 每个sentinelRedisInstance结构里可以是主服务器、从服务器或另一个sentinel的信息;
  4. 每个sentinel会分别于主服务器以及每个从服务器建立命令连接与订阅连接,通过命令连接分别向主从服务器发送info信息以获得主从机状态信息,同时,通过命令连接向服务器的sentinel_:hello频道发送sentinel自身信息以及主从及信息以便其他sentinel可以共享;
  5. 通过订阅连接获取sentinel_:hello频道信息,这些信息可能来自自己,也可能来自其他sentinel;
  6. sentinel与其他sentinel之间只创建命令连接进行通讯,共享信息通过sentinel_:hello频道即可;
  7. 每个sentinel会向主从机以及其他sentinel发送ping命令,如果在一定的时间内没有得到有效回复,则会被认为其已主观下线,如果是主服务器被判断为主观下线,则sentinel会向其他sentinel进行询问,如果达到了设置的认为下线的sentinel数,则判断主服务器下线;
  8. 所有sentinel根据raft算法选举出一个leader sentinel对已下线的主服务器进行故障转移操作,包括在从服务器中选取某个为主服务器(依据从的优先级、复制偏移量、最小运行ID),让其他从改为复制新的主,让旧的主变为从;

以上文字来自Dimmacro,转载请说明来源:http://www.cnblogs.com/dimmacro/ 

 

集群
    1. 多个redis节点可以组成一个集群,每个节点都存储了集群里自身及其他节点的信息,使用cluster meet将某个节点加到集群中;
    2. 在各自节点上使用命令cluster addlots 指派负责的槽号,每个节点都会记录自己及集群内其他节点的对应负责的槽号,所有槽号都被指派到具体节点后,整个集群进入上线状态;
    3. redis集群将数据库分为8个字节共16384个slot槽,每个键key的crc-16&16384得到该key所在的槽号;
    4. 如果key对应的槽号不在当前节点内,会向客户端返回moved key ip:port,引导客户端去找正确的节点;
    5. 扩展节点并指派槽后整个集群会进行重新分片,分片按单个槽依次进行,如果在槽的分片迁移过程中请求到槽所在的节点,会发生ask重定向;
    6. 当集群内的某个节点发生故障后,其他正常的节点会从该故障节点所属的从节点中选取一个主节点,选取的算法同样基于raft领头选举算法;
    7. 被选中为从节点先执行slaveof no one命令成为主节点,然后撤销所有对已下线主节点的槽指派,并指派给自己,然后在集群内广播PONG消息通知其他主节点;
    8. 集群内节点通讯的5中消息:
      • meet消息:请求接受者加入到发送者当前所处的集群里;
      • ping消息:集群内节点探测其他节点是否在线的消息,这种消息不是每两两发送,而且随机选出5个或者超过一定时间没有返回pong消息的节点;
      • pong消息:回复meet或ping消息,或者通知其他节点刷新对本节点的认识;
      • fall消息:当节点a判断节点b进入fall状态,会发送此消息给集群内的其他节点;
      • publish消息:当节点收到publish命令会执行此命令并向集群内广播一条publish消息,所有接收到这条publish消息的节点都会执行相同的publish命令

以上文字来自Dimmacro,转载请说明来源:http://www.cnblogs.com/dimmacro/ 

posted on 2016-12-07 18:48  Dimmacro  阅读(595)  评论(0编辑  收藏  举报