当前位置: 首页 > article >正文

Redis 集群(Cluster)和基础的操作 部署实操篇

三主三从

集群概念
Redis 的哨兵模式,提高了系统的可用性,但是正在用来存储数据的还是 master 和 slave 节点,所有的数据都需要存储在单个 master 和 salve 节点中。

如果数据量很大,接近超出了 master / slave 所在机器的物理内存,就可能出现严重问题了。

虽然硬件价格在不断降低,一些中大厂的服务器内存已经可以达到 TB 级别了,但是1TB 在当前这个“大数据”时代,俨然不算什么,有的时候我们确实需要更大的内存空间来保存更多的数据。

Redis 的集群就是在上述的思路之下,引入多组 master / slave,每一组 master / slave 存储数据全集的一部分,从而构成一个更大的整体,称为 Redis 集群(Cluster)。

假定整个数据全集是1TB,引入三组 master / slave来存储。那么每⼀组机器只需要存储整个数据全集的 1/3 即可。

  • Master1 和 Slave11 和 Slave12 保存的是同样的数据占总数据的 1/3
  • Master2 和 Slave21 和 Slave22 保存的是同样的数据占总数据的 1/3
  • Master3 和 Slave31 和 Slave32 保存的是同样的数据占总数据的 1/3

这三组机器存储的数据都是不同的

每个 Slave 都是对应 Master 的备份(当 Master 挂了,对应的 Slave 会补位成 Master)。

每个红框部分都可以称为是一个分片(Sharding)

如果全量数据进一步增加,只要再增加更多的分片,即可解决。

可能有的人认为,数据量多了,使用硬盘来保存不就行了?不要忘了硬盘只是存储多了,但是访问速度是比内存慢很多的。但是事实上,还是存在很多的应用场景,既希望存储较多的数据,又希望有非常高的读写速度。

数据分片算法

Redis cluster 的核心思路是用多组机器来存数据的每个部分,那么接下来的核心问题就是,给定一个数据(一个具体的 key)那么这个数据应该存储在哪个分片上?读取的时候又应该去哪个分片读取?

围绕这个问题,业界有三种比较主流的实现方式

哈希求余
设有N个分片,使用 [0,N-1] 这样序号进行编号

针对某个给定的 key,先计算 hash 值,再把得到的结果%N,得到的结果即为分片编号。

例如,N为3。给定 key 为 hello,对 hello 计算 hash 值(比如使用 md5 算法),得到的结果为bc4b2a76b9719d91,再把这个结果 %3,结果为 0,那么就把 hello 这个 key 放到 0 号分片上。当然,实际工作中涉及到的系统,计算 hash 的方式不一定是 md5,但是思想是一致的。

后续如果要取某个 key 的记录,也是针对 key 计算 hash,再对 N 求余,就可以找到对应的分片编号

优缺点

优点:简单高效,数据分配均匀。

缺点:一旦需要进行扩容,N 改变了,原有的映射规则被破坏,就需要让节点之间的数据相互传输,重新排列,以满足新的映射规则此时需要搬运的数据量是比较多的,开销较大

一致性哈希算法


为了降低上述的搬运开销,能够更高效扩容,业界提出了“一致性哈希算法”。key 映射到分片序号的过程不再是简单求余了,而是改成以下过程:

第一步:把 0->2^32-1 这个数据空间,映射到⼀个圆环上。数据按照顺时针方向增长。

第二步:假设当前存在三个分片,就把分片放到圆环的某个位置上。

第三步:假定有⼀个 key,计算得到 hash 值 H,那么这个key映射到哪个分片呢?规则很简单,就是从 H 所在位置,顺时针往下找,找到的第⼀个分片,即为该 key 所从属的分片。

这就相当于,N个分片的位置,把整个圆环分成了 N 个管辖区间 key 的 hash 值落在某个区间内,就归对应区间管理。

在这个情况下,如果扩容一个分片,如何处理呢?

原有分片在环上的位置不动,只要在环上新安排一个分片位置即可。

优缺点

优点:大大降低了扩容时数据搬运的规模,提高了扩容操作的效率。

缺点:数据分配不均匀(有的多有的少,数据倾斜)

hash slots算法(Redis 使用)

为了解决上述问题(搬运成本高和数据分配不均),Redis cluster 引入了哈希槽(hash slots)算法。

hash_slot = crc16(key) % 16384 #crc16也是⼀种hash算法,16384其实是16*1024,也就是2^14

相当于是把整个哈希值,映射到 16384 个槽位上,也就是 [0,16383]。

然后再把这些槽位比较均匀的分配给每个分片,每个分片的节点都需要记录自己持有哪些槽位。

假设当前有三个分片,一种可能的分配方式:

  • 0号分片:[0,5461],共 5462 个槽位
  • 1号分片:[5462,10923],共 5462 个槽位
  • 2号分片:[10924,16383],共5460个槽位

这里的分片规则是很灵活的,每个分片持有的槽位也不一定连续。

每个分片的节点使用位图来表示自己持有哪些槽位,对于 16384 个槽位来说,需要 2048 个字节(2KB)大小的内存空间表示

如果需要进行扩容比如新增一个3 号分片就可以针对原有的槽位进行重新分配。

比如可以把之前每个分片持有的槽位,各拿出一点,分给新分片

一种可能的分配方式:

  • 0号分片:[0,40951],共 4096 个槽位
  • 1号分片:[5462,9557],共 4096 个槽位
  • 2号分片:[10924,15019],共 4096个槽位
  • 3号分片:[4096,5461] +[9558,10923]+[15019,16383],共 4096 个槽位

