注意事项:
必须使用六个节点: 其中三个为主节点, 而其余三个则是各个主节点的从节点。否则集群无法正常运行!!
####################### 以下操作步骤是全部机器的操作 ##########################################
一、下载安装安装包
1:下载redis源码包
wget http://www.redis.cn/download.html/redis-5.0.3.tar.gz
(下载完查看大小1.86M,如果只有几十K,请直接上网页手动下载)
二、安装redis修改允许后台运行,并开机自启
#!/bin/bash
yum install gcc-c++ -y
#安装ruby环境
yum -y install ruby ruby-devel rubygems rpm-build curl
tar -zxf redis-5.0.3.tar.gz
cd redis-5.0.3
cp src/redis-trib.rb /usr/local/redis/bin/ #复制cluster集群启动命令
make MALLOC=libc
make
cd src
make install PREFIX=/usr/local/redis
cd ..
cp redis.conf /usr/local/redis/bin/
cd ..
rm -rf redis-5.0.3/
cd /usr/local/redis/bin
##让redis可以后台启动
AA=`cat -n redis.conf | grep daemonize | grep -v "#" | awk '{print $1}'`
sed -i ''"$AA"'c daemonize yes' redis.conf
##开启cluster集群
BB=`cat -n redis.conf | grep cluster-enabled | awk '{print $1}'`
sed -i ''"$BB"'s/#/ /g' redis.conf
##设置请求超时时间(默认15秒,可自行设置)
CC=`cat -n redis.conf | grep cluster-node-timeout | awk '{print $1}'`
sed -i ''"$CC"'s/#/ /g' redis.conf
##aof日志开启 有需要就开启,它会每次写操作都记录一条日志
DD=`cat -n redis.conf | grep appendonly | grep -v "name" | awk '{print $1}'`
sed -i ''"$DD"'s/no/yes/g' redis.conf
#安装ruby (redis5.0之前的版本需要安装tuby)
#先导入公钥:
gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
curl -L get.rvm.io | bash -s stable;source /usr/local/rvm/scripts/rvm
rvm install 2.3.3;rvm use 2.3.3;rvm remove 2.0.0;ruby --version
gem install redis
以上安装ruby步骤,遇到如下报错:(redis5.0之前的版本需要安装tuby)
直接执行gem install redis命令执行时出现了:
[root@beiyong conf]# gem install redis
Fetching: redis-4.1.0.gem (100%)
ERROR: Error installing redis:
redis requires Ruby version >= 2.2.2.
说明:
redis requires Ruby version >= 2.2.2的报错,Centos默认支持ruby到2.0.0,可gem 安装redis需要最低是2.2.2
解决办法是 先安装rvm,再把ruby版本提升至2.3.3
三、单机多实例安装
1:创建多实列目录和启动脚本:
[root@localhost /]# mkdir /usr/local/redis/cluster #创建cluster集群目录
[root@localhost /]# mkdir /usr/local/redis/cluster/{conf,pid,log,data,}
[root@localhost /]# mkdir /usr/local/redis/cluster/data/{6380,6381,6382,6383,6384,6385}
[root@localhost /]# cd /usr/local/redis/bin/
[root@localhost /]# cp redis-server redis-server6380;cp redis-server redis-server6381;cp redis-server redis-server6382
[root@localhost /]# cp redis-server redis-server6383;cp redis-server redis-server6384;cp redis-server redis-server6385
[root@localhost /]# mv redis.conf /usr/local/redis/cluster/conf/
[root@localhost /]# cd /usr/local/redis/cluster/conf/
[root@localhost /]# cp redis.conf redis6380.conf;cp redis.conf redis6381.conf
[root@localhost /]# cp redis.conf redis6382.conf;cp redis.conf redis6383.conf
[root@localhost /]# cp redis.conf redis6384.conf;cp redis.conf redis6385.conf
2:分别修改配置文件:(其他端口配置文件以此类推的去修改)
vim /usr/local/redis/cluster/conf/redis6380.conf
92 port 6380 <== 端口
#pidfile " "(更改为:)
158 pidfile /usr/local/redis/cluster/pid/redis_6380.pid <== 进程id存放文件
171 logfile /usr/local/redis/cluster/log/redis_6380.log <== 日志目录
#dir ./(更改为):
263 dir /usr/local/redis/cluster/data/6380/ <== db目录
846 cluster-config-file /usr/local/redis/cluster/conf/nodes_6380.conf <== 集群的配置,配置文件首次启动自动生成6380
四、启动和关闭脚本(请先查看是否有killall命令)
cat /usr/bin/redis6380
#!/bin/bash
cd /usr/local/redis/bin
case $1 in
start)
./redis-server6380 /usr/local/redis/cluster/conf/redis6380.conf;ps -ef | grep redis | grep 6380 > /dev/null && echo "redis6380 Successful opening" || echo "redis6380 Open failure"
;;
stop)
killall ./redis-server6380 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6380 && echo "redis6380 Shutdown failure" || echo "redis6380 Shut down successfully"
;;
restart)
killall ./redis-server6380 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6380 && echo "redis6380 Shutdown failure" || echo "redis6380 Shut down successfully"
./redis-server6380 /usr/local/redis/cluster/conf/redis6380.conf;ps -ef | grep redis | grep 6380 > /dev/null && echo "redis6380 Successful opening" || echo "redis6380 Open failure"
;;
*)
exit
exit
;;
esac
cat /usr/bin/redis6381
#!/bin/bash
cd /usr/local/redis/bin
case $1 in
start)
./redis-server6381 /usr/local/redis/cluster/conf/redis6381.conf;ps -ef | grep redis | grep 6381 > /dev/null && echo "redis6381 Successful opening" || echo "redis6381 Open failure"
;;
stop)
killall ./redis-server6381 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6381 && echo "redis6381 Shutdown failure" || echo "redis6381 Shut down successfully"
;;
restart)
killall ./redis-server6381 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6381 && echo "redis6381 Shutdown failure" || echo "redis6381 Shut down successfully"
./redis-server6381 /usr/local/redis/cluster/conf/redis6381.conf;ps -ef | grep redis | grep 6381 > /dev/null && echo "redis6381 Successful opening" || echo "redis6381 Open failure"
;;
*)
exit
exit
;;
esac
cat /usr/bin/redis6382
#!/bin/bash
cd /usr/local/redis/bin
case $1 in
start)
./redis-server6382 /usr/local/redis/cluster/conf/redis6382.conf;ps -ef | grep redis | grep 6382 > /dev/null && echo "redis6382 Successful opening" || echo "redis6382 Open failure"
;;
stop)
killall ./redis-server6382 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6382 && echo "redis6382 Shutdown failure" || echo "redis6382 Shut down successfully"
;;
restart)
killall ./redis-server6382 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6382 && echo "redis6382 Shutdown failure" || echo "redis6382 Shut down successfully"
./redis-server6382 /usr/local/redis/cluster/conf/redis6382.conf;ps -ef | grep redis | grep 6382 > /dev/null && echo "redis6382 Successful opening" || echo "redis6382 Open failure"
;;
*)
exit
exit
;;
esac
cat /usr/bin/redis6383
#!/bin/bash
cd /usr/local/redis/bin
case $1 in
start)
./redis-server6383 /usr/local/redis/cluster/conf/redis6383.conf;ps -ef | grep redis | grep 6383 > /dev/null && echo "redis6383 Successful opening" || echo "redis6383 Open failure"
;;
stop)
killall ./redis-server6383 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6383 && echo "redis6383 Shutdown failure" || echo "redis6383 Shut down successfully"
;;
restart)
killall ./redis-server6383 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6383 && echo "redis6383 Shutdown failure" || echo "redis6383 Shut down successfully"
./redis-server6383 /usr/local/redis/cluster/conf/redis6383.conf;ps -ef | grep redis | grep 6383 > /dev/null && echo "redis6383 Successful opening" || echo "redis6383 Open failure"
;;
*)
exit
exit
;;
esac
cat /usr/bin/redis6384
#!/bin/bash
cd /usr/local/redis/bin
case $1 in
start)
./redis-server6384 /usr/local/redis/cluster/conf/redis6384.conf;ps -ef | grep redis | grep 6384 > /dev/null && echo "redis6384 Successful opening" || echo "redis6384 Open failure"
;;
stop)
killall ./redis-server6384 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6384 && echo "redis6384 Shutdown failure" || echo "redis6384 Shut down successfully"
;;
restart)
killall ./redis-server6384 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6384 && echo "redis6384 Shutdown failure" || echo "redis6384 Shut down successfully"
./redis-server6384 /usr/local/redis/cluster/conf/redis6384.conf;ps -ef | grep redis | grep 6384 > /dev/null && echo "redis6384 Successful opening" || echo "redis6384 Open failure"
;;
*)
exit
exit
;;
esac
cat /usr/bin/redis6385
#!/bin/bash
cd /usr/local/redis/bin
case $1 in
start)
./redis-server6385 /usr/local/redis/cluster/conf/redis6385.conf;ps -ef | grep redis | grep 6385 > /dev/null && echo "redis6385 Successful opening" || echo "redis6385 Open failure"
;;
stop)
killall ./redis-server6385 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6385 && echo "redis6385 Shutdown failure" || echo "redis6385 Shut down successfully"
;;
restart)
killall ./redis-server6385 2> /dev/null;sleep 1;ps -ef | grep -v grep | grep redis-server6385 && echo "redis6385 Shutdown failure" || echo "redis6385 Shut down successfully"
./redis-server6385 /usr/local/redis/cluster/conf/redis6385.conf;ps -ef | grep redis | grep 6385 > /dev/null && echo "redis6385 Successful opening" || echo "redis6385 Open failure"
;;
*)
exit
exit
;;
esac
#加上可执行权限:
chmod +x /usr/bin/redis*
五、启动和关闭脚本使用说明:
1:全部启动:(start/stop/restart)
[root@beiyong conf]# redis6380 start
redis6380 Successful opening
[root@beiyong conf]# redis6381 start
redis6381 Successful opening
[root@beiyong conf]# redis6382 start
redis6382 Successful opening
[root@beiyong conf]# redis6383 start
redis6383 Successful opening
[root@beiyong conf]# redis6384 start
redis6384 Successful opening
[root@beiyong conf]# redis6385 start
redis6385 Successful opening
[root@beiyong conf]# ps -ef | grep -v grep | grep redis
root 19306 1 0 04:04 ? 00:00:00 ./redis-server6380 127.0.0.1:6380 [cluster]
root 19315 1 0 04:04 ? 00:00:00 ./redis-server6381 127.0.0.1:6381 [cluster]
root 19324 1 0 04:05 ? 00:00:00 ./redis-server6382 127.0.0.1:6382 [cluster]
root 19333 1 0 04:05 ? 00:00:00 ./redis-server6383 127.0.0.1:6383 [cluster]
root 19342 1 0 04:05 ? 00:00:00 ./redis-server6384 127.0.0.1:6384 [cluster]
root 19351 1 0 04:05 ? 00:00:00 ./redis-server6385 127.0.0.1:6385 [cluster]
六、创建cluster集群:
在某个节点上执行以下创建集群命令:
[root@beiyong conf]# cd /usr/local/redis/bin
[root@beiyong bin]# ./redis-cli --cluster create 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:6383 to 127.0.0.1:6380
Adding replica 127.0.0.1:6384 to 127.0.0.1:6381
Adding replica 127.0.0.1:6385 to 127.0.0.1:6382
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: be2aef4f63e341d74c6ac7121a3752b9d5e4d56c 127.0.0.1:6380
slots:[0-5460] (5461 slots) master
M: fad8c83452c6c0ef43028b0d15caef0db00940e7 127.0.0.1:6381
slots:[5461-10922] (5462 slots) master
M: 1d884ebe5ded17a086d93d198c14d2869d6f81f8 127.0.0.1:6382
slots:[10923-16383] (5461 slots) master
S: 5f82f16d6978dc4390e68de1a59b9fb02f2cee16 127.0.0.1:6383
replicates 1d884ebe5ded17a086d93d198c14d2869d6f81f8
S: 1d28fd50d773542de4ae93a1fb6c3ad220a1217c 127.0.0.1:6384
replicates be2aef4f63e341d74c6ac7121a3752b9d5e4d56c
S: 1e339c5ffaa70e5fe8e89d1b3d2a153121c853f7 127.0.0.1:6385
replicates fad8c83452c6c0ef43028b0d15caef0db00940e7
Can I set the above configuration? (type 'yes' to accept): yes ----这里需要输入 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:6380)
M: be2aef4f63e341d74c6ac7121a3752b9d5e4d56c 127.0.0.1:6380
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 5f82f16d6978dc4390e68de1a59b9fb02f2cee16 127.0.0.1:6383
slots: (0 slots) slave
replicates 1d884ebe5ded17a086d93d198c14d2869d6f81f8
S: 1e339c5ffaa70e5fe8e89d1b3d2a153121c853f7 127.0.0.1:6385
slots: (0 slots) slave
replicates fad8c83452c6c0ef43028b0d15caef0db00940e7
M: fad8c83452c6c0ef43028b0d15caef0db00940e7 127.0.0.1:6381
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 1d884ebe5ded17a086d93d198c14d2869d6f81f8 127.0.0.1:6382
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 1d28fd50d773542de4ae93a1fb6c3ad220a1217c 127.0.0.1:6384
slots: (0 slots) slave
replicates be2aef4f63e341d74c6ac7121a3752b9d5e4d56c
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
以上操作如果遇到以下错误;
[ERR] Node 10.90.6.157:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
解决:
1)将每个节点下aof、rdb、nodes.conf本地备份文件删除;
[[email protected]]# rm -rf appendonly.aof dump.rdb nodes-*
[[email protected]]# pwd
/fs01/redis-5.0.0
2)127.0.0.1:6380> flushdb #清空当前数据库
3)之后再执行脚本,成功执行;
这里解释一下dump.rdb文件:
dump.rdb是由Redis服务器自动生成的 默认情况下 每隔一段时间redis服务器程序会自动对数据库做一次遍历,把内存快照写在一个叫做“dump.rdb”的文件里,这个持久化机制叫做SNAPSHOT。有了SNAPSHOT后,如果服务器宕机,重新启动redis服务器程序时redis会自动加载dump.rdb,将数据库状态恢复到上一次做SNAPSHOT时的状态。
SNAPSHOT即快照
重新连接redis集群,ok
七、集群验证:
说明:-h+节点ip –p+节点都口号 –c 是要连接集群(注意,不加会报错的)
[root@beiyong bin]# ./redis-cli -c -h 127.0.0.1 -p 6381 --连接的是6381
127.0.0.1:6381> get hello
-> Redirected to slot [866] located at 127.0.0.1:6380 --但是建立的值保存在6380节点上(集群会自动计算hasg槽,将建立的值保存在某个节点上)
(nil)
127.0.0.1:6380>
127.0.0.1:6380> set name zzh
-> Redirected to slot [5798] located at 127.0.0.1:6381 --但是建立的值保存在6381节点上(集群会自动计算hasg槽,将建立的值保存在某个节点上)
OK
127.0.0.1:6381> get name
"zzh"
127.0.0.1:6381> set age 26
-> Redirected to slot [741] located at 127.0.0.1:6380 --但是建立的值保存在6380节点上(集群会自动计算hasg槽,将建立的值保存在某个节点上)
OK
127.0.0.1:6380> get age
"26"
127.0.0.1:6380>
八、#开机自启:
echo "/usr/local/redis/bin/redis-server6380 /usr/local/redis/cluster/conf/redis6380.conf" >> /etc/rc.local
……
……
注意事项,多实列下还需要保持不一致的修改处(按自己的需求修改,配置文件默认是注释掉的):
dbfilename dump.rdb #多实例情况下需要修改,例如dump.6380.rdb
appendfilename "appendonly.aof" #多实例情况下需要修改,例如 appendonly_6380.aof