Redis cluster(七)

1.1 Redis cluster简介

Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施(installation)。

Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低 Redis 集群的性能, 并导致不可预测的行为。

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

Redis 集群提供了以下两个好处:

  • 将数据自动切分(split)到多个节点的能力。
  • 当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。

1.2 Redis cluster数据共享

Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现:一个 Redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个键都属于这 16384 个哈希槽的其中一个,集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽,其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和

集群中的每个节点负责处理一部分哈希槽。举个例子,一个集群可以有三个哈希槽,其中:

  • 节点 A 负责处理0 号至 5500 号哈希槽。
  • 节点 B 负责处理5501 号至 11000 号哈希槽。
  • 节点 C 负责处理11001 号至 16384 号哈希槽。

1.3 Redis cluster的主从复制

为了使得集群在一部分节点下线或者无法与集群的大多数(majority)节点进行通讯的情况下, 仍然可以正常运作,Redis 集群对节点使用了主从复制功能:集群中的每个节点都有 1 个至 N 个复制品(replica),其中一个复制品为主节点(master),而其余的 N-1 个复制品为从节点(slave)。

在之前列举的节点 A 、B 、C 的例子中,如果节点 B 下线了,那么集群将无法正常运行, 因为集群找不到节点来处理 5501 号至 11000号的哈希槽。

另一方面,假如在创建集群的时候(或者至少在节点 B 下线之前),我们为主节点 B 添加了从节点 B1 ,那么当主节点 B 下线的时候,集群就会将 B1 设置为新的主节点,并让它代替下线的主节点 B ,继续处理 5501 号至 11000 号的哈希槽,这样集群就不会因为主节点 B 的下线而无法正常运作了。

不过如果节点 B 和 B1 都下线的话,Redis 集群还是会停止运作。

图片[1]|Redis cluster(七)|leon的博客

图片[2]|Redis cluster(七)|leon的博客

1.4 Redis cluster运行机制

  • 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽
  • 节点的fail是通过集群中超过半数的master节点检测失效时才生效
  • 客户端与redis节点直连,不需要中间proxy层,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
  • 把所有的物理节点映射到[0-16383]slot上,cluster负责维护node<>slot<>key

1.5 安装部署redis集群

1.5.1 安装依赖程序

[root@centos7 ~]# yum install -y rubygems

1.5.2 配置ruby使用国内源

[root@centos7 ~]# gem update --system
[root@centos7 ~]# gem source --add https://gems.ruby-china.org/ --remove https://rubygems.org

1.5.3 安装redis

[root@centos7 ~]# gem install redis -v 3.3.5

1.5.4 配置6个redis实例

[root@centos7 ~]# mkdir -p /usr/local/redis/data/{7000..7005}
[root@centos7 ~]# vim /usr/local/redis/conf/redis_7000.conf     # 7000-7005
port 7000                           # 7000-7005
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
pidfile "/var/run/redis_7000.pid"
dir "/usr/local/redis/data/7000"

[root@centos7 ~]# cd /usr/local/redis/conf
[root@centos7 conf]# for i in {1..5}
do
    cp redis_7000.conf redis_700$i.conf
done
[root@centos7 conf]# for i in {1..5}
do
    sed -i "s#7000#700$i#g" redis_700$i.conf
done

1.5.5 启动多实例

[root@centos7 ~]# for i in {0..5}
do
    redis-server /usr/local/redis/conf/redis_700$i.conf
done

1.5.6 创建集群

[root@centos7 ~]# redis-trib.rb create --replicas 1 \
10.0.0.103:7000 \
10.0.0.103:7001 \
10.0.0.103:7002 \
10.0.0.103:7003 \
10.0.0.103:7004 \
10.0.0.103:7005
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
...省略部分输出内容...
Can I set the above configuration  (type 'yes' to accept): yes
...省略部分输出内容...
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
  • 命令说明:
  1. create:创建新集群
  2. –replicas 1:为集群中每个主节点创建一个从节点
  3. …10.0.0.103:7005:实例的地址列表,即创建新集群时的主机及端口列表

1.5.7 测试集群

[root@centos7 ~]# redis-cli -c -h 10.0.0.103 -p 7000
10.0.0.103:7000> set foo leon
-> Redirected to slot [12182] located at 10.0.0.103:7002
OK
10.0.0.103:7002> get foo
"leon"
10.0.0.103:7002> exit
[root@centos7 ~]# redis-cli -c -h 10.0.0.103 -p 7000
10.0.0.103:7000> get foo
-> Redirected to slot [12182] located at 10.0.0.103:7002
"leon"
10.0.0.103:7002> set test shadow
-> Redirected to slot [6918] located at 10.0.0.103:7001
OK
10.0.0.103:7001> set name ly
OK
10.0.0.103:7001> set age 33
-> Redirected to slot [741] located at 10.0.0.103:7000
OK
10.0.0.103:7000> keys *
1) "age"
10.0.0.103:7000> get name
-> Redirected to slot [5798] located at 10.0.0.103:7001
"ly"
10.0.0.103:7001> keys *
1) "name"
2) "test"