我们在实际使用 Redis 集群分片的时候,不需要手动指定哪些槽位分配给某个分片,只需要告诉某个分片应该持有多少个槽位即可,Redis 会自动完成后续的槽位分配。以及对应的 key 搬运的工作

此处还有两个问题:

问题一:Redis集群是最多有16384个分片吗?

并非如此,如果一个分片只有一个槽位,这对于集群的数据均匀其实是难以保证的。

实际上 Redis 的作者建议集群分片数不应该超过1000。

而且,16000 这么大规模的集群,本身的可用性也是一个大问题,一个系统越复杂,出现故障的概率是越高的。

问题二:为什么是16384个槽位?

  • 节点之间通过心跳包通信,心跳包中包含了该节点持有哪些 slots,这个是使用位图这样的数据结构表示的,表示16384(16k) 个 slots,需要的位图大小是2KB。如果给定的 slots 数更多了,比如 65536 个了,此时就需要消耗更多的空间,8 KB 位图表示了 8KB,对于内存来说不算什么,但是在频繁的网络心跳包中,还是一个不小的开销的。
  • 另一方面,Redis 集群一般不建议超过 1000 个分片所以 16k 对于最大 1000个分片来说是足够用的,同时也会使对应的槽位配置位图体积不至于很大。

集群搭建(基于 docker)

接下来基于 docker,搭建一个集群每个节点都是一个容器

此处我们先创建出 11 个 redis 节点,其中前 9 个用来演示集群的搭建,后两个用来演示集群扩容

第一步:生成配置文件

[root@localhost redis]# cat conf/redis.conf 
port 6379
bind 0.0.0.0
protected-mode no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip  172.16.10.42
cluster-announce-port 6379
cluster-announce-bus-port 16379


[root@localhost redis]# cat conf/generate.sh 
for port in $(seq 1 3); \
do \
mkdir -p redis${port}/
touch redis${port}/redis.conf
cat << EOF > redis${port}/redis.conf
port 6379
bind 0.0.0.0
protected-mode no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip  172.16.10.4${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
EOF
done
for port in $(seq 4 6); \
do \
mkdir -p redis${port}/
touch redis${port}/redis.conf
cat << EOF > redis${port}/redis.conf
port 6379
bind 0.0.0.0
protected-mode no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.16.10.4.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
EOF
done
  • bind:指定Redis服务绑定的IP地址。在本例中,使用0.0.0.0表示服务将绑定到所有可用的IPv4地址上。
  • daemonize:决定Redis是否以守护进程方式运行。当设置为yes时,Redis将在后台运行,不会向终端输出日志信息。
  • protected-mode:控制Redis是否启用保护模式。当设置为no时,Redis将不会检查访问请求是否来自本地主机。
  • port:指定Redis服务监听的端口号。在本例中,服务将监听6381端口。
  • logfile:指定Redis日志文件的路径和文件名。在本例中,日志将写入/myredis/cluster/cluster6381.log文件。
  • pidfile:指定Redis进程ID文件的路径和文件名。在本例中,文件名为cluster6381.pid。
  • dir:指定Redis数据库文件和AOF文件所在的目录。在本例中,它们将存储在/myredis/cluster目录下。
  • dbfilename:指定Redis数据库文件的文件名。在本例中,文件名为dump6381.rdb。
  • appendonly:决定Redis是否启用AOF持久化。当设置为yes时,Redis将记录所有修改操作,并将其写入AOF文件中。
  • appendfilename:指定AOF文件的文件名。在本例中,文件名为appendonly6381.aof。
  • requirepass:设置Redis的访问密码。在本例中,密码为111111。
  • masterauth:设置Redis主节点的访问密码。在本例中,主节点密码也为111111。
  • cluster-enabled:决定Redis是否启用集群模式。当设置为yes时,Redis将启用集群模式。
  • cluster-config-file:指定Redis集群配置文件的路径和文件名。在本例中,文件名为nodes-6381.conf。
  • cluster-node-timeout:指定Redis集群节点之间的超时时间。在本例中,超时时间为5000毫秒

[root@localhost redis]# 
[root@localhost redis]# pwd
/opt/redis
[root@localhost redis]# tree
.
├── conf
│   ├── generate.sh
│   └── redis.conf
└── data
    ├── appendonly.aof
    ├── dump.rdb
    └── nodes.conf

2 directories, 5 files

三主三从 6台机器

启动服务器

[root@localhost redis]# docker run -it  --rm --name redis1 -p 6379:6379 -p 16379:16379 -v /opt/redis/conf:/etc/redis/ -v /opt/redis/data:/data -d --sysctl net.core.somaxconn=1024  harbor.jettech.com/jettechtools/redis:6.2 redis-server /etc/redis/redis.conf

创建集群 

root@f604b21ceae6:/# redis-cli  --cluster create 172.16.10.41:6379 172.16.10.42:6379 172.16.10.43:6379 172.16.10.44:6379 172.16.10.45:6379 172.16.10.46:6379  --cluster-replicas 1
  • cluster create 表示建立集群。后面填写每个节点的 ip 和地址
  • cluster-replicas 1 表示每个主节点需要1个从节点备份

日志中会描述哪些是主节点,哪些从节点跟随哪个主节点。 

root@e68581597b49:/data# redis-cli --cluster create 172.16.10.41:6379 172.16.10.42:6379 172.16.10.43:6379 172.16.10.44:6379 172.16.10.45:6379 172.16.10.46:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.16.10.45:6379 to 172.16.10.41:6379
Adding replica 172.16.10.46:6379 to 172.16.10.42:6379
Adding replica 172.16.10.44:6379 to 172.16.10.43:6379
M: d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379
   slots:[0-5460] (5461 slots) master
M: f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379
   slots:[5461-10922] (5462 slots) master
M: 32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379
   slots:[10923-16383] (5461 slots) master
S: e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379
   replicates 32971a9019d7ea5a9e50816e672e542743632d7b
S: 769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379
   replicates d34ed66ac525de9ce5a2f8c84e554ef4ac947a66
S: eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379
   replicates f1eebb36879bc2679b08432f5012da29b0e3e5a7
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 172.16.10.41:6379)
M: d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379
   slots: (0 slots) slave
   replicates f1eebb36879bc2679b08432f5012da29b0e3e5a7
