[TOC]
我叫张贺,贪财好色。一名合格的LINUX运维工程师,专注于LINUX的学习和研究,曾负责某中型企业的网站运维工作,爱好佛学和跑步。 个人博客:传送阵 笔者微信:
zhanghe15069028807
,非诚勿扰。
Redis集群
理论
Redis集群起码是三个服务器做,每个服务器里面都有两个实例,两个实例并不能是单纯的一主一从,而是错开,防止一个服务器挂了之后,数据丢失,如下图所示:
当集群安装好之后,会生成16384个槽位用于存储键值,其中0--5500在master1这个槽位上,5501--11000在master2槽位上,11001--16384在第三个槽位上,如下所示:
当我们存储一个键值的时候,redis会通过一个公式计算出一个值,假如这个值 是6666的话,那么这个键值就存储到master2这个实例上,依次类推,存的时候是这样存,取的时候同样也是这样取。
客户端在连接的时候无论连接哪一个节点都可以,如果本节点上没有要存取的键值的话,本节点会帮客户端转发,客户端不需要重新连接。
万一其中的一个主挂了,并不是从立马主顶上,而是剩下的两个主一同投票来决定,并不是利用了“哨兵sentinel”的机制。
安装
我们操作的时候用一台服务器,然后开6个实例:7000-----7005
[root@NFS ~]# yum -y install ruby rubygems
//默认源在国外
[root@NFS ~]# gem sources -l
*** CURRENT SOURCES ***
https://rubygems.org/
//换成阿里云的
[root@NFS ~]# gem sources -a https://mirrors.aliyun.com/rubygems/
https://mirrors.aliyun.com/rubygems/ added to sources
//移除原来的
[root@NFS ~]# gem sources --remove https://rubygems.org/
https://rubygems.org/ removed from sources
//安装集群插件
[root@NFS ~]# gem install redis -v 3.3.3
Fetching: redis-3.3.3.gem (100%)
Successfully installed redis-3.3.3
Parsing documentation for redis-3.3.3
Installing ri documentation for redis-3.3.3
1 gem installed
//只有一个源了
[root@NFS ~]# gem sources -l
*** CURRENT SOURCES ***
https://mirrors.aliyun.com/rubygems/
//节点准备
mkdir /nosql/700{0..5}
vim /nosql/7000/redis.conf
port 7000
daemonize yes
pidfile /nosql/7000/redis.pid
loglevel notice
logfile "/nosql/7000/redis.log"
dbfilename dump.rdb
dir /nosql/7000
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
vim /nosql/7001/redis.conf
port 7001
daemonize yes
pidfile /nosql/7001/redis.pid
loglevel notice
logfile "/nosql/7001/redis.log"
dbfilename dump.rdb
dir /nosql/7001
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
vim /nosql/7002/redis.conf
port 7002
daemonize yes
pidfile /nosql/7002/redis.pid
loglevel notice
logfile "/nosql/7002/redis.log"
dbfilename dump.rdb
dir /nosql/7002
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
vim /nosql/7003/redis.conf
port 7003
daemonize yes
pidfile /nosql/7003/redis.pid
loglevel notice
logfile "/nosql/7003/redis.log"
dbfilename dump.rdb
dir /nosql/7003
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
vim /nosql/7004/redis.conf
port 7004
daemonize yes
pidfile /nosql/7004/redis.pid
loglevel notice
logfile "/nosql/7004/redis.log"
dbfilename dump.rdb
dir /nosql/7004
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
vim /nosql/7005/redis.conf
port 7005
daemonize yes
pidfile /nosql/7005/redis.pid
loglevel notice
logfile "/nosql/7005/redis.log"
dbfilename dump.rdb
dir /nosql/7005
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
redis-server /nosql/7000/redis.conf
redis-server /nosql/7001/redis.conf
redis-server /nosql/7002/redis.conf
redis-server /nosql/7003/redis.conf
redis-server /nosql/7004/redis.conf
redis-server /nosql/7005/redis.conf
[root@NFS ~]# ps -ef | grep redis
root 28437 1 0 14:07 ? 00:00:00 redis-server *:7000 [cluster]
root 28450 1 0 14:09 ? 00:00:00 redis-server *:7001 [cluster]
root 28452 1 0 14:09 ? 00:00:00 redis-server *:7002 [cluster]
root 28456 1 0 14:09 ? 00:00:00 redis-server *:7003 [cluster]
root 28458 1 0 14:09 ? 00:00:00 redis-server *:7004 [cluster]
root 28466 1 0 14:09 ? 00:00:00 redis-server *:7005 [cluster]
//将节点加入集群管理,--replicas 1代表一个主带一个从,前三个是主,后三个是对应的是从
redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
127.0.0.1:7000
127.0.0.1:7001
127.0.0.1:7002
Adding replica 127.0.0.1:7003 to 127.0.0.1:7000
Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
M: 7517120d8c2b37de8f94cfeb614d8032e24fc129 127.0.0.1:7000
slots:0-5460 (5461 slots) master
M: 367370edab7d5aef62fff5447f0f35e6ddbc8728 127.0.0.1:7001
slots:5461-10922 (5462 slots) master
M: cab39e65a84cbbb8db8ea6d6c04f998bba62876c 127.0.0.1:7002
slots:10923-16383 (5461 slots) master
S: 66af6f975ff30f4fa86dad5250fc2cbaa8dab592 127.0.0.1:7003
replicates 7517120d8c2b37de8f94cfeb614d8032e24fc129
S: bdc7a5dfc50b1d96f5510a5ee01b5ec85411c39a 127.0.0.1:7004
replicates 367370edab7d5aef62fff5447f0f35e6ddbc8728
S: 1a26aa7767c4db8ebe0cf0d937e6afc44eba531e 127.0.0.1:7005
replicates cab39e65a84cbbb8db8ea6d6c04f998bba62876c
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 127.0.0.1:7000)
M: 7517120d8c2b37de8f94cfeb614d8032e24fc129 127.0.0.1:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: bdc7a5dfc50b1d96f5510a5ee01b5ec85411c39a 127.0.0.1:7004
slots: (0 slots) slave
replicates 367370edab7d5aef62fff5447f0f35e6ddbc8728
S: 66af6f975ff30f4fa86dad5250fc2cbaa8dab592 127.0.0.1:7003
slots: (0 slots) slave
replicates 7517120d8c2b37de8f94cfeb614d8032e24fc129
M: 367370edab7d5aef62fff5447f0f35e6ddbc8728 127.0.0.1:7001
slots:5461-10922 (5462 slots) master
1 additional replica(s)
M: cab39e65a84cbbb8db8ea6d6c04f998bba62876c 127.0.0.1:7002
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: 1a26aa7767c4db8ebe0cf0d937e6afc44eba531e 127.0.0.1:7005
slots: (0 slots) slave
replicates cab39e65a84cbbb8db8ea6d6c04f998bba62876c
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
上面的内容有对应关系:
7000----7003
7001----7004
7002----7005
注意还有槽位
//查看集群主的状态
[root@NFS ~]# redis-cli -p 7000 cluster nodes | grep master
367370edab7d5aef62fff5447f0f35e6ddbc8728 127.0.0.1:7001 master - 0 1578378191503 2 connected 5461-10922
cab39e65a84cbbb8db8ea6d6c04f998bba62876c 127.0.0.1:7002 master - 0 1578378191503 3 connected 10923-16383
7517120d8c2b37de8f94cfeb614d8032e24fc129 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
//查看集群从的状态
[root@NFS ~]# redis-cli -p 7000 cluster nodes | grep slave
bdc7a5dfc50b1d96f5510a5ee01b5ec85411c39a 127.0.0.1:7004 slave 367370edab7d5aef62fff5447f0f35e6ddbc8728 0 1578378287351 5 connected
66af6f975ff30f4fa86dad5250fc2cbaa8dab592 127.0.0.1:7003 slave 7517120d8c2b37de8f94cfeb614d8032e24fc129 0 1578378287855 4 connected
1a26aa7767c4db8ebe0cf0d937e6afc44eba531e 127.0.0.1:7005 slave cab39e65a84cbbb8db8ea6d6c04f998bba62876c 0 1578378286845 6 connected
管理
增加新-主节点
mkdir /nosql/7006
mkdir /nosql/7007
vim /nosql/7006/redis.conf
port 7006
daemonize yes
pidfile /nosql/7006/redis.pid
loglevel notice
logfile "/nosql/7006/redis.log"
dbfilename dump.rdb
dir /nosql/7006
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
vim /nosql/7007/redis.conf
port 7007
daemonize yes
pidfile /nosql/7007/redis.pid
loglevel notice
logfile "/nosql/7007/redis.log"
dbfilename dump.rdb
dir /nosql/7007
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
redis-server /nosql/7007/redis.conf
redis-server /nosql/7006/redis.conf
//把7006加入7000所在的集群
redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
[ERR] Node 127.0.0.1:7006 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
解决办法:进入新加入的节点,flushdb,然后shutdown,然后重启,再加一遍就会成功。
//查看一下,7006没有槽位信息
[root@NFS ~]# redis-cli -p 7000 cluster nodes | grep master
367370edab7d5aef62fff5447f0f35e6ddbc8728 127.0.0.1:7001 master - 0 1578382465839 2 connected 5461-10922
cab39e65a84cbbb8db8ea6d6c04f998bba62876c 127.0.0.1:7002 master - 0 1578382465333 3 connected 10923-16383
7517120d8c2b37de8f94cfeb614d8032e24fc129 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
2860170269d03fc5c543eb33cbff0e2c54b26266 127.0.0.1:7006 master - 0 1578382464329 0 connected
//转移一部分槽位(重新分片)给7006,让共平均分配,应该把运行中的应用在停止一下,计算一下用总的除以4等于4096
redis-trib.rb reshard 127.0.0.1:7000
How many slots do you want to move (from 1 to 16384)? 4096 #给新的节点多少槽位
What is the receiving node ID? 2860170269d03fc5c543eb33cbff0e2c54b26266 #新节点的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
[root@NFS ~]# redis-cli -p 7000 cluster nodes | grep master #每人给了一点
367370edab7d5aef62fff5447f0f35e6ddbc8728 127.0.0.1:7001 master - 0 1578383170298 2 connected 6827-10922
cab39e65a84cbbb8db8ea6d6c04f998bba62876c 127.0.0.1:7002 master - 0 1578383172313 3 connected 12288-16383
7517120d8c2b37de8f94cfeb614d8032e24fc129 127.0.0.1:7000 myself,master - 0 0 1 connected 1365-5460
2860170269d03fc5c543eb33cbff0e2c54b26266 127.0.0.1:7006 master - 0 1578383171810 7 connected 0-1364 5461-6826 10923-12287
增加新-从节点
[root@NFS ~]# redis-trib.rb add-node --slave --master-id 2860170269d03fc5c543eb33cbff0e2c54b26266 127.0.0.1:7007 127.0.0.1:7000
[ERR] Node 127.0.0.1:7007 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
把7007关闭,然后除了配置文件之外全部清除,最后重启,最后再加一次就成功了。
[root@NFS 7007]# redis-cli -p 7000 cluster nodes | grep slave
abdacebbecf2c4c948dec63601ff3f8eb6c5a64d 127.0.0.1:7007 slave 2860170269d03fc5c543eb33cbff0e2c54b26266 0 1578384755252 7 connected
bdc7a5dfc50b1d96f5510a5ee01b5ec85411c39a 127.0.0.1:7004 slave 367370edab7d5aef62fff5447f0f35e6ddbc8728 0 1578384755756 5 connected
66af6f975ff30f4fa86dad5250fc2cbaa8dab592 127.0.0.1:7003 slave 7517120d8c2b37de8f94cfeb614d8032e24fc129 0 1578384755756 4 connected
1a26aa7767c4db8ebe0cf0d937e6afc44eba531e 127.0.0.1:7005 slave cab39e65a84cbbb8db8ea6d6c04f998bba62876c 0 1578384755252 6 connected
删除节点
删除节点7006之前,要把槽位移动走,不然把槽位也会一同给删除了,又要重新分片。
redis-trib.rb reshard 127.0.0.1:7000
# 移动多少,当时分配了4096个,现在也就要移动走这么多
# 让你选择接收的节点,填7000的ID
# 让你选择源节点,也就是要删除哪个节点,填7006的节点
# done
# yes
[root@NFS ~]# redis-cli -p 7000 cluster nodes | grep master
367370edab7d5aef62fff5447f0f35e6ddbc8728 127.0.0.1:7001 master - 0 1578385715675 2 connected 6827-10922
cab39e65a84cbbb8db8ea6d6c04f998bba62876c 127.0.0.1:7002 master - 0 1578385716180 3 connected 12288-16383
7517120d8c2b37de8f94cfeb614d8032e24fc129 127.0.0.1:7000 myself,master - 0 0 8 connected 0-6826 10923-12287
2860170269d03fc5c543eb33cbff0e2c54b26266 127.0.0.1:7006 master - 0 1578385716683 7 connected
//删除主节点
[root@NFS ~]# redis-trib.rb del-node 127.0.0.1:7006 2860170269d03fc5c543eb33cbff0e2c54b26266
[root@NFS ~]# redis-cli -p 7000 cluster nodes | grep slave
abdacebbecf2c4c948dec63601ff3f8eb6c5a64d 127.0.0.1:7007 slave 7517120d8c2b37de8f94cfeb614d8032e24fc129 0 1578385840781 8 connected
bdc7a5dfc50b1d96f5510a5ee01b5ec85411c39a 127.0.0.1:7004 slave 367370edab7d5aef62fff5447f0f35e6ddbc8728 0 1578385841286 5 connected
66af6f975ff30f4fa86dad5250fc2cbaa8dab592 127.0.0.1:7003 slave 7517120d8c2b37de8f94cfeb614d8032e24fc129 0 1578385841286 8 connected
1a26aa7767c4db8ebe0cf0d937e6afc44eba531e 127.0.0.1:7005 slave cab39e65a84cbbb8db8ea6d6c04f998bba62876c 0 1578385841790 6 connected
//删除从节点
[root@NFS ~]# redis-trib.rb del-node 127.0.0.1:7007 abdacebbecf2c4c948dec63601ff3f8eb6c5a64d