连接集群
redis-cli -c -p 6380
-c 参数表示 cluster 模式的意思,使用-c 参数时,redis-cli 会自动检测 Redis 集群的配置信息,并将命令路由到正确的节点上执行。
写入数据
单个 key 写入
[root@centos cluster-dis]# redis-cli -c -p 6380127.0.0.1:6380> set name bing-> Redirected to slot [5798] located at 192.168.11.10:6381OK192.168.11.10:6381> get name"bing"192.168.11.10:6381> rpush languages C Python Go Java PHP(integer) 5192.168.11.10:6381> lpop languages 51) "C"2) "Python"3) "Go"4) "Java"5) "PHP"可以看到当写入 name 的时候 redis 会去计算 name 的 hash 值,hash 值为 5798,对应节点的端口号为 6381,于是自动重定向到 6381 的节点上存储数据。当写入 languages 这个 key 的时候,由于 languages 的 hash 值还在 6381 这个节点上,因此没有发生重定向。
批量 key 操作
192.168.11.10:6381> mset username "bingbing" password "1234" age 18(error) CROSSSLOT Keys in request don't hash to the same slot当使用 mset 存储多个 key 时很可能会发生错误。这是因为每个 key 的 hash 值不一样,导致可能每个 key 存储在不同的机器上,所以不能一次性同时写入多个 key。要解决这个问题可以使用组的方式来一次性存储多个 key。只要为这些 key 指定一个统一的 group,让这个 group 作为计算 slot 的唯一值。
192.168.11.10:6381> mset username{msg} "bingbing" password{msg} "1234" age{msg} 18OK集群查询
查询 key 的 slot
通过 cluster keyslot 可以查询指定 key 的 slot。例如,下面是查询 msg 和 name 的 slot。
192.168.11.10:6381> cluster keyslot msg(integer) 6257192.168.11.10:6381> cluster keyslot name(integer) 5798查询 slot 中 key 的数量
通过 cluster countkeysinslot 命令可以查看到指定 slot 所包含的 key 的个数。
192.168.11.10:6381> cluster countkeysinslot 6257(integer) 3192.168.11.10:6381> cluster countkeysinslot 5798(integer) 1查询 slot 中的 key
通过 cluster getkeysinslot 命令可以查看到指定 slot 所包含的 key。
192.168.11.10:6381> cluster getkeysinslot 6257 51) "age{msg}"2) "password{msg}"3) "username{msg}"192.168.11.10:6381> cluster getkeysinslot 5798 51) "name"故障转移
分布式系统中的某个 master 如果出现宕机,那么其相应的 slave 就会自动晋升为 master。如果原 master 又重新启动了,那么原 master 会自动变为新 master 的 slave。
Master 宕机
通过 cluster nodes 命令可以查看系统的整体架构及连接情况。
192.168.11.10:6381> cluster nodes945afe522588ce4d68cb00a47310cb544bf85d90 192.168.11.10:6383@16383 slave 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0 0 1686618349262 1 connected32a425e8c3d6cc43e798374b453498fa9488c04f 192.168.11.10:6384@16384 slave 781390fbc0d43b8b060a09b55fff6d7f8a330f04 0 1686618350269 2 connected781390fbc0d43b8b060a09b55fff6d7f8a330f04 192.168.11.10:6381@16381 myself,master - 0 1686618346000 2 connected 5461-109227daef2acdcbc1c932b607c0deaf6bcbc373d32e0 192.168.11.10:6380@16380 master - 0 1686618348000 1 connected 0-54605c35e22ba66ed3c2603a7f915110376ef7e6f992 192.168.11.10:6382@16382 master - 0 1686618351273 3 connected 10923-16383c8ca4299d26a82be393577bd546e7e7ee1c732be 192.168.11.10:6385@16385 slave 5c35e22ba66ed3c2603a7f915110376ef7e6f992 0 1686618347000 3 connected可以看到 6380、6381、8382 均为 Master 主机,其中 6380 的 Slave 是 6383;6381 的 Slave 是 6384;6382 的 Slave 是 6385。现在将 6381 关机,再登录 6384 的机器。
192.168.11.10:6381> shutdownnot connected> exit[root@centos cluster-dis]# redis-cli -c -p 6384127.0.0.1:6384> cluster nodes781390fbc0d43b8b060a09b55fff6d7f8a330f04 192.168.11.10:6381@16381 master,fail - 1686618687912 1686618683879 2 disconnected5c35e22ba66ed3c2603a7f915110376ef7e6f992 192.168.11.10:6382@16382 master - 0 1686618725468 3 connected 10923-163837daef2acdcbc1c932b607c0deaf6bcbc373d32e0 192.168.11.10:6380@16380 master - 0 1686618724458 1 connected 0-5460c8ca4299d26a82be393577bd546e7e7ee1c732be 192.168.11.10:6385@16385 slave 5c35e22ba66ed3c2603a7f915110376ef7e6f992 0 1686618721000 3 connected945afe522588ce4d68cb00a47310cb544bf85d90 192.168.11.10:6383@16383 slave 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0 0 1686618722442 1 connected32a425e8c3d6cc43e798374b453498fa9488c04f 192.168.11.10:6384@16384 myself,master - 0 1686618724000 7 connected 5461-10922127.0.0.1:6384> info replication# Replicationrole:masterconnected_slaves:0master_failover_state:no-failovermaster_replid:a5daf0e54fc036b6062e5db2feda53607d531a07master_replid2:8063340a57b75a764ff80f7c15510b115a276e32master_repl_offset:3152second_repl_offset:3153repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:15repl_backlog_histlen:3138可以看到,由于 Master6381 宕机,它的 Slave6384 晋升为 Master 节点。当 6381 重新启动后,6381 会成为 6384 的 Slave。
[root@centos cluster-dis]# redis-server redis6381.conf[root@centos cluster-dis]# redis-cli -c -p 6381127.0.0.1:6381> info replication# Replicationrole:slavemaster_host:192.168.11.10master_port:6384master_link_status:upmaster_last_io_seconds_ago:6master_sync_in_progress:0slave_read_repl_offset:3236slave_repl_offset:3236slave_priority:90slave_read_only:1replica_announced:1connected_slaves:0master_failover_state:no-failovermaster_replid:a5daf0e54fc036b6062e5db2feda53607d531a07master_replid2:0000000000000000000000000000000000000000master_repl_offset:3236second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:3167repl_backlog_histlen:70Master 和 Slave 都宕机
如果某 slot 范围对应节点的 master 与 slave 全部宕机,那么整个分布式系统是否还可以对外提供读服务,就取决于属性 cluster-require-full-coverage 的设置。
# 默认情况下,如果 Redis Cluster 节点检测到至少有一个哈希槽未被覆盖# (即没有可用的节点负责处理该哈希槽),就会停止接受查询请求。# 这样一来,如果集群出现部分故障(例如某一范围的哈希槽不再被覆盖),# 最终整个集群都会变得不可用。# 当所有哈希槽重新被覆盖后,它会自动恢复为可用状态。## 但是,有时你希望集群中仍然正常工作的那部分节点,# 继续接受当前仍被覆盖的键空间对应的查询请求。# 如果要实现这一点,只需要将 cluster-require-full-coverage# 选项设置为 no。# ------------------------------------------------------------------------------# By default Redis Cluster nodes stop accepting queries if they detect there# is at least a hash slot uncovered (no available node is serving it).# This way if the cluster is partially down (for example a range of hash slots# are no longer covered) all the cluster becomes, eventually, unavailable.# It automatically returns available as soon as all the slots are covered again.# # However sometimes you want the subset of the cluster which is working,# to continue to accept queries for the part of the key space that is still# covered. In order to do so, just set the cluster-require-full-coverage# option to no.# cluster-require-full-coverage yes该属性有两种取值:
- yes:默认值。要求所有 slot 节点必须全覆盖的情况下系统才能运行。
- no:slot 节点不全的情况下系统也可以提供查询服务。
[root@centos cluster-dis]# ps -aux |grep redisroot 1469 0.2 0.5 163320 10396 ? Ssl 08:22 0:10 /usr/local/redis/bin/redis-server 192.168.11.10:6379root 6926 0.3 0.5 165880 11284 ? Ssl 08:36 0:11 redis-server 192.168.11.10:6380 [cluster]root 6938 0.3 0.5 165880 11308 ? Ssl 08:36 0:11 redis-server 192.168.11.10:6382 [cluster]root 6944 0.3 0.5 241660 11080 ? Ssl 08:36 0:12 redis-server 192.168.11.10:6383 [cluster]root 6956 0.3 0.6 247804 13140 ? Ssl 08:36 0:12 redis-server 192.168.11.10:6385 [cluster]root 27136 0.0 0.1 112836 2296 pts/0 S+ 09:31 0:00 grep --color=auto redis6381 和 6384 现在都关机了。
[root@centos cluster-dis]# redis-cli -c -p 6380127.0.0.1:6380> get name(error) CLUSTERDOWN The cluster is down可以看到,现在整个分布式系统已经不能对外提供服务。
集群扩容
1.启动两个节点
需要添加两个新的节点:端口号为 6386 的节点为 master 节点,其下会有一个端口号为 6387 的 slave 节点。写好相应配置文件以后就能启动。
[root@centos cluster-dis]# redis-server redis6386.conf[root@centos cluster-dis]# redis-server redis6387.conf查询集群的连接情况:
192.168.11.10:6384> cluster nodes945afe522588ce4d68cb00a47310cb544bf85d90 192.168.11.10:6383@16383 slave 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0 0 1686622673127 1 connected781390fbc0d43b8b060a09b55fff6d7f8a330f04 192.168.11.10:6381@16381 slave 32a425e8c3d6cc43e798374b453498fa9488c04f 0 1686622673000 7 connected5c35e22ba66ed3c2603a7f915110376ef7e6f992 192.168.11.10:6382@16382 master - 0 1686622672121 3 connected 10923-163837daef2acdcbc1c932b607c0deaf6bcbc373d32e0 192.168.11.10:6380@16380 master - 0 1686622674134 1 connected 0-546032a425e8c3d6cc43e798374b453498fa9488c04f 192.168.11.10:6384@16384 myself,master - 0 1686622670000 7 connected 5461-10922c8ca4299d26a82be393577bd546e7e7ee1c732be 192.168.11.10:6385@16385 slave 5c35e22ba66ed3c2603a7f915110376ef7e6f992 0 1686622673000 3 connected2.添加 master
虽然启动了 6386 和 6387 这两个节点,但是在没有添加到分布式系统之前,它们两个是孤立节点,每个节点与其它任何节点都没有关系。现在需要为 6386 这个 master 分配 slot。通过以下命令:
# 格式:redis-cli --cluster add-node {newHost}:{newPort} {existHost}:{existPort}redis-cli --cluster add-node 192.168.11.10:6386 192.168.11.10:6385可以将新的节点添加到系统中。其中{newHost}:{newPort}是新添加节点的地址,{existHost}:{existPort}是原系统中的任意节点地址。添加成功后,通过 redis-cli -c -p 6386 cluster nodes 命令可以看到其它 master 节点都分配有 slot,只有新添加的 master 还没有相应的 slot。当然,通过该命令也可以看到该新节点的动态 ID。
[root@centos cluster-dis]# redis-cli -c -p 6386 cluster nodes781390fbc0d43b8b060a09b55fff6d7f8a330f04 192.168.11.10:6381@16381 slave 32a425e8c3d6cc43e798374b453498fa9488c04f 0 1686623246000 7 connected32a425e8c3d6cc43e798374b453498fa9488c04f 192.168.11.10:6384@16384 master - 0 1686623245206 7 connected 5461-10922c939dab0c09bb2d28ece43ea3281b31f0ae27fef 192.168.11.10:6386@16386 myself,master - 0 1686623245000 0 connectedc8ca4299d26a82be393577bd546e7e7ee1c732be 192.168.11.10:6385@16385 slave 5c35e22ba66ed3c2603a7f915110376ef7e6f992 0 1686623247221 3 connected945afe522588ce4d68cb00a47310cb544bf85d90 192.168.11.10:6383@16383 slave 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0 0 1686623244000 1 connected5c35e22ba66ed3c2603a7f915110376ef7e6f992 192.168.11.10:6382@16382 master - 0 1686623247000 3 connected 10923-163837daef2acdcbc1c932b607c0deaf6bcbc373d32e0 192.168.11.10:6380@16380 master - 0 1686623244000 1 connected 0-54603.分配 slot
为新的 master 分配的 slot 来自于其它节点,总 slot 数量并不会改变。所以 slot 分配过程本质是一个 slot 的移动过程。
通过命令:
# 格式:redis-cli --cluster reshard {existIP}:{existPort}redis-cli --cluster reshard 192.168.11.10:6384开启 slot 分配流程,其中地址{existIP}:{existPort}为分布式系统中的任意节点地址。执行完命令后还要输入需要分配 slot 的数量和分配给谁的 id。
[root@centos cluster-dis]# redis-cli --cluster reshard 192.168.11.10:6384>>> Performing Cluster Check (using node 192.168.11.10:6384)M: 32a425e8c3d6cc43e798374b453498fa9488c04f 192.168.11.10:6384 slots:[5461-10922] (5462 slots) master 1 additional replica(s)S: 945afe522588ce4d68cb00a47310cb544bf85d90 192.168.11.10:6383 slots: (0 slots) slave replicates 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0M: c939dab0c09bb2d28ece43ea3281b31f0ae27fef 192.168.11.10:6386 slots: (0 slots) masterS: 781390fbc0d43b8b060a09b55fff6d7f8a330f04 192.168.11.10:6381 slots: (0 slots) slave replicates 32a425e8c3d6cc43e798374b453498fa9488c04fM: 5c35e22ba66ed3c2603a7f915110376ef7e6f992 192.168.11.10:6382 slots:[10923-16383] (5461 slots) master 1 additional replica(s)M: 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0 192.168.11.10:6380 slots:[0-5460] (5461 slots) master 1 additional replica(s)S: c8ca4299d26a82be393577bd546e7e7ee1c732be 192.168.11.10:6385 slots: (0 slots) slave replicates 5c35e22ba66ed3c2603a7f915110376ef7e6f992[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)? 2500What is the receiving node ID? c939dab0c09bb2d28ece43ea3281b31f0ae27fefPlease enter all the source node IDs.现在要选择要移动 slot 的源节点。有两种方案。
- 如果选择键入 all,则所有已存在 slot 的节点都将作为 slot 源节点,即该方案将进行一次 slot 全局大分配。
- 也可以选择其它部分节点作为 slot 源节点。此时将源节点的动态 ID 复制到这里,每个 ID 键入完毕后回车,然后再复制下一个 slot 源节点动态 ID,直至最后一个键入完毕回车后再键入 done。
这里我将 6380 和 6382 这两个机器作为 slot 的源节点,从这两个节点中抽取出 2500 个 slot 给 6386 机器。
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: 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0Source node #2: 5c35e22ba66ed3c2603a7f915110376ef7e6f992Source node #3: doneReady to move 2500 slots. Source nodes: M: 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0 192.168.11.10:6380 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: 5c35e22ba66ed3c2603a7f915110376ef7e6f992 192.168.11.10:6382 slots:[10923-16383] (5461 slots) master 1 additional replica(s) Destination node: M: c939dab0c09bb2d28ece43ea3281b31f0ae27fef 192.168.11.10:6386 slots: (0 slots) master其首先会检测指定的 slot 源节点的数据,然后制定出 reshard 的方案。
Moving slot 12171 from 5c35e22ba66ed3c2603a7f915110376ef7e6f992Moving slot 12172 from 5c35e22ba66ed3c2603a7f915110376ef7e6f992Do you want to proceed with the proposed reshard plan (yes/no)? yes这里会再进行一次 Q&A 交互,询问是否想继续处理推荐的方案。键入 yes,然后开始真正的全局分配,直至完成。现在查看集群的 slot 分配情况。
[root@centos cluster-dis]# redis-cli -c -p 6386 cluster nodes781390fbc0d43b8b060a09b55fff6d7f8a330f04 192.168.11.10:6381@16381 slave 32a425e8c3d6cc43e798374b453498fa9488c04f 0 1686624889162 7 connected32a425e8c3d6cc43e798374b453498fa9488c04f 192.168.11.10:6384@16384 master - 0 1686624887000 7 connected 5461-10922c939dab0c09bb2d28ece43ea3281b31f0ae27fef 192.168.11.10:6386@16386 myself,master - 0 1686624886000 8 connected 0-1249 10923-12172c8ca4299d26a82be393577bd546e7e7ee1c732be 192.168.11.10:6385@16385 slave 5c35e22ba66ed3c2603a7f915110376ef7e6f992 0 1686624886000 3 connected945afe522588ce4d68cb00a47310cb544bf85d90 192.168.11.10:6383@16383 slave 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0 0 1686624890168 1 connected5c35e22ba66ed3c2603a7f915110376ef7e6f992 192.168.11.10:6382@16382 master - 0 1686624888155 3 connected 12173-163837daef2acdcbc1c932b607c0deaf6bcbc373d32e0 192.168.11.10:6380@16380 master - 0 1686624887148 1 connected 1250-5460可以看到 6386 的 slot 确实分配了,只不过并不是连续的,从 [0~1249] 和 [10923~12172]。总共的 slot 数量:(1249 - 0 + 1) + (12172 - 10923+ 1) = 1250+1250 = 2500。
4.添加 slave
现要将 6387 节点添加为 6386 节点的 slave。当然,首先要确保 6387 节点的 Redis 是启动状态。通过命令:
# 格式redis-cli --cluster add-node {newHost}:{newPort} {existHost}:{existPort} --cluster-slave --cluster-master-id masterIDredis-cli --cluster add-node 192.168.11.10:6387 192.168.11.10:6380 --cluster-slave --cluster-master-id c939dab0c09bb2d28ece43ea3281b31f0ae27fef可将新添加的节点直接添加为指定 master 的 slave。最后集群连接的结果如下:
[root@centos cluster-dis]# redis-cli -c -p 6387 cluster nodesc8ca4299d26a82be393577bd546e7e7ee1c732be 192.168.11.10:6385@16385 slave 5c35e22ba66ed3c2603a7f915110376ef7e6f992 0 1686625641000 3 connected7daef2acdcbc1c932b607c0deaf6bcbc373d32e0 192.168.11.10:6380@16380 master - 0 1686625639000 1 connected 1250-5460c939dab0c09bb2d28ece43ea3281b31f0ae27fef 192.168.11.10:6386@16386 master - 0 1686625641000 8 connected 0-1249 10923-121720bd67fc99e234126658b1316ccddd7a39f51b6df 192.168.11.10:6387@16387 myself,slave c939dab0c09bb2d28ece43ea3281b31f0ae27fef 0 1686625635000 8 connected781390fbc0d43b8b060a09b55fff6d7f8a330f04 192.168.11.10:6381@16381 slave 32a425e8c3d6cc43e798374b453498fa9488c04f 0 1686625641000 7 connected5c35e22ba66ed3c2603a7f915110376ef7e6f992 192.168.11.10:6382@16382 master - 0 1686625642870 3 connected 12173-1638332a425e8c3d6cc43e798374b453498fa9488c04f 192.168.11.10:6384@16384 master - 0 1686625643875 7 connected 5461-10922945afe522588ce4d68cb00a47310cb544bf85d90 192.168.11.10:6383@16383 slave 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0 0 1686625643000 1 connected集群缩容
下面要将 slave 节点 6387 与 master 节点 6386 从分布式系统中删除。
1.删除 slave 节点
对于 slave 节点,可以直接通过以下命令删除。
# 格式redis-cli --cluster del-node <delHost>:<delPort> delNodeIDredis-cli --cluster del-node 192.168.11.10:6387 0bd67fc99e234126658b1316ccddd7a39f51b6df[root@centos cluster-dis]# redis-cli --cluster del-node 192.168.11.10:6387 0bd67fc99e234126658b1316ccddd7a39f51b6df>>> Removing node 0bd67fc99e234126658b1316ccddd7a39f51b6df from cluster 192.168.11.10:6387>>> Sending CLUSTER FORGET messages to the cluster...>>> Sending CLUSTER RESET SOFT to the deleted node.2.移出 master 的 slot
在删除一个 master 之前,必须要保证该 master 上没有分配有 slot。否则无法删除。所以,在删除一个 master 之前,需要先将其上分配的 slot 移出。
# 这个IP和端口号必须是分布式系统中存在的IP和端口号redis-cli --cluster reshard 192.168.11.10:6384接下来就是选择移出的 slot 数量和接收 slot 的机器 ID
[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)? 2500What is the receiving node ID? 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0Please 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: c939dab0c09bb2d28ece43ea3281b31f0ae27fefSource node #2: doneWhat is the receiving node ID? 是 6380 这个 master 的机器 ID;ID(c939dab0c09bb2d28ece43ea3281b31f0ae27fef)为 6386 的机器 ID。后面再输入 yes 确认就可以了。整个过程和前面的分配 slot 非常相似。再使用 redis-cli -c -p 6386 cluster nodes 命令查看发现,6386 节点中已经没有 slot 了。
3.删除 master 节点
# 格式redis-cli --cluster del-node <delHost>:<delPort> delNodeIDredis-cli --cluster del-node 192.168.11.10:6386 c939dab0c09bb2d28ece43ea3281b31f0ae27fef此时再查看集群,发现已经没有了 6386 节点。
[root@centos cluster-dis]# redis-cli -c -p 6380 cluster nodes7daef2acdcbc1c932b607c0deaf6bcbc373d32e0 192.168.11.10:6380@16380 myself,master - 0 1686627162000 9 connected 0-5460 10923-12172945afe522588ce4d68cb00a47310cb544bf85d90 192.168.11.10:6383@16383 slave 7daef2acdcbc1c932b607c0deaf6bcbc373d32e0 0 1686627162000 9 connectedc8ca4299d26a82be393577bd546e7e7ee1c732be 192.168.11.10:6385@16385 slave 5c35e22ba66ed3c2603a7f915110376ef7e6f992 0 1686627161666 3 connected5c35e22ba66ed3c2603a7f915110376ef7e6f992 192.168.11.10:6382@16382 master - 0 1686627162672 3 connected 12173-1638332a425e8c3d6cc43e798374b453498fa9488c04f 192.168.11.10:6384@16384 master - 0 1686627163678 7 connected 5461-10922781390fbc0d43b8b060a09b55fff6d7f8a330f04 192.168.11.10:6381@16381 slave 32a425e8c3d6cc43e798374b453498fa9488c04f 0 1686627161000 7 connected
Comments