redis学习笔记——第九章 集群

第十章 集群

10.1 虚拟槽分区

在这里插入图片描述

	虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数集合中,整数定义为槽(slot)。这个范围一般远远大于节点数,比如Redis Cluster槽范围是0~16383。槽是集群内数据管理和迁移的基本单位。采用大范围槽的主要目的是为了方便数据拆分和集群扩展。每个节点会负责一定数量的槽
	当前集群有5个节点,每个节点平均大约负责3276个槽。由于采用高质量的哈希算法,每个槽所映射的数据通常比较均匀,将数据平均划分到5个节点进行数据分区。Redis Cluster就是采用虚拟槽分区
10.1.2 Redis数据分区

​ Redis Cluser采用虚拟槽分区,所有的键根据哈希函数映射到0~16383整数槽内,计算公式:slot=CRC16(key)&16383。每一个节点负责维护一部分槽以及槽所映射的键值数据

在这里插入图片描述
Redis虚拟槽分区的特点:

  1. 解耦数据和节点之间的关系,简化了节点扩容和收缩难度
  2. 节点自身维护槽的映射关系,不需要客户端或者代理服务维护槽分区元数据。
  3. 支持节点、槽、键之间的映射查询,用于数据路由、在线伸缩等场景。
10.1.3 集群功能限制

Redis集群相对单机在功能上存在一些限制,需要开发人员提前了解,在使用时做好规避。限制如下:

  1. key批量操作支持有限。如mset、mget,目前只支持具有相同slot值的key执行批量操作。对于映射为不同slot值的key由于执行mget、mget等操作可能存在于多个节点上因此不被支持
  2. .key事务操作支持有限。同理只支持多key在同一节点上的事务操作,当多个key分布在不同的节点上时无法使用事务功能
  3. key作为数据分区的最小粒度,因此不能将一个大的键值对象如hash、list等映射到不同的节点
  4. 不支持多数据库空间。单机下的Redis可以支持16个数据库,集群模式下只能使用一个数据库空间,即db0。
  5. 复制结构只支持一层,从节点只能复制主节点,不支持嵌套树状复制结构。

10.2 搭建集群

搭建集群工作需要以下三个步骤:

1)准备节点。
2)节点握手。
3)分配槽。

10.2.1 准备节点

​ Redis集群一般由多个节点组成,节点数量至少为6个才能保证组成完整高可用的集群。每个节点需要开启配置cluster-enabled yes,让Redis运行在集群模式下 ,建议为集群内所有节点统一目录,一般划分三个目录:conf、data、log,分别存放配置、数据和日志相关文件。把6个节点配置统一放在conf目录下,集群相关配置如下:

#节点端口
port 6379
# 开启集群模式
cluster-enabled yes
# 节点超时时间,单位毫秒
cluster-node-timeout 15000
# 集群内部配置文件
cluster-config-file "nodes-6379.conf"

其他配置和单机模式一致即可,配置文件命名规则redis-{port}.conf,准备好配置后启动所有节点,命令如下:

redis-server conf/redis-6379.conf
redis-server conf/redis-6380.conf
redis-server conf/redis-6381.conf
redis-server conf/redis-6382.conf
redis-server conf/redis-6383.conf
redis-server conf/redis-6384.conf
10.2.2 节点握手

6379节点启动成功,第一次启动时如果没有集群配置文件,它会自动创建一份,文件名称采用cluster-config-file参数项控制,建议采用node-{port}.conf格式定义,通过使用端口号区分不同节点,防止同一机器下多个
节点彼此覆盖,造成集群信息异常。如果启动时存在集群配置文件,节点会使用配置文件内容初始化集群信息
在这里插入图片描述
​ 集群模式的Redis除了原有的配置文件之外又加了一份集群配置文件。当集群内节点信息发生变化,如添加节点、节点下线、故障转移等。节点会自动保存集群状态到配置文件中。需要注意的是,Redis自动维护集群配置
文件,不要手动修改,防止节点重启时产生集群信息错乱。

​ 每个节点目前只能识别出自己的节点信息。我们启动6个节点,但每个节点彼此并不知道对方的存在,下面通过节点握手让6个节点彼此建立联系从而组成一个集群。