M: f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379
   slots: (0 slots) slave
   replicates 32971a9019d7ea5a9e50816e672e542743632d7b
S: 769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379
   slots: (0 slots) slave
   replicates d34ed66ac525de9ce5a2f8c84e554ef4ac947a66
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

见到下方的[OK]说明集群建立完成。

此时,使用客户端连上集群中的任何一个节点,都相当于连上了整个集群。

  • 客户端后面要加上 -c 选项,否则如果 key 没有落到当前节点上,是不能操作的。-c 会自动把请求重定向到对应节点。也就是说 redis 客户端就会根据当前 key 实际算出来的槽位号,自动找到匹配的分片主机。
  • 使用 cluster nodes 可以查看到整个集群的情况.

root@e68581597b49:/data# redis-cli -h 172.16.10.41 -p 6379 -c
172.16.10.41:6379> cluster nodes
32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379@16379 master - 0 1739178328000 3 connected 10923-16383
d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379@16379 myself,master - 0 1739178327000 1 connected 0-5460
eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379@16379 slave f1eebb36879bc2679b08432f5012da29b0e3e5a7 0 1739178327000 2 connected
f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379@16379 master - 0 1739178328821 2 connected 5461-10922
e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379@16379 slave 32971a9019d7ea5a9e50816e672e542743632d7b 0 1739178328000 3 connected
769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379@16379 slave d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 0 1739178327818 1 connected


172.16.10.41:6379> set name wubo
-> Redirected to slot [5798] located at 172.16.10.42:6379
OK
172.16.10.42:6379> get name
"wubo"
172.16.10.42:6379> 

演示:

主节点宕机

演示效果

手动停止一个 master 节点,观察效果

比如上述拓扑结构中可以看到 redis1 redis2 redis3 是主节点随便挑一个停掉

关闭172.16.10.42

[root@localhost redis]# docker stop redis1
redis1
172.16.10.42:6379> cluster nodes
eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379@16379 slave f1eebb36879bc2679b08432f5012da29b0e3e5a7 0 1739178409733 2 connected
f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379@16379 myself,master - 0 1739178409000 2 connected 5461-10922
769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379@16379 slave d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 0 1739178408728 1 connected
32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379@16379 master - 0 1739178409000 3 connected 10923-16383
e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379@16379 slave 32971a9019d7ea5a9e50816e672e542743632d7b 0 1739178408000 3 connected
d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379@16379 master - 0 1739178409532 1 connected 0-5460
172.16.10.42:6379> cluster nodes
Error: Broken pipe
172.16.10.42:6379> 
root@e68581597b49:/data# redis-cli -h 172.16.10.41 -p 6379 -c
172.16.10.41:6379> cluster nodes
32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379@16379 master - 0 1739178455659 3 connected 10923-16383
d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379@16379 myself,master - 0 1739178456000 1 connected 0-5460
eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379@16379 master - 0 1739178455000 7 connected 5461-10922
f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379@16379 master,fail - 1739178425853 1739178423327 2 disconnected
e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379@16379 slave 32971a9019d7ea5a9e50816e672e542743632d7b 0 1739178456669 3 connected
769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379@16379 slave d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 0 1739178455558 1 connected

可以看到 172.16.10.42 已经提示 fail,然后原本是 slave 的172.16.10.46成了新的 master.

重新启动172.16.10.42  redis1

docker start redis1
172.16.10.41:6379> cluster nodes
32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379@16379 master - 0 1739178609000 3 connected 10923-16383
d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379@16379 myself,master - 0 1739178607000 1 connected 0-5460
eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379@16379 master - 0 1739178609167 7 connected 5461-10922
f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379@16379 slave eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 0 1739178609771 7 connected
e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379@16379 slave 32971a9019d7ea5a9e50816e672e542743632d7b 0 1739178609000 3 connected
769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379@16379 slave d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 0 1739178609000 1 connected

再次观察结果可以看到 172.16.10.42 启动了仍然是 slave。

可以使用 cluster failover 进行集群恢复也就是把172.16.10.42 重新设定成 master.(登录到 172.16.10.42 上执行)

root@e68581597b49:/data# redis-cli -h 172.16.10.42 -p 6379 -c
172.16.10.42:6379> cluster failover
OK
172.16.10.42:6379> cluster nodes
e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379@16379 slave 32971a9019d7ea5a9e50816e672e542743632d7b 0 1739178665756 3 connected
f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379@16379 myself,master - 0 1739178664000 8 connected 5461-10922
d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379@16379 master - 0 1739178665555 1 connected 0-5460
eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379@16379 slave f1eebb36879bc2679b08432f5012da29b0e3e5a7 0 1739178665555 8 connected
769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379@16379 slave d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 0 1739178665000 1 connected
32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379@16379 master - 0 1739178665000 3 connected 10923-16383

此时可以看到 172.16.10.42 重新变成了 master,而 172.16.10.46 又变回了 slave。

