redis-cluster集群详解

一 集群环境搭建
1 集群环境介绍:
虚拟机6台:
192.168.4.51
192.168.4.52
192.168.4.53
192.168.4.54
192.168.4.55
192.168.4.56
每台虚拟机安装redis服务,修改redis配置文件IP地址为自身IP地址,取消回环IP,不开启密码验证。

2 修改主配置文件 (6台)

[root@mysql51 ~]# vim /etc/redis/6379.conf
815 cluster-enabled yes                                                //开启集群
823 cluster-config-file nodes-6351.conf                    //本机用来存储集群信息的文件名
829 cluster-node-timeout 5000                                   //集群节点超时时间

3 重启redis服务,查看服务端口(6台)

[root@mysql51 ~]# ss -antulp | grep redis
tcp    LISTEN     0      128    192.168.4.51:6351                  *:*                   users:(("redis-server",pid=2122,fd=6))
tcp    LISTEN     0      128    192.168.4.51:16351                 *:*                  users:(("redis-server",pid=2122,fd=8))

4 查看集群信息文件原始状态:

[root@mysql55 ~]#  cd /var/lib/redis/6379
[root@mysql55 6379]# cat nodes-6355.conf 
e0f9f77ba2bd2468baa1a2e9d88d494210d406bf :0@0 myself,master - 0 0 0 connected               //显示自己的ID值 
vars currentEpoch 0 lastVoteEpoch 0

查看集群原始状态2:

192.168.4.55:6355> cluster info
cluster_state:fail                                                   //创建集群后才显示OK
cluster_slots_assigned:0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:1
cluster_size:0
cluster_current_epoch:0
cluster_my_epoch:0
cluster_stats_messages_sent:0
cluster_stats_messages_received:0

192.168.4.55:6355> cluster nodes                        //查看集群中的节点(目前只能看到主机,还没有创建集群)
e0f9f77ba2bd2468baa1a2e9d88d494210d406bf :6355@16355 myself,master - 0 0 0 connected

二 创建集群
1 部署管理主机:
在51做redis服务器的同时,同时做管理集群的的服务器
rubygems安装.gem结尾的软件包。ruby是一个解释器,解释ruby脚本

[root@mysql51 ~]# yum -y install ruby rubygems
[root@mysql51 redis-cluster]# rpm -ivh ruby-devel-2.0.0.648-30.el7.x86_64.rpm
[root@mysql51 redis-cluster]# gem install redis-3.2.1.gem

2 为创建集群的脚本redis-trib.rb设置全局环境变量

[root@mysql51 src]# echo $PATH
/root/perl5/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@mysql51 ~]# cd /root/redis2/redis-4.0.8/src
[root@mysql51 src]# ls *.rb
redis-trib.rb
[root@mysql51 ~]# mkdir /root/bin
[root@mysql51 src]# cp redis-trib.rb /root/bin
[root@mysql51 src]# ls /root/bin
redis-trib.rb
[root@mysql51 src]# redis-trib.rb help          //脚本可以在全局环境下单独使用

3 创建集群:(环境为3主3从)

[root@mysql51 ~]# redis-trib.rb create --replicas 1 \    //replicas 1代表一主一从
> 192.168.4.51:6351 192.168.4.52:6352 \
> 192.168.4.53:6353 192.168.4.54:6354 \
> 192.168.4.55:6355 192.168.4.56:6356

>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.4.51:6351
192.168.4.52:6352
192.168.4.53:6353
Adding replica 192.168.4.55:6355 to 192.168.4.51:6351
Adding replica 192.168.4.56:6356 to 192.168.4.52:6352
Adding replica 192.168.4.54:6354 to 192.168.4.53:6353
M: 88e7b3ed90d604cb3170309b084c82defcb32e8e 192.168.4.51:6351
   slots:0-5460 (5461 slots) master                    //第一个槽的范围0-5460
M: 8cb2e1a1c9df060d95ec5f7c0094bed8d69979b6 192.168.4.52:6352
   slots:5461-10922 (5462 slots) master                //第二个槽的范围5461-10922
M: aa1dd1ea0e5328541764f81541046bfd14acf20e 192.168.4.53:6353
   slots:10923-16383 (5461 slots) master              //第三个槽的范围10923-16383
S: f71b5bc43cf4be71516f87ca56224d81a10795c8 192.168.4.54:6354
   replicates aa1dd1ea0e5328541764f81541046bfd14acf20e
