redis-cluster架构图
(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.
(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
(4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value
Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点
示例如下
redis-cluster投票容错
首先你需要连接上redis
[root@localhost src]# ./redis-cli -p 6384 --第一步从客户端命令工具连接redis
127.0.0.1:6384> auth 123456 --输入登录密码,登录
[root@localhost src]# info replication --使用命令 info replication查看状态信息
示例图片
(1)集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超过(cluster-node-timeout),认为该master节点挂掉.
(2):什么时候整个集群不可用(cluster_state:fail)?
如果集群任意master挂掉,且当前master没有slave,则集群进入fail状态。也可以理解成集群的[0-16383]slot映射不完全时进入fail状态。
如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态。
搭建Ruby环境
redis集群需要使用技巧管理工具redis-trib.rb,它依赖ruby环境,首先需要安装ruby环境。
第一步:安装ruby
[root@ERAYT-01 erayt]# yum install ruby
[root@ERAYT-01 erayt]# yum install rubygems
第二步:上传redis-3.0.0.gem到Linux系统
第三步:安装ruby和redis的接口程序redis-3.0.0.gem
[root@ERAYT-01 erayt]# gem install redis-3.0.0.gem
第四步:redis-3.0.0/src目录,将redis-trib.rb文件复制到/usr/local/redis-cluster目录下
[root@ERAYT-01 src]# cp redis-trib.rb /usr/local/redis-cluster/
Redis集群搭建
Redis集群最少需要三台主服务器,三台从服务器。
端口号分别为:7001~7006
第一步:创建7001实例,并编辑redis.conf文件,修改port为7001。
注意:创建实例,即拷贝单机版安装时,生成的bin目录,为7001目录。
[erayt@ERAYT-01 redis]$ cd /usr/local/
[erayt@ERAYT-01 local]$ ls
bin etc games include lib libexec redis redis-cluster sbin share src
[erayt@ERAYT-01 local]$ cp redis/bin/ redis-cluster/7001 -r
进入7001目录,修改端口,打开Cluster-enable yes
# Accept connections on the specified port, default is 6379.
# If port 0 is specified Redis will not listen on a TCP socket.
port 7001
cluster-enabled yes
第三步:复制7001,创建7002~7006实例,注意端口修改。
[pcts@ERAYT-01 redis-cluster]$ ls
7001 redis-trib.rb
[erayt@ERAYT-01 redis-cluster]$ cp 7001/ 7002 -r
[erayt@ERAYT-01 redis-cluster]$ cp 7001/ 7003 -r
[erayt@ERAYT-01 redis-cluster]$ cp 7001/ 7004 -r
[erayt@ERAYT-01 redis-cluster]$ cp 7001/ 7005 -r
[erayt@ERAYT-01 redis-cluster]$ cp 7001/ 7006 -r
第四步:启动所有的实例
[erayt@ERAYT-01 7001]$ ./redis-server redis.conf
[erayt@ERAYT-01 7001]$ cd ../7002
[erayt@ERAYT-01 7002]$ ./redis-server redis.conf
[erayt@ERAYT-01 7002]$ cd ../7003
[erayt@ERAYT-01 7003]$ ./redis-server redis.conf
[erayt@ERAYT-01 7003]$ cd ../7004
[erayt@ERAYT-01 7004]$ ./redis-server redis.conf
[erayt@ERAYT-01 7004]$ cd ../7005
[erayt@ERAYT-01 7005]$ ./redis-server redis.conf
[erayt@ERAYT-01 7005]$ cd ../7006
[erayt@ERAYT-01 7006]$ ./redis-server redis.conf
启动后,查看redis
[erayt@ERAYT-01 7006]$ ps aux | grep redis
erayt 3265 0.1 0.1 35548 1884 ? Ssl 02:38 0:00 ./redis-server *:7001 [cluster]
erayt 3269 0.1 0.1 35548 1884 ? Ssl 02:38 0:00 ./redis-server *:7002 [cluster]
erayt 3273 0.1 0.1 35548 1884 ? Ssl 02:38 0:00 ./redis-server *:7003 [cluster]
erayt 3277 0.1 0.1 35548 1884 ? Ssl 02:38 0:00 ./redis-server *:7004 [cluster]
erayt 3281 0.1 0.1 35548 1884 ? Ssl 02:38 0:00 ./redis-server *:7005 [cluster]
erayt 3285 0.1 0.1 35548 1888 ? Ssl 02:38 0:00 ./redis-server *:7006 [cluster]
erayt 3320 0.0 0.0 6052 788 pts/1 S+ 02:44 0:00 grep redis
第五步:创建集群
[erayt@ERAYT-01 redis-cluster]$ ls
7001 7002 7003 7004 7005 7006 redis-trib.rb
[erayt@ERAYT-01 redis-cluster]$ ./redis-trib.rb create --replicas 1 192.168.232.128:7001 192.168.232.128:7002 192.168.232.128:7003 192.168.232.128:7004 192.168.232.128:7005 192.168.232.128:7006
replicas 后面的1表示的是每个主机都带有1个从机
>>> Creating cluster
Connecting to node 192.168.232.128:7001: OK
Connecting to node 192.168.232.128:7002: OK
Connecting to node 192.168.232.128:7003: OK
Connecting to node 192.168.232.128:7004: OK
Connecting to node 192.168.232.128:7005: OK
Connecting to node 192.168.232.128:7006: OK
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.232.128:7001
192.168.232.128:7002
192.168.232.128:7003
Adding replica 192.168.232.128:7004 to 192.168.232.128:7001
Adding replica 192.168.232.128:7005 to 192.168.232.128:7002
Adding replica 192.168.232.128:7006 to 192.168.232.128:7003
M: 1455dfd4f6ba95c94fb9b78219afe477eb449897 192.168.232.128:7001
slots:0-5460 (5461 slots) master
M: 78912c846586d65c43a243eb1780426bf2e363f2 192.168.232.128:7002
slots:5461-10922 (5462 slots) master
M: b9f0452e588df5eeec3ce9bc461f8327727b99c8 192.168.232.128:7003
slots:10923-16383 (5461 slots) master
S: a88a707d4c8a2db36365c78d69b8450c1b5f201b 192.168.232.128:7004
replicates 1455dfd4f6ba95c94fb9b78219afe477eb449897
S: 1e88baa5c85261c7803f6b7e8dec086612bd3d23 192.168.232.128:7005
replicates 78912c846586d65c43a243eb1780426bf2e363f2
S: 8a130089dc3158b55a110b8957fac85d5d0917cb 192.168.232.128:7006
replicates b9f0452e588df5eeec3ce9bc461f8327727b99c8
日志可以看到7001 7002 7003是主节点 7004 7005 7006是从节点,还可以看到redis 根据节点数量大致均等的将哈希槽映射到不同的节点。
Redis集群连接
命令:./redis-cli –h 127.0.0.1 –p 7001 –c
注意:-c 连接redis集群
cluster info 查看集群状态
[erayt@ERAYT-01 7001]$ ./redis-cli -p 7001 -c
127.0.0.1:7001> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_sent:267
cluster_stats_messages_received:267
127.0.0.1:7001>
查看集群中的节点
127.0.0.1:7001> cluster nodes
8a130089dc3158b55a110b8957fac85d5d0917cb 192.168.232.128:7006 slave b9f0452e588df5eeec3ce9bc461f8327727b99c8 0 1563823021952 6 connected
1e88baa5c85261c7803f6b7e8dec086612bd3d23 192.168.232.128:7005 slave 78912c846586d65c43a243eb1780426bf2e363f2 0 1563823027004 5 connected
1455dfd4f6ba95c94fb9b78219afe477eb449897 192.168.232.128:7001 myself,master - 0 0 1 connected 0-5460
a88a707d4c8a2db36365c78d69b8450c1b5f201b 192.168.232.128:7004 slave 1455dfd4f6ba95c94fb9b78219afe477eb449897 0 1563823023969 4 connected
78912c846586d65c43a243eb1780426bf2e363f2 192.168.232.128:7002 master - 0 1563823025989 2 connected 5461-10922
b9f0452e588df5eeec3ce9bc461f8327727b99c8 192.168.232.128:7003 master - 0 1563823024979 3 connected 10923-16383
127.0.0.1:7001>
添加主节点
集群创建成功后可以向集群中添加节点,下面是添加一个master主节点
添加7007结点作为新节点
1.先依照上面的复制一个redis实例,修改端口为7007,启动该服务
[erayt@ERAYT-01 7007]$ ./redis-server redis.conf
2.添加7007结点作为新节点
执行命令:./redis-trib.rb add-node 127.0.0.1:7007 127.0.0.1:7001
[erayt@ERAYT-01 redis-cluster]$ ./redis-trib.rb add-node 192.168.232.128:7007 192.168.232.128:7001
3.查看集群结点发现7007已添加到集群中
127.0.0.1:7001> cluster nodes
d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3 192.168.232.128:7007 master - 0 1563824280943 0 connected
8a130089dc3158b55a110b8957fac85d5d0917cb 192.168.232.128:7006 slave b9f0452e588df5eeec3ce9bc461f8327727b99c8 0 1563824284990 6 connected
1e88baa5c85261c7803f6b7e8dec086612bd3d23 192.168.232.128:7005 slave 78912c846586d65c43a243eb1780426bf2e363f2 0 1563824280340 5 connected
1455dfd4f6ba95c94fb9b78219afe477eb449897 192.168.232.128:7001 myself,master - 0 0 1 connected 0-5460
a88a707d4c8a2db36365c78d69b8450c1b5f201b 192.168.232.128:7004 slave 1455dfd4f6ba95c94fb9b78219afe477eb449897 0 1563824283975 4 connected
78912c846586d65c43a243eb1780426bf2e363f2 192.168.232.128:7002 master - 0 1563824279930 2 connected 5461-10922
b9f0452e588df5eeec3ce9bc461f8327727b99c8 192.168.232.128:7003 master - 0 1563824282964 3 connected 10923-16383
127.0.0.1:7001>
hash槽重新分配
添加完主节点需要对主节点进行hash槽分配,这样该主节才可以存储数据。
1.查看集群中槽占用情况
127.0.0.1:7001> cluster nodes
d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3 192.168.232.128:7007 master - 0 1563824280943 0 connected
8a130089dc3158b55a110b8957fac85d5d0917cb 192.168.232.128:7006 slave b9f0452e588df5eeec3ce9bc461f8327727b99c8 0 1563824284990 6 connected
1e88baa5c85261c7803f6b7e8dec086612bd3d23 192.168.232.128:7005 slave 78912c846586d65c43a243eb1780426bf2e363f2 0 1563824280340 5 connected
1455dfd4f6ba95c94fb9b78219afe477eb449897 192.168.232.128:7001 myself,master - 0 0 1 connected 0-5460
a88a707d4c8a2db36365c78d69b8450c1b5f201b 192.168.232.128:7004 slave 1455dfd4f6ba95c94fb9b78219afe477eb449897 0 1563824283975 4 connected
78912c846586d65c43a243eb1780426bf2e363f2 192.168.232.128:7002 master - 0 1563824279930 2 connected 5461-10922
b9f0452e588df5eeec3ce9bc461f8327727b99c8 192.168.232.128:7003 master - 0 1563824282964 3 connected 10923-16383
127.0.0.1:7001>
redis集群有16384个槽,集群中的每个结点分配自已槽,通过查看集群结点可以看到槽占用情况。
可以看到7001分配的0-5460、7002分配的 5461-10922、7003分配的10923-16383
2.连接上集群(连接集群中任意一个可用结点都行)
[erayt@ERAYT-01 redis-cluster]$ ./redis-trib.rb reshard 192.168.232.128:7001
2.1 输入要分配的槽数量
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)?
2.2 输入:1000,表示要分配1000个槽 点击回车 根据具体情况定
How many slots do you want to move (from 1 to 16384)? 1000
What is the receiving node ID?
2.3 输入接收槽的结点id 输入7007对应的编号(cluster nodes命令查看)
What is the receiving node ID? d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3
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:
2.4 输入源结点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:
槽的总量是一定的,之前都已经全部分配给了7001/7002/7003,现在要重新从分好的的节点拿出来一些分给7007节点。
可以输入多个节点的编号,每次输完一个点击回车,输完所以的输入done表示输入完成。表示7007的槽来源这几个节点
可以输入all,表示所有具有槽的节点都需要去分配一些给7007,我这里输入的是all
2.5 输入yes开始移动槽到目标结点id
Do you want to proceed with the proposed reshard plan (yes/no)? yes
2.6 查看7007节点槽的分配
d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3 192.168.232.128:7007 master - 0 1563826629735 7 connected 0-332 5461-5794 10923-11255
添加从节点
集群创建成功后也可以向集群中添加从节点。
添加7008从结点,将7008作为7007的从结点
命令:./redis-trib.rb add-node --slave --master-id 主节点id 新节点的ip和端口 旧节点ip和端口
[erayt@ERAYT-01 redis-cluster]$ ./redis-trib.rb add-node --slave --master-id d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3 192.168.232.128:7008 192.168.101.3:7007
d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3 是刚刚7007的id
删除节点
[erayt@ERAYT-01 redis-cluster]$ ./redis-trib.rb del-node 192.168.232.128:7007 d1c9dbe277c82b36831b01fe29a0cac1f45f0dd3
删除已经占有hash槽的结点会失败,报错如下:
[ERR] Node 192.168.232.128:7007 is not empty! Reshard data away and try again.
需要将该结点占用的hash槽分配出去
https://blog.csdn.net/weixin_39963744/article/details/111616889