处理流程
故障判定
集群中的所有节点都会周期性的使用心跳包进行通信

  • 节点 A 给节点 B 发送 ping 包,B 就会给 A 返回一个 pong 包。ping 和 pong 除了 message type 属性之外,其他部分都是一样的。这里包含了集群的配置信息(该节点的id,该节点从属于哪个分片,是主节点还是从节点,从属于谁,持有哪些 slots 的位图…).
  • 每个节点,每秒钟,都会给一些随机的节点发起 ping 包,而不是全发一遍。这样设定是为了避免在节点很多的时候,心跳包也非常多(比如有 9 个节点,如果全发,就是 9*8 有 72 组心跳了而且这是按照 N^2 这样的级别增长的).
  • 当节点 A 给节点 B 发起 ping 包,不能如期回应的时候,此时 A 就会尝试重置和 B 的 tcp 连接,看能否连接成功如果仍然连接失败,A 就会把 B 设为 PFAIL 状态相当于主观下线)。
  • A 判定 B 为 PFAIL 之后,会通过 redis 内置的 Gossip 协议,和其他节点进行沟通,向其他节点确认 B 的状态.(每个节点都会维护一个自己的“下线列表"由于视角不同,每个节点的下线列表也不一定相同)。
  • 此时 A 发现其他很多节点也认为 B 为 PFAIL 并且数目超过总集群个数的一半,那么 A 就会把 B 标记成 FAIL(相当于客观下线),并且把这个消息同步给其他节点(其他节点收到之后,也会把 B 标记成FAIL)。

至此,B 就彻底被判定为故障节点了。

某个或者某些节点宕机有的时候会引起整个集群都宕机(称为 fail 状态)

以下三种情况会出现集群宕机:

某个分片,所有的主节点和从节点都挂了(该分片无法提供数据服务了)
某个分片,主节点挂了,但是没有从节点(该分片无法提供数据服务了)
超过半数的 master 节点都挂了(如果突然一系列的 master 都挂了,此时说明集群遇到了非常严重的情况)

核心原则是保证每个 slots 都能正常工作(存取数据)

故障迁移

上述例子中 B 故障。并且 A 把 B FAIL的消息告知集群中的其他节点。

  • 如果 B 是从节点那么不需要进行故障迁移
  • 如果 B 是主节点那么就会由 B 的从节点(比如C和D)触发故障迁移了

所谓故障迁移就是指把从节点提拔成主节点继续给整个 redis 集群提供支持

具体流程如下:

  • 从节点判定自己是否具有参选资格。如果从节点和主节点已经太久没通信(此时认为从节点的数据和主节点差异太大了),时间超过阐值,就失去竞选资格。
  • 具有资格的节点比如 C 和 D,就会先休眠一定时间。休眠时间 = 500ms 基础时间 + [0,500ms 随机时间 + 排名*1000ms。offset 的值越大,则排名越靠前(越小)。
  • 比如 C 的休眠时间到了,C 就会给其他所有集群中的节点进行拉票操作,但是只有主节点才有投票资格。
  • 主节点就会把自己的票投给 C(每个主节点只有1票),当 C 收到的票数超过主节点数目的一半,C 就会晋升成主节点(C自己负责执行slaveof no one,并且让 D 执行slave of C)。
  • 同时,C 还会把自己成为主节点的消息,同步给其他集群的节点,大家也都会更新自己保存的集群结构信息。

上述选举的过程称为 Raft 算法是一种在分布式系统中广泛使用的算法。

在随机休眠时间的加持下,基本上就是谁先唤醒,谁就能竞选成功

集群扩容

扩容是一个在开发中比较常遇到的场景

随着业务的发展,现有集群很可能无法容纳日益增长的数据此时给集群中加入更多新的机器,就可以使存储的空间更大了。

所谓分布式的本质,就是使用更多的机器引入更多的硬件资源

第一步:把新的主节点加入到集群

上面已经把 172.16.10.41, 172.16.10.42, 172.16.10.43, 172.16.10.44, 172.16.10.45, 172.16.10.46 重新构成了集群接下来把 172.16.10.47和 172.16.10.48也加入集群

此处我们把 172.16.10.47作为主机, 172.16.10.48作为从机

redis-cli --cluster add-node 172.16.10.47:6379 172.16.10.41:6379

add-node 后的第一组地址是新节点的地址,第二组地址是集群中的任意节点地址

root@e68581597b49:/data# redis-cli  --cluster add-node 172.16.10.47:6379 172.16.10.41:6379
>>> Adding node 172.16.10.47:6379 to cluster 172.16.10.41:6379
>>> Performing Cluster Check (using node 172.16.10.41:6379)
M: d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379
   slots: (0 slots) slave
   replicates f1eebb36879bc2679b08432f5012da29b0e3e5a7
M: f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379
   slots: (0 slots) slave
   replicates 32971a9019d7ea5a9e50816e672e542743632d7b
S: 769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379
   slots: (0 slots) slave
   replicates d34ed66ac525de9ce5a2f8c84e554ef4ac947a66
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 172.16.10.47:6379 to make it join the cluster.
[OK] New node added correctly.

此时的集群状态如下,可以看到172.16.10.47这个节点已经成为了集群中的主节点 

root@e68581597b49:/data# redis-cli -h 172.16.10.41 -p 6379 cluster nodes
32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379@16379 master - 0 1739178975000 3 connected 10923-16383
f6afbe3e3315b8b756144cb49742141713f7cee8 172.16.10.47:6379@16379 master - 0 1739178976110 0 connected
d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379@16379 myself,master - 0 1739178974000 1 connected 0-5460
eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379@16379 slave f1eebb36879bc2679b08432f5012da29b0e3e5a7 0 1739178974603 8 connected
f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379@16379 master - 0 1739178975506 8 connected 5461-10922
e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379@16379 slave 32971a9019d7ea5a9e50816e672e542743632d7b 0 1739178975000 3 connected
769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379@16379 slave d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 0 1739178975104 1 connected

第二步:重新分配 slots

root@e68581597b49:/data# redis-cli --cluster reshard 172.16.10.41:6379
>>> Performing Cluster Check (using node 172.16.10.41:6379)
M: d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: f6afbe3e3315b8b756144cb49742141713f7cee8 172.16.10.47:6379
   slots: (0 slots) master
S: eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379
   slots: (0 slots) slave
   replicates f1eebb36879bc2679b08432f5012da29b0e3e5a7
M: f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379
   slots: (0 slots) slave
   replicates 32971a9019d7ea5a9e50816e672e542743632d7b
S: 769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379
   slots: (0 slots) slave
   replicates d34ed66ac525de9ce5a2f8c84e554ef4ac947a66
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 4096
What is the receiving node ID? f6afbe3e3315b8b756144cb49742141713f7cee8
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
Source node #1: all

reshard 后的地址是集群中的任意节点地址

另外,注意单词拼写,是 reshard(重新切分),不是 reshared(重新分享),不要多写个 e。

执行之后,会进入交互式操作,redis 会提示用户输入以下内容:

  • 多少个 slots 要进行 reshard ?(此处我们填写 4096 =16384/4)。
  • 哪个节点来接收这些 slots ?(此处我们填写 172.16.10.47 这个节点的集群节点id)
  • 这些 slots 从哪些节点搬运过来?(此处我们填写 all,表示从其他所有的节点都进行搬运)

确定之后,会初步打印出搬运方案,让用户确认。

之后就会进行集群的 key 搬运工作这个过程涉及到数据搬运可能需要消耗一定的时间

在搬运 key 的过程中,对于那些不需要搬运的 key,访问的时候是没有任何问题的。但是对于需要搬运的 key,进行访问可能会出现短暂的访问错误(key 的位置出现了变化)。随着搬运完成,这样的错误自然就恢复了。因此,在进行扩容的时候,尽量选择访问量少的时候进行访问。

 第三步:给新的主节点添加从节点
光有主节点了。此时扩容的目标已经初步达成但是为了保证集群可用性。还需要给这个新的主节点添加从节点,保证该主节点宕机之后,有从节点能够顶上。

root@e68581597b49:/data# redis-cli --cluster add-node 172.16.10.48:6379 172.16.10.41:6379 --cluster-slave --cluster-master-id f6afbe3e3315b8b756144cb49742141713f7cee8
>>> Adding node 172.16.10.48:6379 to cluster 172.16.10.41:6379
>>> Performing Cluster Check (using node 172.16.10.41:6379)
M: d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379
   slots:[1365-5460] (4096 slots) master
   1 additional replica(s)
M: 32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
M: f6afbe3e3315b8b756144cb49742141713f7cee8 172.16.10.47:6379
   slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
S: eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379
   slots: (0 slots) slave
   replicates f1eebb36879bc2679b08432f5012da29b0e3e5a7
M: f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
S: e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379
   slots: (0 slots) slave
   replicates 32971a9019d7ea5a9e50816e672e542743632d7b
S: 769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379
   slots: (0 slots) slave
   replicates d34ed66ac525de9ce5a2f8c84e554ef4ac947a66
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 172.16.10.48:6379 to make it join the cluster.
Waiting for the cluster to join

>>> Configure node as replica of 172.16.10.47:6379.
[OK] New node added correctly.

查看  172.16.10.47 master的id

root@e68581597b49:/data# redis-cli --cluster check 172.16.10.47:6379
172.16.10.47:6379 (f6afbe3e...) -> 1 keys | 4096 slots | 1 slaves.
172.16.10.41:6379 (d34ed66a...) -> 0 keys | 4096 slots | 1 slaves.
172.16.10.43:6379 (32971a90...) -> 0 keys | 4096 slots | 1 slaves.
172.16.10.42:6379 (f1eebb36...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 1 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 172.16.10.47:6379)
M: f6afbe3e3315b8b756144cb49742141713f7cee8 172.16.10.47:6379
   slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
   1 additional replica(s)
S: eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379
   slots: (0 slots) slave
   replicates f1eebb36879bc2679b08432f5012da29b0e3e5a7
S: 58aa0783f38169f64eb23be72229e2c1c2331575 172.16.10.48:6379
   slots: (0 slots) slave
   replicates f6afbe3e3315b8b756144cb49742141713f7cee8
M: d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379
   slots:[1365-5460] (4096 slots) master
   1 additional replica(s)
M: 32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
M: f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
S: e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379
   slots: (0 slots) slave
   replicates 32971a9019d7ea5a9e50816e672e542743632d7b
S: 769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379
   slots: (0 slots) slave
   replicates d34ed66ac525de9ce5a2f8c84e554ef4ac947a66
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
root@e68581597b49:/data# 

查看从属关系

root@e68581597b49:/data# redis-cli cluster nodes
32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379@16379 master - 0 1739179413467 3 connected 12288-16383
f6afbe3e3315b8b756144cb49742141713f7cee8 172.16.10.47:6379@16379 master - 0 1739179413000 9 connected 0-1364 5461-6826 10923-12287
58aa0783f38169f64eb23be72229e2c1c2331575 172.16.10.48:6379@16379 slave f6afbe3e3315b8b756144cb49742141713f7cee8 0 1739179413000 9 connected
d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379@16379 myself,master - 0 1739179414000 1 connected 1365-5460
eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379@16379 slave f1eebb36879bc2679b08432f5012da29b0e3e5a7 0 1739179413000 8 connected
f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379@16379 master - 0 1739179413000 8 connected 6827-10922
e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379@16379 slave 32971a9019d7ea5a9e50816e672e542743632d7b 0 1739179414475 3 connected
769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379@16379 slave d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 0 1739179413971 1 connected

连接redis时带  -c 参数打开路由

命令使用:

root@e68581597b49:/data# redis-cli -c -p 6379 -h 172.16.10.41
172.16.10.41:6379> 

//集群(cluster) 
CLUSTER INFO 打印集群的信息 

172.16.10.41:6379> CLUSTER info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:8
cluster_size:4
cluster_current_epoch:9
cluster_my_epoch:1
cluster_stats_messages_ping_sent:2555
cluster_stats_messages_pong_sent:2535
cluster_stats_messages_auth-ack_sent:2
cluster_stats_messages_update_sent:4
cluster_stats_messages_sent:5096
cluster_stats_messages_ping_received:2528
cluster_stats_messages_pong_received:6652
cluster_stats_messages_meet_received:7
cluster_stats_messages_fail_received:1
cluster_stats_messages_auth-req_received:2
cluster_stats_messages_received:9190


CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。  

172.16.10.41:6379> cluster nodes
32971a9019d7ea5a9e50816e672e542743632d7b 172.16.10.43:6379@16379 master - 0 1739179552728 3 connected 12288-16383
f6afbe3e3315b8b756144cb49742141713f7cee8 172.16.10.47:6379@16379 master - 0 1739179553030 9 connected 0-1364 5461-6826 10923-12287
58aa0783f38169f64eb23be72229e2c1c2331575 172.16.10.48:6379@16379 slave f6afbe3e3315b8b756144cb49742141713f7cee8 0 1739179552026 9 connected
d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 172.16.10.41:6379@16379 myself,master - 0 1739179551000 1 connected 1365-5460
eb5655ffd0c8e2ab8be76bc5fd5ae680a82254c6 172.16.10.46:6379@16379 slave f1eebb36879bc2679b08432f5012da29b0e3e5a7 0 1739179552225 8 connected
f1eebb36879bc2679b08432f5012da29b0e3e5a7 172.16.10.42:6379@16379 master - 0 1739179551219 8 connected 6827-10922
e27ca51b5300138a94dd931006490d21eedb2b7a 172.16.10.44:6379@16379 slave 32971a9019d7ea5a9e50816e672e542743632d7b 0 1739179552000 3 connected
769885221734d36082e9c171e4402b1c2c2a0c55 172.16.10.45:6379@16379 slave d34ed66ac525de9ce5a2f8c84e554ef4ac947a66 0 1739179550717 1 connected

//节点(node) 
CLUSTER MEET <ip> <port> 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。 
CLUSTER FORGET <node_id> 从集群中移除 node_id 指定的节点。 
CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点。 
CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。  

//槽(slot) 
CLUSTER ADDSLOTS <slot> [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。 
CLUSTER DELSLOTS <slot> [slot ...] 移除一个或多个槽对当前节点的指派。 
CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。 
CLUSTER SETSLOT <slot> NODE <node_id> 将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。 
CLUSTER SETSLOT <slot> MIGRATING <node_id> 将本节点的槽 slot 迁移到 node_id 指定的节点中。 
CLUSTER SETSLOT <slot> IMPORTING <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。 
CLUSTER SETSLOT <slot> STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。  

//键 (key) 
CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。 
CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。 
CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。

1)新配置二个测试节点
# cd /etc/redis 
 
//新增配置 
//启动 
2)添加主节点
# redis-cli  add-node 172.16.10.47:6378 172.16.10.41:6379 
注释:
172.16.10.47:6378是新增的节点
172.16.10.41:6379集群任一个旧节点

3)添加从节点
# redis-cli   add-node --slave --master-id 03ccad2ba5dd1e062464bc7590400441fafb63f2(这个是172.16.10.47主节点的id) 172.16.10.48:6385 172.16.10.41:6379 
注释:
--slave,表示添加的是从节点
--master-id 03ccad2ba5dd1e062464bc7590400441fafb63f2,主节点的node id,在这里是前面新添加的6378的node id
172.16.10.48:6385,新节点
172.16.10.41:6379集群任一个旧节点