​ 节点握手是指一批运行在集群模式下的节点通过Gossip协议彼此通信,达到感知对方的过程。节点握手是集群彼此通信的第一步,由客户端发起命令:cluster meet{ip}{port}

集群无法完成槽到节点的映射。只有当16384个槽全部分配给节点后,集群才进入在线状态
在这里插入图片描述

10.2.3 分配槽

​ Redis集群把所有的数据映射到16384个槽中。每个key会映射为一个固定的槽,只有当节点分配了槽,才能响应和这些槽关联的键命令,通过cluster addslots命令为节点分配槽。这里利用bash特性批量设置槽(slots)

redis-cli -h 127.0.0.1 -p 6379 cluster addslots {0...5461}
redis-cli -h 127.0.0.1 -p 6380 cluster addslots {5462...10922}
redis-cli -h 127.0.0.1 -p 6381 cluster addslots {10923...16383}

​ 当前集群状态是OK,集群进入在线状态。所有的槽都已经分配给节点,执行cluster nodes命令可以看到节点和槽的分配关系

​ 目前还有三个节点没有使用,作为一个完整的集群,每个负责处理槽的节点应该具有从节点,保证当它出现故障时可以自动进行故障转移。使用cluster replicate{nodeId}命令让一个节点成为从节点,其中命令执行必须在对应的从节点上执行,nodeId是要复制主节点的节点ID

​ 目前为止,我们依照Redis协议手动建立一个集群。它由6个节点构成,3个主节点负责处理槽和相关数据,3个从节点负责故障转移

10.2.4 用redis-trib.rb搭建集群
  1. Ruby环境准备

  2. 准备节点

    redis-server conf/redis-6481.conf
    redis-server conf/redis-6482.conf
    redis-server conf/redis-6483.conf
    redis-server conf/redis-6484.conf
    redis-server conf/redis-6485.conf
    redis-server conf/redis-6486.conf
    
  3. 创建集群

    redis-trib.rb create --replicas 1 127.0.0.1:6481 127.0.0.1:6482 127.0.0.1:6483
    127.0.0.1:6484 127.0.0.1:6485 127.0.0.1:6486
    --replicas参数指定集群中每个主节点配备几个从节点,这里设置为1。
    
  4. 集群完整性检查

    可以使用redis-trib.rb check命令检测之前创建的两个集群是否成功,check命令只需要给出集群中任意一个节点地址就可以完成整个集群的检查工作,
        redis-trib.rb check 127.0.0.1:6379
        redis-trib.rb check 127.0.0.1:6481
    当最后输出如下信息,提示集群所有的槽都已分配到节点:
        [OK] All nodes agree about slots configuration.
        >>> Check for open slots...
        >>> Check slots coverage...
        [OK] All 16384 slots covered.
    
    

10.3节点通信

10.3.1 通信流程

​ Redis集群采用P2P的Gossip(流言)协议,Gossip协议工作原理就是节点彼此不断通信交换信息,一段时间后所有的节点都会知道集群完整的信息,这种方式类似流言传播

在这里插入图片描述

10.4 集群伸缩

10.4.1 伸缩原理

​ Redis集群提供了灵活的节点扩容和收缩方案。在不影响集群对外服务的情况下,可以为集群添加节点进行扩容也可以下线部分节点进行缩容,Redis集群可以实现对节点的灵活上下线控制。其中原理可抽象为槽和对应数据在不同节点之间灵活移动

10.4.2 扩容集群

扩容是分布式存储最常见的需求,Redis集群扩容操作可分为如下步骤:

  1. 准备新节点

    redis-server conf/redis-6385.conf
    redis-server conf/redis-6386.conf
    启动后的新节点作为孤儿节点运行,并没有其他节点与之通信
    
  2. 加入集群

    新节点依然采用cluster meet命令加入到现有集群中。在集群内任意节点执行cluster meet命令让6385和6386节点加入进来
    127.0.0.1:6379> cluster meet 127.0.0.1 6385
    127.0.0.1:6379> cluster meet 127.0.0.1 6386
    

    新节点刚开始都是主节点状态,但是由于没有负责的槽,所以不能任何读写操作。对于新节点的后续操作我们一般有两种选择:

    1. 为它迁移槽和数据实现扩容。
    2. ·作为其他主节点的从节点负责故障转移

