Redis分片集群搭建
1.集群结构
分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个master包含一个slave节点,结构如下:
信息如下:
IP | PORT | 角色 |
---|---|---|
glnode03 | 6379 | slave |
glnode05 | 6379 | slave |
glnode07 | 6379 | master |
glnode08 | 6379 | master |
glnode09 | 6379 | master |
glnode11 | 6379 | slave |
2.准备实例和配置
在 redis 的安装目录下的 etc 目录下准备一个新的 redis.conf 文件,内容如下:
port 6379
# 以下的集群配置在redis官方提供的配置模板文件中并没有,需要自己添加
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /export/servers/redis/etc/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 开启aof,也可以不开启
appendonly yes
# 开启RDB
save 3600 1 300 100 60 10000
# 持久化文件存放目录
dir ../data/
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 192.168.150.101
# 保护模式
protected-mode no
# 数据库数量
databases 16
# 日志
logfile logfile "/export/servers/redis/logs/redis.log"
将这个文件拷贝到每台服务器中:
切记:在这步骤之前 删除所有的 RDB AOF 文件
[root@glnode07 AutoShell]# ./1toN.sh 01,03-06,08,09,11 /export/servers/redis /export/servers/
这个脚本文件会在附录中给出,当然也可以通过 Xfps 等工具直接拖拽
3.启动
因为已经配置了后台启动模式,所以可以直接启动服务,进入到redis安装文件的bin目录下:
redis-server ../etc/redis.conf
通过ps查看状态:
ps -ef | grep redis
发现服务都已经正常启动:
如果要关闭进程,可以执行命令:
redis-cli shutdown
4.创建集群
虽然服务启动了,但是目前每个服务之间都是独立的,没有任何关联。
我们需要执行命令来创建集群,在Redis5.0之前创建集群比较麻烦,5.0之后集群管理命令都集成到了redis-cli中。
1)Redis5.0之前
Redis5.0之前集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。
# 安装依赖
yum -y install zlib ruby rubygems
gem install redis
然后通过命令来管理集群:
# 进入redis的src目录
cd /tmp/redis-7.2.4/src
# 创建集群
./redis-trib.rb create --replicas 1 glnode03:6379 glnode05:6379 glnode07:6379 glnode08:6379 glnode9:6379 glnode11:6379
2)Redis5.0以后
我们使用的是Redis7.2.4版本,集群管理以及集成到了redis-cli中,格式如下:
redis-cli --cluster create --cluster-replicas 1 glnode07:6379 glnode08:6379 glnode09:6379 glnode03:6379 glnode05:6379 glnode11:6379
redis-cli --cluster create --cluster-replicas 1 192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 192.168.150.101:8001 192.168.150.101:8002 192.168.150.101:8003
命令说明:
redis-cli --cluster
或者./redis-trib.rb
:代表集群操作命令create
:代表是创建集群--replicas 1
或者--cluster-replicas 1
:指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1)
得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master
运行后的样子:
这里输入yes,则集群开始创建:
通过命令可以查看集群状态:
redis-cli -p 7001 cluster nodes
5.测试
尝试连接7001节点,存储一个数据:
# 连接
redis-cli -c
# 存储数据
set num 123
# 读取数据
get num
# 再次存储
set a 1
集群操作时,需要给redis-cli
加上-c
参数才可以:
redis-cli -c
可以看到会在存储 hash 不在一个节点的数据时,自动切换master节点
报错:
在创建集群时报错[ERR] Node glnode07:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
主要原因是 RDB 或者 AOF 文件中有数据,redis集群搭建的时候需要所有节点都为 空,不可以右节点有数据,我这个节点原本是一个单机 redis 并且存在数据,所以我需要删除之前的 RDB 和 AOF 文件。
还可能由于上次redis集群没有配置成功,生成了每个节点的配置文件,才产生这个错误,要将每个节点中的 nodes.conf文件删除.
先停止 redis 服务
redis-cli shutdown
按照我的配置 AOF 和 RDB 文件是在redis安装目录下的 redis/data/appendonlydir 这个文件夹中。删除即可
[root@glnode07 appendonlydir]# rm -rf *
删除 dump.rdb 文件,按照我的配置是在 redis 安装目录下的 redis/data 这个文件夹
[root@glnode07 data]# rm -rf dump.rdb
然后 删除 nodes.conf 文件
[root@glnode07 etc]# rm -rf nodes.conf
参考
redisNode is not empty
附件
#!/bin/bash
if [ $# -ne 3 ]
then
printf "Usage: \n"
printf " 1toN.sh \"01,04-05,08-12\" SrcFile TargetDir \n"
printf "该命令会将本机的SrcFile文件(夹)传输至01,04,05,08,09,10,11, \n"
printf "12主机的TargetDir路径下 \n"
printf " \n"
printf "PS: \n"
printf " + 目标主机编号应使用双引号,源文件(夹)和目标路径不需要 \n"
exit
fi
array=(${1//,/ })
for arra in ${array[@]}
do
if (( ${#arra} == 2 ))
then
# do somethings
echo "#################### glnode${arra} ####################"
# scp -r ${2} root@glnode${arra}:${3}>/export/AutoShell/1toN.log
script /export/AutoShell/scp.log -q -c "scp -r ${2} root@glnode${arra}:${3}"
echo "#################### glnode${arra} ####################"
echo
else
arr=(${arra[@]})
start=`echo ${arra:0:2}|bc`
end=`echo ${arra:3:2}|bc`
while (($start <= $end))
do
ar=`printf "%02d" $start`
start=$(($start+1))
# do somethings
echo "#################### glnode${ar} ####################"
# scp -r ${2} root@glnode${ar}:${3}>/export/AutoShell/1toN.log
script /export/AutoShell/scp.log -q -c "scp -r ${2} root@glnode${ar}:${3}"
echo "#################### glnode${ar} ####################"
echo
done
fi
done