4)重新分配slot
#redis-cli   reshard 172.16.10.41:6378               //下面是主要过程 
How many slots do you want to move (from 1 to 16384)? 1000 //设置slot数1000 
What is the receiving node ID? 03ccad2ba5dd1e062464bc7590400441fafb63f2 //新节点node id 
Please enter all the source node IDs. 
 Type 'all' to use all the nodes as source nodes for the hash slots. 
 Type 'done' once you entered all the source nodes IDs. 
Source node #1:all                                      //表示全部节点重新洗牌 
Do you want to proceed with the proposed reshard plan (yes/no)? yes //确认重新分 

新增加的主节点,是没有slots的,
M: 03ccad2ba5dd1e062464bc7590400441fafb63f2 172.16.10.47:6378
slots:0-332,5461-5794,10923-11255 (0 slots) master
主节点如果没有slots的话,存取数据就都不会被选中。
可以把分配的过程理解成打扑克牌,all表示大家重新洗牌;输入某个主节点的node id,然后在输入done的话,就好比从某个节点,抽牌。

四、删除节点

 
1)删除从节点
# redis-cli  del-node 172.16.10.48:6385 9c240333476469e8e2c8e80b089c48f389827265

2)删除主节点
如果主节点有从节点,将从节点转移到其他主节点
如果主节点有slot,去掉分配的slot,然后在删除主节点
# redis-trib.rb reshard 172.16.10.47:6378                             //取消分配的slot,下面是主要过程 
How many slots do you want to move (from 1 to 16384)? 1000              //被删除master的所有slot数量 
What is the receiving node ID? 5d8ef5a7fbd72ac586bef04fa6de8a88c0671052 //接收6378节点slot的master 
Please enter all the source node IDs. 
 Type 'all' to use all the nodes as source nodes for the hash slots. 
 Type 'done' once you entered all the source nodes IDs. 
