开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第32天,点击查看活动详情
Redis多机数据库-集群
Redis集群是Redis提供的分布式数据库方案,集群通过分片来进行数据共享,并提供复制和故障转移功能
节点
- 多个独立的节点连接起来,就可以构成一个包含多个节点的集群
- 节点通过握手来将其它节点加到自己所处的集群当中
- 连接各个节点的工作可以使用CLUSTER MEET命令完成
- 向一个节点node发送CLUSTER MEET命令,可以让node节点与ip和port所指定的节点进行握手.当握手成功时,node节点会将ip和port所指定的节点添加到node节点当前所在的集群中
- CLUSTER NODES会展示集群相关信息
- 根据config中的cluster-enabled判断是否为yes决定是否开启服务器的集群模式
- 将节点B添加到节点A所在集群中的步骤
- A> CLUSTER MEET B
- 收到命令的节点A会与节点B进行握手,以此来确认彼此的存在
- 节点A会为节点B创建一个clusterNode结构,并将该结构添加到自己的clusterState.nodes字典里面
- 节点A会根据CLUSTER MEET命令给定的IP地址和端口号,向节点B发送一条MEET消息[message]
- 如果一切顺利,节点B将接收到节点A发送的MEET消息,节点B会为节点A创建一个clusterNode结构,并将该结构添加到自己的clusterState.nodes字典中
- 节点B向节点A返回一条PONG消息
- 节点A接收到节点B返回的PONG消息后,会再向节点B返回一条PING消息
- 节点B接收到节点A返回的PING消息,完成握手
槽指派
- Redis集群通过分片的方式来保存数据库中的键值对
- 集群的整个数据库都被分为16384个槽,数据库中的每个键都属于这个16384个槽中的一个
- 集群中的每个节点最多可以处理16384个槽,最少处理0个槽
- 集群中的16384个槽可以分别指派给集群中的各个节点,每个节点都会记录哪些槽指派给了自己,而哪些槽又被指派给了其它节点
命令执行
当客户端向节点发送与数据库键相关的命令时,接收命令的节点会计算出命令要处理的数据库键属于哪个槽,并检查这个槽是否指派给了自己.如果键所在的槽正好就指派给了当前节点,那么节点就直接执行这个命令,否则节点会向客户端返回一个MOVED错误,指引客户端转向至正确的节点,并再次发送之前想要执行的命令
重新分片
Redis集群的重新分片操作可以将任意数量已经指派给某个节点(源节点)的槽改为指派给另一个节点(目标节点),并且相关槽所属的键值对也会从源节点被移动的到目标节点
重新分片操作可以在线进行,在重新分片的过程中,集群不需要下线,并且源节点和目标节点都可以继续处理命令请求
对Redis集群的重新分片工作由redis-trib负责执行的,重新分片的关键是将属于某个槽的所有键值对从一个节点转移至另一个节点
转向
- ASK错误
- ASK错误是两个节点在迁移槽的过程中使用的一种临时措施: 在客户端收到关于槽I的MOVED错误后,客户端只会在接下来的一次命令请求中将关于槽I的命令请求时,都可以直接将命令请求发送至MOVED错误所指向的节点
- MOVED错误
- MOVED错误代表槽的负责权已经从一个节点转移到另一个节点: 在客户端收到关于槽I的MOVED错误之后,客户端每次遇到关于槽I的命令请求时,都可以直接将命令请求发送至MOVED错误所指向的节点,因为该节点就是目前负责槽I的节点
主从节点
Redis集群中的节点分为主节点(master)和从节点(slave),其中主节点用于处理槽,从节点用于复制某个主节点,并在被复制的主节点下线时,代替下线主节点继续处理命令请求
故障转移
- step1
节点 角色 状态 工作 7000 主节点 在线 负责处理槽0至槽5000 7001 主节点 在线 负责处理槽5001至槽10000 7002 主节点 在线 负责处理槽10001至槽15000 7003 主节点 在线 负责处理槽15001至槽16383 7004 从节点 在线 复制节点7000 7005 从节点 在线 复制节点7000 - step2
节点 角色 状态 工作 7000 主节点 下线 负责处理槽0至槽5000(因为故障转移已经完成,所以该工作已经无效) 7001 主节点 在线 负责处理槽5001至槽10000 7002 主节点 在线 负责处理槽10001至槽15000 7003 主节点 在线 负责处理槽15001至槽16383 7004 主节点 在线 负责处理槽0至槽5000 7005 从节点 在线 复制节点7004 - step3
节点 角色 状态 工作 7000 从节点 上线 复制节点7004 7001 主节点 在线 负责处理槽5001至槽10000 7002 主节点 在线 负责处理槽10001至槽15000 7003 主节点 在线 负责处理槽15001至槽16383 7004 主节点 在线 负责处理槽0至槽5000 7005 从节点 在线 复制节点7004 - 故障转移执行步骤
- 复制下线主节点的所有从节点里面,会由一个从节点被选中
- 被选中的从节点会执行SLAVEOF no one命令,成为新的主节点
- 新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己
- 新的主节点向集群广播一条PONG消息,这条PONG消息可以让集群中的其他几点立即知道这个几点已经由从节点变成了主节点,并且这个主节点已经接管了原本由已下线节点负责处理的槽
- 新的主节点开始接受和自己负责处理的槽有关的命令请求,转移故障完成
消息
集群中的节点通过发送和接收消息进行通信,常见的消息包括MEET、PING、PONG、PUBLISH、FALL五种
- MEET
- 当发送者接到客户端发送的CLUSTER MEET命令时,发送者会向接收者发送MEET消息,请求接受者加入到发送者当前所处的集群里面
- PING
- 集群里的每个节点默认每隔一秒钟就会从已知节点列表中随机选出五个节点,然后对这五个节点中最长 时间没有发送过PING消息的节点发送PING消息,以此来检测被选中的节点是否在线
- PONG
- 当接收者收到发送者发来的MEET消息或者PING消息时,为了向发送者确认这条MEET消息或者PING消息已到达,接收者会返回一条PONG消息
- 一个节点也可以通过PONG消息让集群中其它节点刷新对自己的认识,用在故障转移之后
- FAIL
- 当一个主节点A判断另一个主节点B已经进入FAIL状态时,节点A会向集群广播一条关于节点B的FAIL消息,所有接收到这条消息的节点都会立即将节点B标记为下线
- PUBLISH
- 当节点接收到一个PUBLISH命令时,节点会执行这个命令,并向集群广播一条PUBLISH消息,所有接收到这条PUBLISH消息的节点都会执行想用的PUBLISH命令