1.6 Redis cluster基本操作

1.6.1 查看集群状态

[root@centos7 ~]# redis-cli -h 10.0.0.103 -p 7000 cluster nodes
bae6c43d1d010fb7ad5df2a05fd9755068745c33 10.0.0.103:7002@17002 master - 0 1512624983545 3 connected 10923-16383
5c80c02a1e904f727a03205cfffcfc507fa39f41 10.0.0.103:7001@17001 master - 0 1512624984551 2 connected 5461-10922
f2a6ca72b822a436b69df218dcb878c0e394dca7 10.0.0.103:7004@17004 slave 5c80c02a1e904f727a03205cfffcfc507fa39f41 0 1512624984048 5 connected
1dfb3e9e3bb0f870b93ba70b787e43a3d3702393 10.0.0.103:7005@17005 slave bae6c43d1d010fb7ad5df2a05fd9755068745c33 0 1512624983000 6 connected
c3f615aed8df9773f6d28f94e68f87e76cd95c46 10.0.0.103:7000@17000 myself,master - 0 1512624983000 1 connected 0-5460
3affc896ae3373286943008c25c277713ed0fa62 10.0.0.103:7003@17003 slave c3f615aed8df9773f6d28f94e68f87e76cd95c46 0 1512624983000 4 connected
  • 状态说明:

图片[3]|Redis cluster(七)|leon的博客

1.6.2 模拟故障转移

# 模拟发生故障

[root@centos7 ~]# redis-cli -h 10.0.0.103 -p 7002 debug segfault
Error: Server closed the connection
[root@centos7 ~]# redis-cli -h 10.0.0.103 -p 7000 cluster nodes
bae6c43d1d010fb7ad5df2a05fd9755068745c33 10.0.0.103:7002@17002 master,fail - 1512625543356 1512625541747 3 disconnected 10923-16383
5c80c02a1e904f727a03205cfffcfc507fa39f41 10.0.0.103:7001@17001 master - 0 1512625548803 2 connected 5461-10922
f2a6ca72b822a436b69df218dcb878c0e394dca7 10.0.0.103:7004@17004 slave 5c80c02a1e904f727a03205cfffcfc507fa39f41 0 1512625548000 5 connected
1dfb3e9e3bb0f870b93ba70b787e43a3d3702393 10.0.0.103:7005@17005 slave bae6c43d1d010fb7ad5df2a05fd9755068745c33 0 1512625547000 6 connected
c3f615aed8df9773f6d28f94e68f87e76cd95c46 10.0.0.103:7000@17000 myself,master - 0 1512625548000 1 connected 0-5460
3affc896ae3373286943008c25c277713ed0fa62 10.0.0.103:7003@17003 slave c3f615aed8df9773f6d28f94e68f87e76cd95c46 0 1512625549307 4 connected

# 模拟恢复故障
[root@centos7 ~]# redis-server /usr/local/redis/conf/redis_7002.conf
[root@centos7 ~]# redis-cli -h 10.0.0.103 -p 7000 cluster nodes
bae6c43d1d010fb7ad5df2a05fd9755068745c33 10.0.0.103:7002@17002 slave 1dfb3e9e3bb0f870b93ba70b787e43a3d3702393 0 1512626359433 7 connected
5c80c02a1e904f727a03205cfffcfc507fa39f41 10.0.0.103:7001@17001 master - 0 1512626358000 2 connected 5461-10922
f2a6ca72b822a436b69df218dcb878c0e394dca7 10.0.0.103:7004@17004 slave 5c80c02a1e904f727a03205cfffcfc507fa39f41 0 1512626358422 5 connected
1dfb3e9e3bb0f870b93ba70b787e43a3d3702393 10.0.0.103:7005@17005 master - 0 1512626357414 7 connected 10923-16383
c3f615aed8df9773f6d28f94e68f87e76cd95c46 10.0.0.103:7000@17000 myself,master - 0 1512626356000 1 connected 0-5460
3affc896ae3373286943008c25c277713ed0fa62 10.0.0.103:7003@17003 slave c3f615aed8df9773f6d28f94e68f87e76cd95c46 0 1512626358000 4 connected

1.6.3 新增节点

1.6.3.1 创建新实例

[root@centos7 ~]# cd /usr/local/redis/conf/
[root@centos7 conf]# cp redis_7005.conf redis_7006.conf
[root@centos7 conf]# vim redis_7006.conf
[root@centos7 conf]# sed -i 's#7005#7006#g' redis_7006.conf
[root@centos7 ~]# mkdir -p /usr/local/redis/data/7006
[root@centos7 ~]# redis-server /usr/local/redis/conf/redis_7006.conf

1.6.3.2 添加节点