Source node #1:03ccad2ba5dd1e062464bc7590400441fafb63f2                //被删除master的node-id 
Source node #2:done  
   
Do you want to proceed with the proposed reshard plan (yes/no)? yes    //取消slot后,reshard 

新增master节点后,也进行了这一步操作,当时是分配,现在去掉。反着的。
#redis-cli del-node 172.16.10.47:6378 '03ccad2ba5dd1e062464bc7590400441fafb63f2' 
 
新的master节点被删除了,这样就回到了,就是这篇文章开头,还没有添加节点的状态

五、Redis缓存清理

 
1)登陆redis
# src/redis-cli -c -h 172.16.10.41 -p 6379
 
2)执行:
172.16.10.41:6379> dbsize
 
3)
172.16.10.41:6379> flushall
 
================================================================
redis集群指定key值得缓存清理:
1)登录至指定端口的redis服务器
# src/redis-cli -c -h 172.16.10.41 -p 6379
 
2)查看所有key值 (或者使用info命令也能查看出来)
keys *
 
3)删除指定索引的值
del key

redis cluster 命令整理如下:

[root@localhost bin]# ./redis-cli --cluster help
Cluster Manager Commands:
  create         host1:port1 ... hostN:portN
                 --cluster-replicas <arg>
  check          host:port
                 --cluster-search-multiple-owners
  info           host:port
  fix            host:port
                 --cluster-search-multiple-owners
                 --cluster-fix-with-unreachable-masters
  reshard        host:port
                 --cluster-from <arg>
                 --cluster-to <arg>
                 --cluster-slots <arg>
                 --cluster-yes
                 --cluster-timeout <arg>
                 --cluster-pipeline <arg>
                 --cluster-replace
  rebalance      host:port
                 --cluster-weight <node1=w1...nodeN=wN>
                 --cluster-use-empty-masters
                 --cluster-timeout <arg>
                 --cluster-simulate
                 --cluster-pipeline <arg>
                 --cluster-threshold <arg>
                 --cluster-replace
  add-node       new_host:new_port existing_host:existing_port
                 --cluster-slave
                 --cluster-master-id <arg>
  del-node       host:port node_id
  call           host:port command arg arg .. arg
                 --cluster-only-masters
                 --cluster-only-replicas
  set-timeout    host:port milliseconds
  import         host:port
                 --cluster-from <arg>
                 --cluster-from-user <arg>
                 --cluster-from-pass <arg>
                 --cluster-from-askpass
                 --cluster-copy
                 --cluster-replace
  backup         host:port backup_directory
  help           
 
