redis 系列27 Cluster高可用 (2)
一. ASK错误
集群上篇最后讲到,对于重新分片由redis-trib负责执行,关于该工具以后再介绍。在进行重新分片期间,源节点向目标节点迁移一个槽的过程中,可以会出现该槽中的一部分键值对保存在源节点中,另一部份键值对则保存在目标节点中。
当客户端向源节点发送一个与数据库键有关的命令时,并且命令要处理的数据库键正好就是正在被迁移的槽时,会出现二种情况的一种:
(1) 源节点会先在自己的数据库中查找指定的键,如果找到的话,就会直接执行客户端发送的命令。
(2) 相反,如果在源节点找不到指定的键,那么键有可能已经被迁移到了目标节点,源节点将向客户端返回一个ASK错误,指引客户端转向正在导入槽的目标节点,并再次发送之前想要执行的命令。
注意:和接到Moved错误时的情况一样,集群模式的redis-cli在接到ask错误时也不会打印错误,而是自动根据错误提供的ip和port进行转向(Redirected to ..)动作。
1.1 cluster setslot importing 命令实现
在clusterState结构的importing_slots_from数组中,记录了当前节点正在从其他节点导入的槽号。在集群进行重新分片的时候,向目标节点发送以下命令,格式为:
cluster setslot < slot > importing <node ID>
slot 和 node_id是指:源节点槽号和源节点ID。比如在上一篇结尾,原属于7002节点的14042 号槽,迁移到了目标7003节点,在7003节点中内部clusterState结构的importing_slots_from数组下记录了14042号槽,并且还记录了源节点ip和端口(127.0.0.1 7002)。
1.2 cluster setslot migrating命令实现
在clusterState结构的 migrating_slots_to数组中,记录了当前节点正在迁移至其他节点的槽。在集群进行重新分片的时候,向源节点发送命令以下命令,格式为:
cluster setslot < slot > migrating <node ID>
slot 和 node_id是指:目标节点槽号和目标节点ID。
下图左边7003目标节点 importing_slots_from数组 和 右边7002源节点的migrating_slots_to数组:

1.3 ASK错误后的引导
如果节点收到一个关于键key的命令请求,并且键key所属的槽i正好就指派给了这个节点, 如果节点没有在自己的数据库里找到键key,那么节点会检查自己的迁移数组clusterState.migrating_slots_to[i], 看键key所属的槽i是否正在进行迁移,如果槽 i 的确在进行迁移,那么节点会向客户端发送一个ask错误,引导客户端到正在导入槽 i 的节点去查找键key。
1.4 ASK错误和Moved错误的区别
ASK错误和Moved错误都会导致客户端转向,它们区别在于:
(1) Moved错误代表槽的负责权,已经从一个节点转移到了另一个节点:在客户端收到关于槽i的mvoed错误之后,客户端每次遇到关于槽i的命令请求时,都可以直接将命令请求发送到moved错误所指向的节点,因为该节点就是目前负责槽i的节点。
(2) 与此相反,ASK错误只是两个节点在迁移槽的过程中使用的一种临时措施:在客户端收到关于槽 i 的ASK错误之后,客户端只会在接下来的一次命令请求中将关于槽 i 的命令请求发送到ASK错误所指示的节点。
二. 复制与故障转移
集群中的节点分为主节点和从节点,主节点用于处理槽,而从节点则用于复制某个主节点,当主节点下线时,从节点代替主节点继续处理命令请求。
复制设置从节点:在主节点将设置 node_id (node_id为从节点),脚本如下:
CLUSTER REPLICATE <node_id>
2.1 节点故障检测
集群中的每个节点都会定期向群集中的其他节点发送ping消息,以此来检测对方是否在线,如果接收ping消息的节点没有在规定的时间内返回pong消息,那么发送节点就会将接收节点标记为疑似下线pfail(probable fail)。
集群中的各个节点会通过互相发送消息的方式来交换集群中各个节点的状态信息,来判断节点是处于在线、疑似下线还是下线(fail) 状态。
在集群中,负责处理槽的节点在半数以上都将某个主节点x 报告为疑似下线状态时,那么这个主节点x将标记为已下线 fail。 将主节点x标记为已下线的节点会向集群广播一条关于主节点x的fail消息。
2.2 故障转移实现步骤
当一个从节点发现自己正在复制的主节点进入已下线状态时,从节点将开始对下线主节点进行故障转移,步骤如下:
(1) 复制下线主节点的所有从节点,会有一个从节点被选中。
(2) 被选中的从节点会执行slaveof no one 命令,成为新的主节点。
(3) 新的主节点会撤消所有对已下线主节点的槽指派,并将这些槽指派给自己。
(4) 新的主节点向集群广播一条pong消息,这条pong消息可以让集群中的其他节点立即知道这个节点已经由从节点变成了主节点,并且接管了原本已下线的节点负责处理的槽。
(5) 新的主节点开始接收和自己负责处理的槽有关的命令请求,故障转移完成。
2.3 节点之间的通信
集群中的各个节点通过发送和接收消息来进行通信,节点发送的消息主要以5种:
(1) meet消息: 发送者向接收者发送meet消息,请求接收者加入到发送者当前所处的集群中。
(2) ping消息:集群中每个节点默认每隔1秒就会从已知节点列表随机选出5个节点,然后对这5个节点中最长时间没有发送过ping消息的节点发送ping消息,以此来检测被选中的节点是否在线。
(3) pong消息:当接收者收到meet或ping消息时,会向发送者返回一条pong消息,以此表明自己(接收者)节点是正常的。另外一个节点也可以通过向集群广播自己的pong消息来让集群中的其他节点刷新关于这个节点的认识。
(4) Fail消息: 当一个主节点A判断另一个主节点B已经进入Fall状态时,节点A会向集群广播一条关于节点B的Fall消息,所有收到这条消息的节点都会立即将节点B标记为已下线。
(5) publish消息: 当节点接收到一个publish命令时,节点会执行这个命令,并向集群广播一条publish消息,所有接收到这条publish消息的节点都会执行相同的publish命令。
三. 集群知识点总结
(1) 节点通过握手来将其他节点添加到自己所处的集群当中。
(2) 集群中的16384个槽可以分别指派给集群中的各个节点,通过cluster nodes命令可以看到节点的槽分布。
(3) 节点在接到一个命令请求时,先检查这个命令请求要处理的键所在的槽是否由自己负责,如果不是,节点向客户端返回一个moved错误,moved错误携带的信息可以指引客户端转向至正在负责相关槽的节点继续来处理。
(4)对Redis集群的重新分片工作是由redis-trib负责执行的,重新分片是将属于某个槽的所有键值对从一个节点转移至另一个节点。
(5)如果节点A正在迁移槽 i 到节点B,当节点A没能在自己的数据库中找到命令指定的键时,节点A向客户端返回一个ASK错误,指引客户端到节点B继续查找指定键。
(6) Moved错误代表槽的负责权已经从一个节点转移到了另一个节点,而ASK错误只是两个节点在迁移槽的过程中使用的一种临时措施。
(7) 集群中的从节点用于复制主节点,并在主节点下线时,代替主节点继续处理命令请求。
(8) 集群中的节点通过发送和接收消息来进行通信,常见的消息包括meet;ping ;pong;publish;fail五种。
redis 系列27 Cluster高可用 (2)的更多相关文章
- redis 系列26 Cluster高可用 (1)
一.概述 Redis集群提供了分布式数据库方案,集群通过分片来进行数据共享,并提供复制和故障转移功能.在大数据量方面的高可用方案,cluster集群比Sentinel有优势.但Redis集群并不支持处 ...
- Redis系列4:高可用之Sentinel(哨兵模式)
Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 1 背景 从第三篇 Redis系列3:高可用之主从架构 ,我们知道,为Re ...
- Redis系列3:高可用之主从架构
Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 1 主从复制介绍 上一篇<Redis系列2:数据持久化提高可用性>中,我们介绍了Redis中的数据 ...
- Redis系列(四)-低成本高可用方案设计
关于Redis高可用方案,看到较多的是keepalived.zookeeper方案. keepalived是主备模式,意味着总有一台浪费着.zookeeper工作量成本偏高. 本文主要介绍下使用官方s ...
- Redis Cluster高可用集群在线迁移操作记录【转】
之前介绍了redis cluster的结构及高可用集群部署过程,今天这里简单说下redis集群的迁移.由于之前的redis cluster集群环境部署的服务器性能有限,需要迁移到高配置的服务器上.考虑 ...
- Redis Cluster高可用集群在线迁移操作记录
之前介绍了redis cluster的结构及高可用集群部署过程,今天这里简单说下redis集群的迁移.由于之前的redis cluster集群环境部署的服务器性能有限,需要迁移到高配置的服务器上.考虑 ...
- Dubbo入门到精通学习笔记(十五):Redis集群的安装(Redis3+CentOS)、Redis集群的高可用测试(含Jedis客户端的使用)、Redis集群的扩展测试
文章目录 Redis集群的安装(Redis3+CentOS) 参考文档 Redis 集群介绍.特性.规范等(可看提供的参考文档+视频解说) Redis 集群的安装(Redis3.0.3 + CentO ...
- Redis从出门到高可用--Redis复制原理与优化
Redis从出门到高可用–Redis复制原理与优化 单机有什么问题? 1.单机故障; 2.单机容量有瓶颈 3.单机有QPS瓶颈 主从复制:主机数据更新后根据配置和策略,自动同步到备机的master/s ...
- net core 实战之 redis 负载均衡和"高可用"实现
net core 实战之 redis 负载均衡和"高可用"实现 1.概述 分布式系统缓存已经变得不可或缺,本文主要阐述如何实现redis主从复制集群的负载均衡,以及 redis的& ...
随机推荐
- pycharm中range的应用
v = range(100) for item in v: print (item) #输出结果是0 1 2 3 ......99 这是在python3中实现的,python2中不一样 下面是一个从大 ...
- Hive基础测试操作
一.Hive测试 1.查看数据库 show databases; 2.使用某个数据库,如默认数据库 user default; 3.创建表 create table if not exist itst ...
- 在Ubuntu下开启我的第一个Android工程
目录 环境 流程 Phone PC端 我踩到坑 1.device offline Error while Installing APK 2.NO MODULE 3.应用无法安装 环境 小米Note4: ...
- C++ 使用 curl 进行 http 请求(GET、POST、Download)的封装
修改自网路 CommonTools.h /* * CommonTools.h * * Created on: 2018年8月2日 * Author: didi */ #include <iost ...
- Spring Cloud微服务笔记(四)客户端负载均衡:Spring Cloud Ribbon
客户端负载均衡:Spring Cloud Ribbon 一.负载均衡概念 负载均衡在系统架构中是一个非常重要,并且是不得不去实施的内容.因为负载均衡对系统的高可用性. 网络压力的缓解和处理能力的扩容的 ...
- python爬取珞珈1号卫星数据
首先登录珞珈一号数据系统查询想要的数据 利用浏览器审查元素获取包含下载信息的源码 将最右侧的table相关的网页源码copy到剪切板备用 利用python下载数据 ## utf-8 import re ...
- 三色GDOI
前面说点什么.. 翻了翻别人的游记.. 发现自己从来没写过gdoi的游记.. 那就.. 一起写完它吧.. GDOI2015 肇庆 没啥印象,只有复联2的首映.. 那时候真的是什么都不懂.. 就是外出打 ...
- 用kattle将数据从SQLserver中导入到vertica中
今天简单的学习了一下ETL工具kattle了,只是简单的上手,不过这也已经够我去做POC了. 首先大体介绍一下kattle,Kettle是一款国外开源的ETL工具,纯java编写,可以在Window. ...
- Ubuntu上安装使用WeChat、TIM
WeChat可以直接到软件商店安装,不过是网页版...(其实个人感觉还行,就是什么都不能设置就挺蛋疼的,字体大小.背景什么的) 以下是网上找到的教程,在此总结一下: 下载地址:https://gith ...
- Jmeter中连接Oracle报错Cannot create PoolableConnectionFactory
填坑贴,之前一直用jmeter2.13版本进行oracle测试,今天改为3.2版本,发现按照以往的方法执行测试,JDBC Request结果始终报错:Cannot create PoolableCon ...