文章目录
Redis 集群
一、下载,编译,安装Ruby
官网 点我直达
wget https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.1.tar.gz
安装依赖包
yum -y install zlib-devel readline openssl-devel gcc gcc-c++
更多具体安装方法 点我直达
./configure
make
sudo make install
二、安装 rubygem redis
一个 ruby 语言实现的访问 Redis 集群的客户端
官网 点我直达
cd ..
wget https://rubygems.org/rubygems/rubygems-3.0.2.tgz
tar -xf rubygems-3.0.2.tgz
cd rubygems-3.0.2/
ruby setup.rb
gem install redis
三、安装 redis-trib.rb
redis-trib
位于 Redis 源码的 src
文件夹中, 它是一个 Ruby 程序, 这个程序通过向实例发送特殊命令来完成创建新集群, 检查集群, 或者对集群进行重新分片(reshared
)等工作。
1.配置集群
假如你完全安装这个文档做的实验的换,此时配置集群之前,需要把之前的集群进程都停掉。
先在从节点上执行,再到主节点上执行
ps -ef | grep redis-server | grep -v 'grep' | awk '{print $2}' |xargs kill
接着分别在两台主机上,把之前集群产生的数据清除
[root@n1 ~]# rm -rf /redis/data/*
[root@n2 ~]# rm -rf /redis/data/*
2.编辑一个集群的配置文件
编译配置文件 /etc/redis/cluster-redis-7001.conf
, 添加如下内容:
bind 0.0.0.0
port 7001
daemonize yes
# 允许任何地址不使用密码访问我
protected-mode no
dir "/redis/data/"
logfile "cluster-7001.log"
dbfilename "cluster-dump-7001.log"
cluster-enabled yes
cluster-config-file cluster-redis-7001.conf
# 不需要集群的全部节点完好才提供服务
cluster-require-full-coverage no
3.再创建其他集群的配置文件
cd /etc/redis/
sed 's/7001/7002/g' cluster-redis-7001.conf > cluster-redis-7002.conf
sed 's/7001/7003/g' cluster-redis-7001.conf > cluster-redis-7003.conf
sed 's/7001/7011/g' cluster-redis-7001.conf > cluster-redis-7011.conf
sed 's/7001/7012/g' cluster-redis-7001.conf > cluster-redis-7012.conf
sed 's/7001/7013/g' cluster-redis-7001.conf > cluster-redis-7013.conf
4.检查配置是否正确
[root@n1 ~]# grep -E '70[0-9]+' /etc/redis/cluster-redis*
/etc/redis/cluster-redis-7001.conf:port 7001
/etc/redis/cluster-redis-7001.conf:logfile "cluster-7001.log"
/etc/redis/cluster-redis-7001.conf:dbfilename "cluster-dump-7001.log"
/etc/redis/cluster-redis-7001.conf:cluster-config-file cluster-redis-7001.conf
/etc/redis/cluster-redis-7002.conf:port 7002
/etc/redis/cluster-redis-7002.conf:logfile "cluster-7002.log"
/etc/redis/cluster-redis-7002.conf:dbfilename "cluster-dump-7002.log"
/etc/redis/cluster-redis-7002.conf:cluster-config-file cluster-redis-7002.conf
/etc/redis/cluster-redis-7003.conf:port 7003
/etc/redis/cluster-redis-7003.conf:logfile "cluster-7003.log"
/etc/redis/cluster-redis-7003.conf:dbfilename "cluster-dump-7003.log"
/etc/redis/cluster-redis-7003.conf:cluster-config-file cluster-redis-7003.conf
/etc/redis/cluster-redis-7011.conf:port 7011
/etc/redis/cluster-redis-7011.conf:logfile "cluster-7011.log"
/etc/redis/cluster-redis-7011.conf:dbfilename "cluster-dump-7011.log"
/etc/redis/cluster-redis-7011.conf:cluster-config-file cluster-redis-7011.conf
/etc/redis/cluster-redis-7012.conf:port 7012
/etc/redis/cluster-redis-7012.conf:logfile "cluster-7012.log"
/etc/redis/cluster-redis-7012.conf:dbfilename "cluster-dump-7012.log"
/etc/redis/cluster-redis-7012.conf:cluster-config-file cluster-redis-7012.conf
/etc/redis/cluster-redis-7013.conf:port 7013
/etc/redis/cluster-redis-7013.conf:logfile "cluster-7013.log"
/etc/redis/cluster-redis-7013.conf:dbfilename "cluster-dump-7013.log"
/etc/redis/cluster-redis-7013.conf:cluster-config-file cluster-redis-7013.conf
传输到另一台主机
scp cluster-redis* 10.9.29.169:/etc/redis/
5.重新启动这些节点的服务进程
先在主节点上执行
[root@n1 ~]# redis-server /etc/redis/cluster-redis-7001.conf
[root@n1 ~]# redis-server /etc/redis/cluster-redis-7002.conf
[root@n1 ~]# redis-server /etc/redis/cluster-redis-7003.conf
[root@n1 ~]# ps -ef | grep redis-server
root 116263 1 0 21:29 ? 00:00:00 redis-server 0.0.0.0:7001 [cluster]
root 116416 1 0 21:29 ? 00:00:00 redis-server 0.0.0.0:7002 [cluster]
root 116483 1 0 21:29 ? 00:00:00 redis-server 0.0.0.0:7003 [cluster]
root 119290 55072 0 21:32 pts/0 00:00:00 grep --color=auto redis-server
从节点
[root@n2 ~]# mkdir -p /redis/data/
[root@n2 ~]# redis-server /etc/redis/cluster-redis-7011.conf
[root@n2 ~]# redis-server /etc/redis/cluster-redis-7012.conf
[root@n2 ~]# redis-server /etc/redis/cluster-redis-7013.conf
[root@n2 ~]# ps -ef | grep redis-server
root 74978 1 0 21:31 ? 00:00:00 redis-server 0.0.0.0:7011 [cluster]
root 75087 1 0 21:31 ? 00:00:00 redis-server 0.0.0.0:7012 [cluster]
root 75174 1 0 21:31 ? 00:00:00 redis-server 0.0.0.0:7013 [cluster]
root 76105 24252 0 21:31 pts/0 00:00:00 grep --color=auto redis-server
查看集群信息
[root@n1 ~]# redis-cli -p 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_ping_sent:2296
cluster_stats_messages_pong_sent:2213
cluster_stats_messages_sent:4509
cluster_stats_messages_ping_received:2208
cluster_stats_messages_pong_received:2296
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:4509
查看节点信息
[root@n1 ~]# redis-cli -p 7001 cluster nodes
6b3c120d2fd3360b69b5a4a86d4545ca36ca9f04 10.9.29.169:7012@17012 slave 5ac8af60ad6d757a6ea7a795ed0b86b2597f11dd 0 1609730159553 5 connected
ab7ddf7e999585987b48971ee11268cbddddea2f 10.9.29.168:7003@17003 slave 577b46dde1050d2a5c82f25d34335a17e358d3b9 0 1609730159000 4 connected
577b46dde1050d2a5c82f25d34335a17e358d3b9 10.9.29.169:7011@17011 master - 0 1609730161566 4 connected 5461-10922
27701f54573c4551d2a9e40c9bcf6c86deca3bb3 10.9.29.168:7001@17001 myself,master - 0 1609730160000 1 connected 0-5460
5ac8af60ad6d757a6ea7a795ed0b86b2597f11dd 10.9.29.168:7002@17002 master - 0 1609730159000 2 connected 10923-16383
c1fb776e97bbaa6b674e2e0c222e519b5f7fe20f 10.9.29.169:7013@17013 slave 27701f54573c4551d2a9e40c9bcf6c86deca3bb3 0 1609730160558 6 connected
创建集群
注:示例版本必须一致, 否则无法加入集群
redis-trib.rb create --replicas 1 主节点1的IP:端口 主节点2的IP:端口 主节点3的IP:端口 从节点1的IP:端口 从节点2的IP:端口 从节点3的IP:端口
选项–replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。
redis-trib.rb create --replicas 1 10.9.29.168:7001 10.9.29.168:7002 10.9.29.168:7003 10.9.29.169:7011 10.9.29.169:7012 10.9.29.169:7013
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
10.9.29.168:7001
10.9.29.169:7011
10.9.29.168:7002
...
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
...
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
验证集群是否搭建成功
[root@n1 ~]# redis-cli -h 10.9.29.168 -p 7001 -c set name Neko
OK
[root@n1 ~]# redis-cli -h 10.9.29.168 -p 7002 -c get name
"Neko"
[root@n1 ~]# redis-cli -h 10.9.29.169 -p 7011 -c get name
"Neko"
集群节点之间的 meet
我们下面使用主节点 172.16.153.178:7001 去依次的 meet 其他 5 个节点。
[root@n1 ~]# redis-cli -p 7001 cluster meet 10.9.29.168 7002
OK
[root@n1 ~]# redis-cli -p 7001 cluster meet 10.9.29.168 7003
OK
[root@n1 ~]# redis-cli -p 7001 cluster meet 10.9.29.168 7004
OK
[root@n1 ~]# redis-cli -p 7001 cluster meet 10.9.29.168 7011
OK
[root@n1 ~]# redis-cli -p 7001 cluster meet 10.9.29.168 7012
OK
[root@n1 ~]# redis-cli -p 7001 cluster meet 10.9.29.168 7013
OK
给集群节点分配 数据槽
集群的槽号是 从 0 开始,到 16383 结束,共 16384 个。
槽的分配是拿 16384 除以集群中主节点的个数,得到每个主节点应该被分配给槽的数量。
所以现在的计划是:
0~5431 -> 7001 5462~10922 -> 7002 10923`16383 -> 7003
redis-cli -h 被添加的主机 IP -p 端口 cluster addslots 槽号
假如给 7001 分配 0 号槽。命令应该是:
redis-cli -h 10.9.29.1688 -p 7001 cluster addslots 0
每次只能分配一个 槽号,所以我们可以写个脚本,当然这种方式是不会在生产环境中使用的,这里只是为了理解集群的架构关系。
#!/bin/sh
target_host_ip=$1
target_host_port=$2
star=$3
end=$4
for slot in $(seq ${
star} ${
end})
do
echo "正在给 ${target_host_ip} ${target_host_port} 添加${slot}"
redis-cli -h ${target_host_ip} -p ${target_host_port} cluster addslots ${slot}
done
使用脚本
sh mutil-addslots.sh 10.9.29.168 7002 5462 10922
sh mutil-addslots.sh 10.9.29.168 7003 10923 16383
多线程版脚本
target_host_ip=$1
target_host_port=$2
star=$3
end=$4
num=$5
mkfifo t # 创建命名管道文件
exec 7<>t # 给命名管道起个文件描述符
rm -rf t # 删除这个命名管道文件,但是管道依然存在,可以使用文件描述符 7 进行使用。
for i in $(seq 1 ${
num}) # 向这个管道中输入相应数据的空行
do
echo >&7 # 每一行就是一次并发
done
for slot in $(seq ${
star} ${
end})
do
read -u7 # 这个不能变
{
echo " 主机 ${target_host_ip} 端口 ${target_host_port} 数据槽 ${slot}"
redis-cli -h ${target_host_ip} -p ${target_host_port} \
cluster addslots ${slot}
echo >&7
}&
done
wait # 这个不能变, 就是等待上面的所有后台进程结束
exec 7>&- # 这个不能变,
echo "任务执行完毕"
给集群节点配置主从关系
命令语法
redis-cli -p 从节点端口 cluster replicate 主节点的 ID
四、深入集群
集群的伸缩
添加节点(扩容)
1.准备节点
启动两个新的 redis 实例, 分别监听不同端口 比如 7004 和 7014
我这里是分别在两台主机上启动 redis 实例
主节点
cd /etc/redis/
cp cluster-redis-7001.conf cluster-redis-7004.conf
sed -i 's/7001/7004/g' cluster-redis-7004.conf
redis-server cluster-redis-7004.conf
从节点
cp cluster-redis-7011.conf cluster-redis-7014.conf
sed -i 's/7011/7014/g' cluster-redis-7014.conf
redis-server cluster-redis-7014.conf
2.加入集群中
添加一个新的节点为主节点
redis-trib.rb add-node new_host:new_port existing_host:existing_port
# new_host:new_port 为新添加的节点信息
# existing_host:existing_port 集群中任意节点的信息
redis-trib.rb add-node 10.9.29.168:7004 10.9.29.168:7001
添加一个新节点为从节点
redis-trib.rb add-node --slave --master-id 主节点的 ID new_host:new_port existing_host:existing_port
redis-trib.rb add-node --slave --master-id 10.9.29.168 10.9.29.169:7014 10.9.29.169:7011
3.减少节点(缩容)
./redis-trib.rb reshard --from 下线节点 ID --to 集群中的任意主节点 ID --slots 迁移到槽数 目前集群中任意节点 IP:端口
redis-trib.rb reshard --from 3db5ac0fd45c0aa6801036aa1e2daf6835463445 --to 27701f54573c4551d2a9e40c9bcf6c86deca3bb3 --slots 100 10.9.29.168:7001
注意:
需要把下线节点的槽数平均迁移到剩余的所有节点,所以需要分批分次执行上面的命令。
并且,每次都集群中的主节点应该不同。
注意:
需要把下线节点的槽数平均迁移到剩余的所有节点,所以需要分批分次执行上面的命令。
并且,每次都集群中的主节点应该不同。
删除节点
当我们使用 redis-trib.rb 工具时,只需要在目前集群中的任意一个节点中执行如下命令即可
注意:
你应该始终先删除从节点,再删除主节点
忘记节点
redis-trib.rb del-node 127.0.0.1:7001 99c7179fa050512c85559cb1d58e3088153c632f
4.报错解决
[WARNING] Node 127.0.0.1:6380 has slots in migrating state (5798). [WARNING] Node 127.0.0.1:6382 has slots in importing state (5798). [WARNING] The following slots are open: 5798
解决
redis-cli -h 10.9.29.168 -p 7014 cluster setslot 5798 stable