For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
 
Cluster Manager Options:
  --cluster-yes  Automatic yes to cluster commands prompts
 

1、 --cluster create  创建集群
create         host1:port1 ... hostN:portN
                 --cluster-replicas <arg>

该命令用来创建集群,假设我现在想搭建三主三从的集群127.0.0.1:7001~7006

启动所有节点后,可通过如下命令进行搭建:

2.--cluster check  检查集群

2、--cluster check  检查集群
check          host:port
                 --cluster-search-multiple-owners #检查是否有槽同时被分配给了多个节点

该命令经常使用,需要拥有槽位的所有节点为启动状态,用于检查集群状态是否正常,只有当所有的槽位正常时,集群状态才OK

3.--cluster info 查看集群

用于查看集群的简易信息

4.--cluster fix  修复集群

fix            host:port
                 --cluster-search-multiple-owners    
                 --cluster-fix-with-unreachable-masters  

该命令十分有用,说明如下:

 --cluster-search-multiple-owners : 是否修复多个拥有者的槽位。当集群中的槽位在迁移过程中,出现意外时,使用fix可使用该参数。fix功能,redis内部在槽位的某些异常情况下会交互式的询问操作者是否同意它的修复策略,一般情况下,默认即可。

 --cluster-fix-with-unreachable-masters : 是否修复不可达的主节点上的槽位。例如,集群中某个主节点就是坏掉了,也没有故障转移成功。此时如何恢复该主节点上的所有槽位呢,这时就可以使用该参数,会将处于该主节点上的所有槽位恢复到存活的主节点上(之前的数据会丢失,仅仅是恢复了槽位)。

5.--cluster rehard 迁移槽位

reshard        host:port
                 --cluster-from <arg>   #槽位来源的节点运行id,多个用,分割,all表示全部节点
                 --cluster-to <arg>       #目标节点的运行id,只允一个
                 --cluster-slots <arg>   #迁移的槽位数
                 --cluster-yes               #是否默认同意集群内部的迁移计划(默认同意就可以)
                 --cluster-timeout <arg>   #迁移命令(migrate)的超时时间
                 --cluster-pipeline <arg>  #迁移key时,一次取出 的key数量,默认10
                 --cluster-replace           #是否直接replace到目标节点