S: e0f9f77ba2bd2468baa1a2e9d88d494210d406bf 192.168.4.55:6355
   replicates 88e7b3ed90d604cb3170309b084c82defcb32e8e
S: f169df56c739577d2d0cba2f883840a32631d511 192.168.4.56:6356
   replicates 8cb2e1a1c9df060d95ec5f7c0094bed8d69979b6
Can I set the above configuration? (type 'yes' to accept): yes
2.168.4.55:6355 192.168.4.56:6356

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.                     //创建成功,总槽数16384个

################################
创建集群时报错解析:

Can I set the above configuration? (type 'yes' to accept): yes
/usr/local/share/gems/gems/redis-3.2.1/lib/redis/client.rb:113:in `call': ERR Slot 16287 is already busy (Redis::CommandError)
	from /usr/local/share/gems/gems/redis-3.2.1/lib/redis.rb:2556:in `block in method_missing'
	from /usr/local/share/gems/gems/redis-3.2.1/lib/redis.rb:37:in `block in synchronize'

查看51上的集群日志文件,在集群创建未完成时,连接槽均为0

[root@mysql51 ~]# cat /var/lib/redis/6379/nodes-6351.conf
删除/var/lib/redis/6379/目录下的两个文件 dump.rdb  nodes-6351.conf
重新启动redis服务
继续执行创建集群命令即可

#################################################
4 测试:
1)检测集群中的某个redid的master主机:

[root@mysql51 ~]# redis-trib.rb check 192.168.4.52:6352
>>> Performing Cluster Check (using node 192.168.4.52:6352)
M: 8cb2e1a1c9df060d95ec5f7c0094bed8d69979b6 192.168.4.52:6352
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: aa1dd1ea0e5328541764f81541046bfd14acf20e 192.168.4.53:6353
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: f169df56c739577d2d0cba2f883840a32631d511 192.168.4.56:6356
   slots: (0 slots) slave
   replicates 8cb2e1a1c9df060d95ec5f7c0094bed8d69979b6
S: f71b5bc43cf4be71516f87ca56224d81a10795c8 192.168.4.54:6354
   slots: (0 slots) slave
   replicates aa1dd1ea0e5328541764f81541046bfd14acf20e
S: e0f9f77ba2bd2468baa1a2e9d88d494210d406bf 192.168.4.55:6355
   slots: (0 slots) slave
   replicates 88e7b3ed90d604cb3170309b084c82defcb32e8e
M: 88e7b3ed90d604cb3170309b084c82defcb32e8e 192.168.4.51:6351
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

通过查看
主库192.168.4.51 它的从库为:192.168.4.55
主库192.168.4.52 它的从库为:192.168.4.56
主库192.168.4.53 它的从库为:192.168.4.54

2 )客户端192.168.4.50 访问集群管理服务器51,检测redis集群的分布式存储策略

 [root@mysql50 ~]# redis-cli -c -h 192.168.4.51 -p 6351            //访问集群时需要加-c选项
192.168.4.51:6351> keys *
(empty list or set)
192.168.4.51:6351> set x 100
-> Redirected to slot [16287] located at 192.168.4.53:6353   (自动分配到了数据库53主库)
OK
192.168.4.53:6353> keys *           
1) "x"
192.168.4.53:6353> set q 455
OK
192.168.4.53:6353> set w 400
-> Redirected to slot [3696] located at 192.168.4.51:6351
OK
192.168.4.51:6351> set q 88
-> Redirected to slot [11958] located at 192.168.4.53:6353
OK
192.168.4.53:6353> get w
-> Redirected to slot [3696] located at 192.168.4.51:6351
"400"

关于存储的原理:
关于总槽数16384,无论有多少个主库,这个值是不变的。
5461个槽并不代表可以存储5461个变量。具体存多少个变量,根据主机的内存决定。
存储时,做一个计算,CRC16算法,算出hash槽的值,决定这个变量存在哪里,决定去哪里取值
将变量名和CRC16算法做一个运算,得出来一个数和16384做取余运算,得出来的余数即为每次设置或者查询变量时Redirected重定向的槽数,从而根据槽数决定重定向到哪个主库。

redis高可用,当主库宕机后,它对应从库会自动升级为主库

三 管理集群
1 master选举测试:
当52宕机后,52的从库56会自动被选举为主库
当52修好启动后,52会自动成为56的从库,自动同步宕机期间在主库52上产生的数据
在正常哪个的访问过程中,为了实现真正的高可用,还需要写一个脚本,当主库宕机后,用户访问主数据库的ip地址自动切换为之前从库的IP地址,不然访问会出错。

集群不能用的情况:
有半数或者半数以上的主库机器挂掉,集群就不能用了
把一个从库升级成主,没有从库,集群不能用(前提是:有半数或者半数以上的主库机器挂掉)
一个主库挂掉,它的从库自动顶替为主库,正常使用(前提是:有半数或者半数以上的主库机器能用),挂掉的主库修复好后,会成为从库,不会抢占为主
当一组组从全挂掉之后,集群不可用
可以设置一主两从

2 添加新的节点:
准备两个新的redis节点
1)将57添加进集群为主库

 [root@mysql51 ~]# redis-trib.rb add-node 192.168.4.57:6357 192.168.4.51:6351

2)为57分配hash槽(重新分片)手动对集群进行分片迁移 选项:reshard 重新分配hash槽

[root@mysql51 ~]# redis-trib.rb reshard 192.168.4.51:6351
How many slots do you want to move (from 1 to 16384)? 4096       //指定移出hash槽的个数
What is the receiving node ID? 57488ae2bc84ce1b9cf1956c5e47e4d7c7372808 //指定接受hash槽的主机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     //指定移出hash槽的主机ID
do you want to proceed with the proposed reshard plan(yes/no) yes //你确定要接受这个分片方式吗?

3)查看集群状态:再次查看发现4.57有4096个hash slot

[root@mysql51 ~]# redis-trib.rb check 192.168.4.51:6351
>>> Performing Cluster Check (using node 192.168.4.51:6351)
M: 88e7b3ed90d604cb3170309b084c82defcb32e8e 192.168.4.51:6351
   slots:1365-5460 (4096 slots) master
   1 additional replica(s)
S: e0f9f77ba2bd2468baa1a2e9d88d494210d406bf 192.168.4.55:6355
   slots: (0 slots) slave
   replicates 88e7b3ed90d604cb3170309b084c82defcb32e8e
M: f71b5bc43cf4be71516f87ca56224d81a10795c8 192.168.4.54:6354
   slots:12288-16383 (4096 slots) master
   1 additional replica(s)

S: 8cb2e1a1c9df060d95ec5f7c0094bed8d69979b6 192.168.4.52:6352
   slots: (0 slots) slave
   replicates f169df56c739577d2d0cba2f883840a32631d511
S: aa1dd1ea0e5328541764f81541046bfd14acf20e 192.168.4.53:6353
   slots: (0 slots) slave
   replicates f71b5bc43cf4be71516f87ca56224d81a10795c8
M: 57488ae2bc84ce1b9cf1956c5e47e4d7c7372808 192.168.4.57:6357
   slots:0-1364,5461-6826,10923-12287 (4096 slots) master
   0 additional replica(s)
M: f169df56c739577d2d0cba2f883840a32631d511 192.168.4.56:6356
   slots:6827-10922 (4096 slots) master
   1 additional replica(s)

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

[root@mysql50 ~]# redis-cli -c -h 192.168.4.57 -p 6357
192.168.4.57:6357> keys *
1) "uq"
2) "rl"
3) "yc"
4) "uu"
5) "uer"
6) "we"
7) "q"
数据来源于分过来的hash槽

4) 添加从库并指定主库:(默认情况下,不指定主库ID时,谁的从库最少,那么就会成为它的从库)

[root@mysql51 ~]# redis-trib.rb add-node --slave 192.168.4.58:6358 192.168.4.51:6351

另一种指定主库ID的写法:
[root@mysql51 ~]# redis-trib.rb add-node --slave --master-id 2e1584d4a4885288f26e314197f97d12e99576ce 192.168.4.58:6358 192.168.4.51:6351


[root@mysql51 ~]# redis-trib.rb check 192.168.4.51:6351
>>> Performing Cluster Check (using node 192.168.4.51:6351)
M: 88e7b3ed90d604cb3170309b084c82defcb32e8e 192.168.4.51:6351
   slots:1365-5460 (4096 slots) master
   1 additional replica(s)
S: e0f9f77ba2bd2468baa1a2e9d88d494210d406bf 192.168.4.55:6355
   slots: (0 slots) slave
   replicates 88e7b3ed90d604cb3170309b084c82defcb32e8e
M: f71b5bc43cf4be71516f87ca56224d81a10795c8 192.168.4.54:6354
   slots:12288-16383 (4096 slots) master
   1 additional replica(s)
S: 4726211191d55c54bfb72d9a56f7f0ed040a36a4 192.168.4.58:6358
   slots: (0 slots) slave
   replicates 57488ae2bc84ce1b9cf1956c5e47e4d7c7372808
S: 8cb2e1a1c9df060d95ec5f7c0094bed8d69979b6 192.168.4.52:6352
   slots: (0 slots) slave
   replicates f169df56c739577d2d0cba2f883840a32631d511
S: aa1dd1ea0e5328541764f81541046bfd14acf20e 192.168.4.53:6353
   slots: (0 slots) slave
   replicates f71b5bc43cf4be71516f87ca56224d81a10795c8
M: 57488ae2bc84ce1b9cf1956c5e47e4d7c7372808 192.168.4.57:6357
   slots:0-1364,5461-6826,10923-12287 (4096 slots) master
   1 additional replica(s)
M: f169df56c739577d2d0cba2f883840a32631d511 192.168.4.56:6356
   slots:6827-10922 (4096 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered

5)移除从节点:

[root@mysql51 ~]# redis-trib.rb del-node 192.168.4.58:6358 4726211191d55c54bfb72d9a56f7f0ed040a36a4
>>> Removing node 4726211191d55c54bfb72d9a56f7f0ed040a36a4 from cluster 192.168.4.58:6358
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

移除的同时会关闭被移除主机的redis服务
登录58主机的redis服务,能看到之前的数据,但是没办法获取值

[root@mysql58 utils]# redis-cli
192.168.4.58:6358> keys *
1) "uer"
2) "q"
3) "we"
4) "uu"
5) "yc"
6) "rl"
7) "uq"
192.168.4.58:6358> get q;
(error) MOVED 15440 192.168.4.54:6354

192.168.4.58:6358> cluster reset 重置集群信息(所有集群的信息将在本数据库清除)
进入配置文件 /etc/redis/6379.conf 将配置集群的三个选项注释,
[root@mysql58 utils]# rm -rf /var/lib/redis/6379/nodes-6358.conf
再重启redis服务即可

当完成以上步骤后,这个58主机的redis数据库就时一台单独的数据库服务器,和集群没有关系了,也没有数据了。

注意:当没有进行cluster reset 重置时,先进入配置文件注释掉集群信息,再重启服务后,集群的数据会在数据库内保留,而且可以正常获取数据
192.168.4.58:6358> get yc
“09”
192.168.4.58:6358> get q
“88”
192.168.

6)移除主节点:
先移除57的hash槽

[root@mysql51 ~]# redis-trib.rb reshard 192.168.4.51:6351
How many slots do you want to move (from 1 to 16384)? 4096       //移出多少个hash槽
What is the receiving node ID?88e7b3ed90d604cb3170309b084c82defcb32e8e //把hash槽移给谁
Source node #1:57488ae2bc84ce1b9cf1956c5e47e4d7c7372808  //从哪里取hash槽
Source node #2:done  // 结束,指定从57一台主机上取hash
Do you want to proceed with the proposed reshard plan (yes/no)?yes  //是否接受这个方式

[root@mysql51 ~]# redis-trib.rb check 192.168.4.51:6351
M: 57488ae2bc84ce1b9cf1956c5e47e4d7c7372808 192.168.4.57:6357
   slots: (0 slots) master
   0 additional replica(s)

删除集群主机:

[root@mysql51 ~]# redis-trib.rb del-node 192.168.4.57:6357 57488ae2bc84ce1b9cf1956c5e47e4d7c7372808

主库被移除后,数据库内数据被清空,因为hash槽被释放了
192.168.4.57:6357> cluster reset
进入配置文件注释掉集群信息,删除集群日志文件/var/lib/redis/6379/nodes-6357.conf
重启redis服务即可。

##################################################

怎么样把拿出来的主机再次放入集群
cluster reset
删除集群日志文件/var/lib/redis/6379/nodes-6357.conf
重启redis服务
再往

猜你喜欢

转载自blog.csdn.net/weixin_42104231/article/details/84715753