[root@centos7 ~]# redis-trib.rb add-node 10.0.0.103:7006 10.0.0.103:7000
>>> Adding node 10.0.0.103:7006 to cluster 10.0.0.103:7000
>>> Performing Cluster Check (using node 10.0.0.103:7000)
M: c3f615aed8df9773f6d28f94e68f87e76cd95c46 10.0.0.103:7000
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: bae6c43d1d010fb7ad5df2a05fd9755068745c33 10.0.0.103:7002
   slots: (0 slots) slave
   replicates 1dfb3e9e3bb0f870b93ba70b787e43a3d3702393
M: 5c80c02a1e904f727a03205cfffcfc507fa39f41 10.0.0.103:7001
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: f2a6ca72b822a436b69df218dcb878c0e394dca7 10.0.0.103:7004
   slots: (0 slots) slave
   replicates 5c80c02a1e904f727a03205cfffcfc507fa39f41
M: 1dfb3e9e3bb0f870b93ba70b787e43a3d3702393 10.0.0.103:7005
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 3affc896ae3373286943008c25c277713ed0fa62 10.0.0.103:7003
   slots: (0 slots) slave
   replicates c3f615aed8df9773f6d28f94e68f87e76cd95c46
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 10.0.0.103:7006 to make it join the cluster.
[OK] New node added correctly.
  • 命令说明:
  1. add-node 之后跟着的是新节点的 IP 地址和端口号,再之后跟着的是集群中任意一个已存在节点的 IP 地址和端口号

1.6.4 变为某个主库的从库

[root@centos7 ~]# redis-cli -h 10.0.0.103 -p 7006 cluster replicate 5c80c02a1e904f727a03205cfffcfc507fa39f41
OK
# 或
[root@centos7 ~]# redis-cli -h 10.0.0.103 -p 7006
10.0.0.103:7006> cluster replicate 5c80c02a1e904f727a03205cfffcfc507fa39f41
[root@centos7 ~]# redis-cli -h 10.0.0.103 -p 7000 cluster nodes
bae6c43d1d010fb7ad5df2a05fd9755068745c33 10.0.0.103:7002@17002 slave 1dfb3e9e3bb0f870b93ba70b787e43a3d3702393 0 1512626854000 7 connected
5c80c02a1e904f727a03205cfffcfc507fa39f41 10.0.0.103:7001@17001 master - 0 1512626854000 2 connected 5461-10922
f2a6ca72b822a436b69df218dcb878c0e394dca7 10.0.0.103:7004@17004 slave 5c80c02a1e904f727a03205cfffcfc507fa39f41 0 1512626854951 5 connected
1dfb3e9e3bb0f870b93ba70b787e43a3d3702393 10.0.0.103:7005@17005 master - 0 1512626853000 7 connected 10923-16383
c3f615aed8df9773f6d28f94e68f87e76cd95c46 10.0.0.103:7000@17000 myself,master - 0 1512626852000 1 connected 0-5460
3affc896ae3373286943008c25c277713ed0fa62 10.0.0.103:7003@17003 slave c3f615aed8df9773f6d28f94e68f87e76cd95c46 0 1512626854549 4 connected
1bef00d0e51706b41a42eed3087e071006760400 10.0.0.103:7006@17006 slave 5c80c02a1e904f727a03205cfffcfc507fa39f41 0 1512626853543 2 connected

1.6.5 移除某个节点

1.6.5.1 移除slave节点

[root@centos7 ~]# redis-trib.rb del-node 10.0.0.103:7006 1bef00d0e51706b41a42eed3087e071006760400
>>> Removing node 1bef00d0e51706b41a42eed3087e071006760400 from cluster 10.0.0.103:7006
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

1.6.5.2 移除master节点

# 删除master节点前首先要reshard移除master的全部slot,然后再删除节点
[root@centos7 ~]# redis-trib.rb reshard 10.0.0.103:7005
How many slots do you want to move (from 1 to 16384)  16384
What is the receiving node ID  5c80c02a1e904f727a03205cfffcfc507fa39f41
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

[root@centos7 ~]# redis-trib.rb del-node 10.0.0.103:7005 1dfb3e9e3bb0f870b93ba70b787e43a3d3702393
>>> Removing node 1dfb3e9e3bb0f870b93ba70b787e43a3d3702393 from cluster 10.0.0.103:7005
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

1.6.5.3 重新添加节点

# 必须删除节点配置文件才可以重新添加进集群
[root@centos7 ~]# rm -f /usr/local/redis/data/7005/nodes.conf
[root@centos7 ~]# rm -f /usr/local/redis/data/7006/nodes.conf
[root@centos7 ~]# redis-server /usr/local/redis/conf/redis_7005.conf
[root@centos7 ~]# redis-server /usr/local/redis/conf/redis_7006.conf
# 重新添加进集群
[root@centos7 ~]# redis-trib.rb add-node 10.0.0.103:7005 10.0.0.103:7000
[root@centos7 ~]# redis-trib.rb add-node 10.0.0.103:7006 10.0.0.103:7000
温馨提示:本文最后更新于2022-12-20 20:57:49,已超过483天没有更新。某些文章具有时效性,若文章内容或图片资源有错误或已失效,请联系站长。谢谢!
转载请注明本文链接:https://blog.leonshadow.cn/763482/897.html
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享