redis-trib.rb工具也实现了为现有集群添加新节点的命令,还实现了直接添加为从节点的支持,命令如下:

redis-trib.rb add-node new_host:new_port existing_host:existing_port --slave --master-id <arg>

3.迁移槽和数据

​ 加入集群后需要为新节点迁移槽和相关数据,槽在迁移过程中集群可以正常提供读写服务,迁移过程是集群扩容最核心的环节
在这里插入图片描述

10.4.3 收缩集群

​ 收缩集群意味着缩减规模,需要从现有集群中安全下线部分节点.
在这里插入图片描述

  1. 首先需要确定下线节点是否有负责的槽,如果是,需要把槽迁移到其他节点,保证节点下线后整个集群槽节点映射的完整性
  2. 当下线节点不再负责槽或者本身是从节点时,就可以通知集群内其他节点忘记下线节点,当所有的节点忘记该节点后可以正常关闭

10.5 请求路由

10.5.1 请求重定向

​ 在集群模式下,Redis接收任何键相关命令时首先计算键对应的槽,再根据槽找出所对应的节点,如果节点是自身,则处理键命令;否则回复MOVED重定向错误,通知客户端请求正确的节点。这个过程称为MOVED重定向

10.5.2 ASK重定向

​ ASK与MOVED虽然都是对客户端的重定向控制,但是有着本质区别。ASK重定向说明集群正在进行slot数据迁移,客户端无法知道什么时候迁移完成,因此只能是临时性的重定向,客户端不会更新slots缓存。但是MOVED重定向说明键对应的槽已经明确指定到新的节点,因此需要更新slots缓存。

10.6 故障转移

10.6.1 故障发现

主观下线:指某个节点认为另一个节点不可用,即下线状态,这个状态并不是最终的故障判定,只能代表一个节点的意见,可能存在误判情况。
·客观下线:指标记一个节点真正的下线,集群内多个节点都认为该节点不可用,从而达成共识的结果。如果是持有槽的主节点故障,需要为该节点进行故障转移。

本章重点回顾

  1. Redis集群数据分区规则采用虚拟槽方式,所有的键映射到16384个槽中,每个节点负责一部分槽和相关数据,实现数据和请求的负载均衡。
  2. 搭建集群划分三个步骤:准备节点,节点握手,分配槽。可以使用redis-trib.rb create命令快速搭建集群。
  3. 集群内部节点通信采用Gossip协议彼此发送消息,消息类型分为:ping消息、pong消息、meet消息、fail消息等。节点定期不断发送和接受ping/pong消息来维护更新集群的状态。消息内容包括节点自身数据和部分其
    他节点的状态数据。
  4. 集群伸缩通过在节点之间移动槽和相关数据实现。扩容时根据槽迁移计划把槽从源节点迁移到目标节点,源节点负责的槽相比之前变少从而达到集群扩容的目的,收缩时如果下线的节点有负责的槽需要迁移到其他节
    点,再通过cluster forget命令让集群内其他节点忘记被下线节点
  5. 使用Smart客户端操作集群达到通信效率最大化,客户端内部负责计算维护键→槽→节点的映射,用于快速定位键命令到目标节点。集群协议通过Smart客户端全面高效的支持需要一个过程,用户在选择Smart客户端时建议review下集群交互代码如:异常判定和重试逻辑,更新槽的并发控制等。节点接收到键命令时会判断相关的槽是否由自身节点负责,如果不是则返回重定向信息。重定向分为MOVED和ASK,ASK说明集群正在进行槽数据迁移,客户端只在本次请求中做临时重定向,不会更新本地槽缓存。MOVED重定向说明槽已经明确分派到另一个节点,客户端需要更新槽节点缓存。
  6. 集群自动故障转移过程分为故障发现和故障恢复。节点下线分为主观下线和客观下线,当超过半数主节点认为故障节点为主观下线时标记它为客观下线状态。从节点负责对客观下线的主节点触发故障恢复流程,保证集
    群的可用性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值