手撸Redis的无中心化集群

167 阅读3分钟
  • Redis 集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N。

  • Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。

  • 一个集群至少有3个master,新master的选举需要大于半数的集群master节点同意才能选举成功,如果只有两个master节点,其中一个宕机了,达不到选举新master的条件。

1. 集群设计方案

单机实现伪集群,我们设定三主三从,端口分别为:6379,6380,6381,6389,6390,6391

1.1 拷贝6份 redis.conf

  • 拷贝6份 redis.conf,放在cluster文件夹同一管理 image.png

1.2 分别修改各节点配置文件

daemonize yes
bind 127.0.0.1
dir /datas/redis-6.2.4/cluster/
port 6379
dbfilename dump_6379.rdb
pidfile /var/run/redis_6379.pid
logfile "./log-6379.log"
################################ REDIS CLUSTER  ###############################
# 开启集群设置
cluster-enabled yes
# 设置节点配置文件
cluster-config-file node-6379.conf
# 设置节点失联时间,超过该时间(毫秒),集群自动进行主从切换
cluster-node-timeout 15000

1.3 分别启动各节点

image.png

  • 启动后会在cluster文件夹中生成各自节点的nodes文件

image.png

1.4 使用集群创建指令创建集群

# redis-cli --cluster create --cluster-replicas 1 ip:端口
./redis-cli --cluster create --cluster-replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6389 127.0.0.1:6390 127.0.0.1:6391

如出现 [ERR] Node 127.0.0.1:6379 NOAUTH Authentication required.则需要在指令后面加上-a 密码

image.png 执行成功过程中需要输入yes,之后方可搭建成功。 image.png

image.png

1.5 查看集群信息

  • 查看集群节点信息,我们可以看到各节点的角色,同时在slave节点上附带了对应master的id,例如:6391从节点上附带的1edd38c43546e4ee539436ed2e3adc6859a2993c是6380主节点的id。
[root@17:35 src]# redis-cli -h 127.0.0.1 -p 6379 -a 123456
127.0.0.1:6379> cluster nodes

image.png

2. 集群的插槽(slots)

  • 在6379设置值后,进入6380节点设置时报(error) MOVED 1153 127.0.0.1:6379

image.png

在Redis集群中包含 16384插槽(slots),合并成集合的时候,会将每个slots映射到一个master上。例如:上面的三个master,映射范围如下:

Redis主节点插槽(slots)范围
master1(6379)[0-5460] 0是开始位置,表示第一个插槽
master2(6380)[5460-10922]
master3(6381)[10922-16383]
slave1,slave2,slave3从节点没有插槽,slave是用来对master做替补

而每个写入数据的key通过CRC16(key) % 16384运算后得到slots的位置,其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和,然后根据slots与master的映射关系找到对应的redis节点,然后将数据写入的对应的master中。

2.1 集群中录入值

  • redis-cli 每次录入、查询键值,redis都会计算出该key应该送往的插槽,如果不是该客户端对应服务器的插槽,redis会报错,并告知应前往的redis实例地址和端口。

  • redis-cli客户端提供了–c参数实现自动重定向。

image.png

  • 不在一个slot下的键值,是不能使用mget,mset等多键操作。

image.png

  • 可在mset stohox{group1} 110key值后面加{}分组信息,实现多间操作

image.png

2.2 集群值的查询

cluster keyslot group1
cluster countkeysinslot 7859
cluster getkeysinslot 7859 10

image.png

3. 集群的故障恢复

cluster-require-full-coverage 为 yes :如果某一段插槽的主从都挂掉,整个集群都挂掉

cluster-require-full-coverage 为 no :如果某一段插槽的主从都挂掉,该插槽数据全都不能使用,也无法存储。

  • 如果主节点下线,从节点会自动升为主节点;主节点恢复后,主节点回来变成从节点。