迁移一个或者多个(--cluster-from)节点上的--cluster-slots个槽位至一个目标节点(--cluster-to)上。

 --cluster-from 的值不为all的情况下, --cluster-from不能包含--cluster-to

6.--cluster rebalance 平衡集群

rebalance      host:port
                 --cluster-weight <node1=w1...nodeN=wN>
                 --cluster-use-empty-masters
                 --cluster-timeout <arg>     #迁移命令(migrate)的超时时间
                 --cluster-simulate              # 模拟rebalance操作,不会真正执行迁移操作
                 --cluster-pipeline <arg>    #定义 getkeysinslot命令一次取出的key数量,默认值为10
                 --cluster-threshold <arg>
                 --cluster-replace               #是否直接replace到目标节点

--cluster-weight: 槽位权重(浮点型)比值,例如(这里使用端口号代替运行id): 7001=1.0,7002=1.0,7003=2.0 则表示,总权重为4.0, 7001和7002将分配到 (16384/4)*1  个槽位,7003则是(16384/4)*2个槽位。

 --cluster-threshold: 平衡触发的阈值条件,默认为2.00%。例如上一步,7001和7002应该有4096个槽位,如果7001的槽位数不够4096个,且超过 (4096*0.02 约等于)82个及以上;或者7001的槽位数比4096少于82个及以上,则会触发自平衡。

7.--cluster  add-node    集群扩容

add-node    new_host:new_port                  #新加入集群的ip和port

                existing_host:existing_port          #集群中任一节点的ip和port
                 --cluster-slave                             #新节点作为从节点,默认随机一个主节点
                 --cluster-master-id <arg>            #给新节点指定主节点,值为节点的运行id

可用于向集群中添加主、从节点(即扩容)

8.--cluster del-node      集群缩容

del-node    host:port node_id         #删除给定的一个节点,成功后关闭该节点服务

也就是缩容。

删除一个主节点要求先迁移走改主节点上的槽位(数据),这时就可以使用reshard命令了。
————————————————

9.--cluster call  在集群中执行命令

 --cluster call  在集群中执行命令
call           host:port command arg arg .. arg               #在集群的所有节点执行相关命令
                 --cluster-only-masters                                #是否只在主节点上执行
                 --cluster-only-replicas                                #是否只在从节点上执行

10.--cluster set-timeout     整个集群的cluster-node-timeout时间

11.--cluster import          导入数据至集群

import         host:port
                 --cluster-from <arg>
                 --cluster-from-user <arg>
                 --cluster-from-pass <arg>
                 --cluster-from-askpass
                 --cluster-copy               #migrate时指定类型为copy
                 --cluster-replace           #migrate时指定类型为replace

将外部redis的数据导入集群 

redis-cli --cluster import 127.0.01:6379 --cluster-from 127.0.0.2:6379 --cluster-replace --cluster-copy

说明:外部Redis实例(127.0.0.2:6379)导入到集群中的任意一节点,倒入之后,原来集群的key变为空,导入到新集群的key会自动分片到各个mater节点的slot

--cluster-replace 如果集群(127.0.01:6379)中存在外部redis实例(127.0.0.2:6379)的key,则会覆盖掉(10.35.2.68:6379)的value

--cluster-copy 默认情况下,import 命令在向集群导入数据的同时,还会删除单机服务器中源数据。如果用户想要保留单机服务器中的数据,那么可以在执行命令的同时给定 –cluster-copy 选项 

该命令将正在运行的实例的所有键(从源实例中删除键)移动到指定的预先存在的 Redis 集群。

实际项目上,数据导入应该用redis-shake工具的比较多。

12.--cluster backup         备份集群rdb文件

./redis-cli --cluster backup 192.168.84.1:7001 ./backup

 Redis集群详解:槽位、分片与高可用架构-CSDN博客


http://www.kler.cn/a/541314.html

相关文章:

  • 怎么查看电脑显存大小(查看电脑配置)
  • [LLM面试题] 指示微调(Prompt-tuning)与 Prefix-tuning区别
  • 理邦仪器嵌入式(C/C++开发)开发面试题及参考答案
  • UnityShader学习笔记——高级纹理
  • C++,STL 迭代器简介:概念、分类、操作
  • C++并发编程指南 09(共享数据)
  • JAVA安全之Java Agent打内存马
  • MacOS 安装NVM
  • 场景设计:设计一个分布式限流器,采用令牌桶算法,漏桶算法、滑动窗口算法实现
  • 荣耀手机Magic3系列、Magic4系列、Magic5系列、Magic6系列、Magic7系列详情对比以及最新二手价格预测
  • Spring Boot Actuator(官网文档解读)
  • QT:QWidget
  • 采用分步式无线控制架构实现水池液位自动化管理
  • LLM Note
  • 图论——并查集
  • TCP队头阻塞问题以及QUIC解决方案
  • 本地搭建springboot服务并实现公网远程调试本地接口
  • 【QT】 Qt经典面试题
  • 嵌入式硬件---OpenMV文件系统基本图像处理
  • 《量化绿皮书》Chapter 3 Calculus and Linear Algebra 微积分与线性代数(一)
  • 字节跳动大模型应用 Go 开发框架 —— Eino 实践
  • 结合实际讲NR系列2—— SIB1
  • 解锁 CSS Grid 高级技巧:提升网页布局灵活性的秘诀
  • PyTorch torch.sign函数介绍
  • MySQL 8版本认证问题
  • DeepSeek模型场景应用:基于腾讯云HAI搭建IDEA开发助手