同样接着第一篇redis部署继续往下:
redis集群起始于redis3.0版本以后
这里我们用一台服务器模拟6个节点
mkdir /opt
cd /opt
mkdir `seq 7001 7008`
cp /etc/redis/6379.conf ./
vim 6379.conf(pidfile要改,logfile要改,dbfilename要改,dir要改,还要加入集群需要的三行参数)
pidfile /var/run/redis_6379.pid
logfile "/var/log/redis_6379.log"
dbfilename dump_6379.rdb
dir /opt/6379
新内容一般插入到端口下面
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
统一替换
sed 's/6379/7008/g' 6379.conf >7008/redis.conf
sed 's/6379/7007/g' 6379.conf >7007/redis.conf
sed 's/6379/7006/g' 6379.conf >7006/redis.conf
sed 's/6379/7005/g' 6379.conf >7005/redis.conf
sed 's/6379/7004/g' 6379.conf >7004/redis.conf
sed 's/6379/7003/g' 6379.conf >7003/redis.conf
sed 's/6379/7002/g' 6379.conf >7002/redis.conf、
sed 's/6379/7001/g' 6379.conf >7001/redis.conf
启动redis节点
可以用for循环命令:
for i in `seq 7001 7008` do cd /opt/$i && /usr/local/redis/bin/redis-server redis.conf;done
还可以依次去连接每个端口并info查看一定要保证全部启动正常
redis-cli -h 10.3.45.233 -p 7001
10.3.45.233:7001> info
redis-cli -h 10.3.45.233 -p 7002
10.3.45.233:7002> info
redis-cli -h 10.3.45.233 -p 7003
10.3.45.233:7003> info
redis-cli -h 10.3.45.233 -p 7004
10.3.45.233:7004> info
redis-cli -h 10.3.45.233 -p 7005
10.3.45.233:7005> info
redis-cli -h 10.3.45.233 -p 7006
10.3.45.233:7006> info
redis-cli -h 10.3.45.233 -p 7007
10.3.45.233:7007> info
redis-cli -h 10.3.45.233 -p 7008
10.3.45.233:7008> info
由于redis集群需要使用ruby命令。所以我们需要安装ruby
安装ruby,可以取消ssl验证参数:--no-check-certificate
cd /usr/local/src
wget --no-check-certificate https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.3.tar.gz
tar xf ruby-2.5.3.tar.gz
cd ruby-2.5.3
./configure --prefix=/usr/local/ruby
make
make install
添加环境变量:
vim /etc/profile
export PATH=$PATH:/usr/local/ruby/bin
source /etc/profilegem install redis
ruby管理工具gem安装redis
gem install redis
拷贝ruby脚本redis-trib这个脚本用来便于管理redis
cp /usr/local/src/redis-5.0.2/src/redis-trib.rb /usr/local/bin/redis-trib
创建集群使用 redis-trib 的 create 命令完成
redis-trib create –replicas 1 10.3.45.233:7001 10.3.45.233:7002 10.3.45.233:7003 10.3.45.233:7004 10.3.45.233:7005 10.3.45.233:7006
#WARNING: redis-trib.rb is not longer available!
#上面的警告,原因是因为redis5.0使用redis-cli作为创建集群的命令,使用c语言实现,不再使用ruby语言。也就是说上面的命令适用于redis5.0版本之前的,那么下面这条命令才是5.0版本以后的集群创建命令,所以说如果你用的redis5.0以上的版本就可以不用安装ruby。
创建集群:
redis5以后创建集群命令不再用redis-trib.rb,而是回归于redis-cli
cd /usr/local/bin
./redis-cli --cluster create --cluster-replicas 1 10.3.45.233:7001 10.3.45.233:7002 10.3.45.233:7003 10.3.45.233:7004 10.3.45.233:7005 10.3.45.233:7006
从结果看redis创建集群的时候回自动把后面三个IP设置成前三个IP的slave。
通过连接某一台集群内的服务是否配合正常
redis连接集群内的节点要加-c参数
[root@localhost ~]# redis-cli -c -h 10.3.45.233 -p 7001
10.3.45.233:7001> info
上面可以看到7001为master,7004分配为它的slave。
还可以在master上set一个key然后去slave查看数据是否同步完成
[root@localhost ~]# redis-cli -c -h 10.3.45.233 -p 7001
10.3.45.233:7001> set key 123
-> Redirected to slot [12539] located at 10.3.45.233:7003
OK
10.3.45.233:7003>
[root@localhost ~]# redis-cli -c -h 10.3.45.233 -p 7001
10.3.45.233:7001> get keys *
(error) ERR wrong number of arguments for 'get' command
10.3.45.233:7001> keys *
(empty list or set)
10.3.45.233:7001> exit
[root@localhost ~]# redis-cli -c -h 10.3.45.233 -p 7006
10.3.45.233:7006> keys *
1) "key"
10.3.45.233:7006> get key
-> Redirected to slot [12539] located at 10.3.45.233:7003
"123"
10.3.45.233:7003> exit
[root@localhost ~]# redis-cli -c -h 10.3.45.233 -p 7004
10.3.45.233:7004> keys *
(empty list or set)
10.3.45.233:7004> get key
-> Redirected to slot [12539] located at 10.3.45.233:7003
"123"
10.3.45.233:7003> set key1 abc
-> Redirected to slot [9189] located at 10.3.45.233:7002
OK
10.3.45.233:7002> exit
[root@localhost ~]# redis-cli -c -h 10.3.45.233 -p 7005
10.3.45.233:7005> get key1
-> Redirected to slot [9189] located at 10.3.45.233:7002
"abc"
10.3.45.233:7002> keys *
1) "key1"
10.3.45.233:7002>
细节发现客户端连接加-c选项的时候,存储和提取key的时候不断在7001和7003之间跳转,这个称为客户端重定向。之所以发生客户端重定向,是因为Redis Cluster中的每个Master节点都会负责一部分的槽(slot),存取的时候都会进行键值空间计算定位key映射在哪个槽(slot)上,如果映射的槽(slot)正好是当前Master节点负责则直接存取,否则就跳转到其他Master节点负的槽(slot)中存取,这个过程对客户端是透明的。继续看下面的集群分区原理。
从上面集群的简单操作中,我们已经知道redis存取key的时候,都要定位相应的槽(slot)。
Redis 集群键分布算法使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot), 它们的编号为0、1、2、3……16382、16383,这个槽是一个逻辑意义上的槽,实际上并不存在。redis中的每个key都属于这 16384 个哈希槽的其中一个,存取key时都要进行key->slot的映射计算。
和memcached一样,redis也采用一定的算法进行键-槽(key->slot)之间的映射。memcached采用一致性哈希(consistency hashing)算法进行键-节点(key-node)之间的映射,而redis集群使用集群公式来计算键 key 属于哪个槽:
无论是memcached的一致性哈希算法,还是redis的集群分区,最主要的目的都是在移除、添加一个节点时对已经存在的缓存数据的定位影响尽可能的降到最小。redis将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点
还可以在客户端直接查看集群信息和集群节点信息
cluster nodes
cluster info
集群添加节点
可以用redis-cli –cluster help查看帮助
语法:add-node new_host:new_port existing_host:existing_port
这是redis5.0版本的用法,5.0之前的版本应该只需去掉—cluster并且把redis-cli换成redis-trib.rh就可以。
添加7007节点
redis-cli –cluster add-node 10.3.45.233:7007 10.3.45.233:7001
从集群节点信息可以看出新添加的节点是没有分配任何槽位,这样的话在集群中是不能写入数据到这个节点的,也就是不会重定向到这个节点,除非单独连接这个节点,所以需要给新节点进行重新分片(迁移槽位)
节点重新分片命令用reshard
redis-cli --cluster reshard 10.3.45.233:7007
迁移槽位之后再看节点信息,0-332,5461-5794,10923-11255分配了1000个槽位如下正常
再添加一个从节点7008,并设置7007成为7008的master。
redis-cli --cluster add-node 10.3.45.233:7008 10.3.45.233:7001 --cluster-slave --cluster-master-id 69ed043676047f98c33c16ecce23bb26ad8d24a7
注意:如果是5.0以前的版本是不需要重新添加7008的,只需要客户端连接到7008里面去执行命令 cluster replicate后面跟上主节点id就可以了。
删除节点
语法:redis-cli --cluster del-node 127.0.0.1:7000
注意:删除节点之前要先kill掉集群服务节点的进程。
节点数量:在故障转移阶段,需要由主节点投票选出哪个从节点成为新的主节点;从节点选举胜出需要的票数为 N/2+1;其中 N 为主节点数量(包括故障主节点),但故障主节点实际上不能投票。
因此为了能够在故障发生时顺利选出从节点,集群中至少需要 3 个主节点(且部署在不同的物理机上),否则当存活的主节点数小于总节点数的一半时,整个集群就无法提供服务了。