目录
- redis cluster三主三从搭建
- 原生部署cluster集群
- 安装C/C++环境
- redis下载
- 解压、编译
- 创建Redis相关工作目录(目录可自定义)
- 复制redis配置文件
- 修改Redis配置文件
- 启动Redis
- 创建Redis Cluster
- 验证集群Redis-Cluster
- 故障恢复
- 读取key的小细节
- docker部署cluster集群
- 提前编辑好配置文件
- 创建文件夹
- 一台机器
- 三台机器
- 在机器上分别启动redis
- 一台机器
- 三台机器
- 进入任一redis容器启动redis集群
- 一台机器
- 三台机器
redis cluster三主三从搭建
分了原生部署和docker部署
原生部署cluster集群
需要用到三台机器,每台机器上启动8001和8002端口,也可以根据自己需求改成别的端口,在下面配置文件中会体现
截止7.1步骤,1.1-7.1的步骤在三台机器上都要操作,7.1及7.1之后的内容是在一台机器执行
安装C/C++环境
Redis编译时需要使用C/C++环境:
yum install -y gcc gcc-c++ make
redis下载
wget https://download.redis.io/releases/redis-5.0.13.tar.gz
解压、编译
//依赖库安装
yum install gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel -y
tar -zxvf redis-5.0.13.tar.gz
cd redis-5.0.13
make
创建Redis相关工作目录(目录可自定义)
mkdir /data/redis/redis-cluster/{data/{redis_8001,redis_8002},conf,log} -p
复制redis配置文件
cp /data/redis/redis-5.0.13/redis.conf /data/redis/redis-cluster/conf/redis_8001.conf
cp /data/redis/redis-5.0.13/redis.conf /data/redis/redis-cluster/conf/redis_8002.conf
修改Redis配置文件
port 8001
#修改redis监听端口(可以自定义) 8001与端口号同步
bind 0.0.0.0
#表示redis允许所有地址连接。默认127.0.0.1,仅允许本地连接。
daemonize yes
#允许redis后台运行
pidfile /var/run/redis_8001.pid
#pid存放目录 8001与端口号同步
logfile "/data/redis/redis-cluster/log/redis_8001.log"
#设置日志存放路径 8001与端口号同步
dir /data/redis/redis-cluster/data/redis_8001
#工作目录 8001与端口号同步
cluster-enabled yes
#是否开启集群
cluster-config-file /data/redis/redis-cluster/conf/nodes_8001.conf
#集群配置文件的名称,每个节点都有一个集群相关的配置文件,持久化保存集群的信息 8001与端口号同步
#这个文件并不需要手动配置,这个配置文件有Redis生成并更新,
cluster-node-timeout 15000
#节点互连超时的阀值。集群节点超时毫秒数,默认15秒
appendonly yes
#Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,
#每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。
appendfsync everysec
#Redis会把每次写入的数据在接收后每秒写入一次 appendonly.aof 文件
requirepass 123456
#设置redis密码
masterauth 123456
#主从同步master的密码(如果没有设置redis密码,则无需配置)
启动Redis
集群内每台服务器分别启动两个redis
cd /data/redis/redis-5.0.13/src/
./redis-server /data/redis/redis-cluster/conf/redis_8001.conf
./redis-server /data/redis/redis-cluster/conf/redis_8002.conf
创建Redis Cluster
./redis-cli -a {redis密码} --cluster create {redis集群地址} --cluster-replicas 1
例子: ./redis-cli -a 123456 --cluster create 192.168.48.91:8001 192.168.48.91:8002 192.168.48.92:8001 192.168.48.92:8002 192.168.48.93:8001 192.168.48.93:8002--cluster-replicas 1
验证集群Redis-Cluster
//登录redis集群
./redis-cli -a {redis密码} -h {redis地址} -p {redsi端口} -c
//验证集群信息
{redis地址}:{redis端口}>cluster info #查看集群信息
{redis地址}:{redis端口}>cluster nodes #查看集群节点列表
//查看集群内主从关系
{redis地址}:{redis端口}>cluster slots
//数据验证
插入数据:
{redis地址}:{redis端口}> set name
{redis地址}:{redis端口}> get name
登录其他节点查看数据:
redis-cli -a {redis密码} -h {redis地址} -p {redsi端口} -c
{redis地址}:{redis端口}> get mykey
故障恢复
假设你现在有一个3主3从的redis cluster,很不幸运,你丢了2个节点
redis cluster集群状态为fail,丢失了一些分片
集群坏了原因分析:
* master节点能启动,但是master节点的IP变化了,集群还是根据旧的IP去连接节点,导致集群不能自愈。
* master节点某种原因不能启动,slave节点坏掉,有部分槽位slot丢失
* master节点因为网络原因不能连接,部分分片丢失,有部分槽位slot丢失
修复步骤:
//需要把dump.rdb或者appendonly.aof文件拷贝出来,目的是先恢复redis节点数据, 如果数据能恢复,可能不需要fix修复命令,集群就可能恢复
//连接任意一个集群节点,cluster forget删除掉有故障的节点。这个时候建议你用call命令,这个命令很好用
redis-cli --cluster call 192.168.8.101:6381 cluster forget
redis-cli --cluster call 192.168.8.101:6381 cluster nodes
//meet命令添加节点
redis-cli --cluster call 192.168.8.101:6381 cluster meet 192.168.8.101 6384
//查询检查集群信息是否一致
redis-cli --cluster call 192.168.8.101:6381 cluster nodes
redis-cli --cluster check 192.168.8.101:6381
//如果这个时候足够幸运,cluster应该是恢复了。如果提示[ERR] Not all 16384 slots are covered by nodes.
//接下来需要fix修复命令,在这个步骤你也可以使用命令add-node节点增加集群节点
redis-cli --cluster add-node 192.168.8.102:6384 192.168.8.101:6381
//fix修复节点命令,fix修复命令,不仅可以自动删除disconnected的节点,而且会迁移没有分配的slots到正常节点,可以使集群状态fail转变为ok。我之所以手动先给集群增加一个节点,手动删除有故障节点,然后fix修复命令,fix是会迁移的slots,需要代价的,fix完成后,还需要再平衡rebalance集群。
redis-cli --cluster fix 192.168.8.101 6381
//再平衡rebalance集群
redis-cli --cluster rebalance --cluster-use-empty-masters --cluster-pipeline 1000 --cluster-simulate 192.168.8.101 6384
rebalance host:port # 指定集群的任意一节点进行平衡集群节点slot数量
--cluster-weight # 指定集群节点的权重
--cluster-use-empty-masters # 设置可以让没有分配slot的主节点参与,默认不允许
--cluster-timeout # 设置migrate命令的超时时间
--cluster-simulate # 模拟rebalance操作,不会真正执行迁移操作
--cluster-pipeline # 定义cluster getkeysinslot命令一次取出的key数量,默认值为10
--cluster-threshold # 迁移的slot阈值超过threshold,执行rebalance操作
--cluster-replace # 是否直接replace到目标节点
//最后不忘记保存配置
cluster saveconfig
读取key的小细节
我部署了三主,没有从的集群,即replica=0
集群正常时,存了一个age:32,卡槽在741
kill一个主8001端口,3-5秒内仍可以连接redis集群,可以看到访问741卡槽的时候被拒绝
3-5秒后,集群报错connected refused,无法再使用
重启8001端口,集群因为没有从节点,无法自愈,需要人为修复,修复方式请参考另一篇修复cluster集群故障的文档
docker部署cluster集群
准备三台机器,一台机器也可以
提前编辑好配置文件
cd /root/redis //这里目录可以自定义,只要后面docker run的时候改一下启动命令即可
vim redis.conf
# bind 127.0.0.1 #IP地址需要注释;
port ${PORT}
protected-mode no
cluster-enabled yes
cluster-config-file nodes-${PORT}.conf
cluster-node-timeout 5000
cluster-announce-ip 10.0.18.8
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
appendonly yes
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
//bind:IP地址需要注释;
//port:节点端口;
//requirepass:添加访问认证;
//masterauth:如果主节点开启了访问认证,从节点访问主节点需要认证;
//protected-mode:保护模式,默认值 yes,即开启。开启保护模式以后,需配置 bind ip 或者设置访问密码;关闭保护模式,外部网络可以直接访问;
//daemonize:是否以守护线程的方式启动(后台启动),默认 no
//appendonly:是否开启 AOF 持久化模式,默认 no;
//cluster-config-file:集群节点信息文件;
//cluster-node-timeout:集群节点连接超时时间;
//cluster-announce-ip:集群节点 IP,填写宿主机的 IP;是的,宿主机的ip,redis在哪个宿主机运行就改成那台宿主机的Ip
//cluster-announce-port:集群节点映射端口;
//cluster-announce-bus-port:集群节点总线端口。
每个 Redis 集群节点都需要打开两个 TCP 连接。
一个用于为客户端提供服务的正常 Redis TCP 端口,例如 6379。还有一个基于 6379 端口加 10000 的端口,比如 16379。
第二个端口用于集群总线,这是一个使用二进制协议的节点到节点通信通道。
节点使用集群总线进行故障检测、配置更新、故障转移授权等等。
客户端永远不要尝试与集群总线端口通信,与正常的 Redis 命令端口通信即可
但是请确保防火墙中的这两个端口都已经打开,否则 Redis 集群节点将无法通信
创建文件夹
一台机器
for port in `seq 9001 9006`; do \
mkdir -p ./redis-cluster/${port}/conf \
&& PORT=${port} envsubst < ./redis.conf > ./redis-cluster/${port}/conf/redis.conf \
&& mkdir -p ./redis-cluster/${port}/data; \
done
三台机器
for port in `seq 9001 9002`; do \
mkdir -p ./redis-cluster/${port}/conf \
&& PORT=${port} envsubst < ./redis.conf > ./redis-cluster/${port}/conf/redis.conf \
&& mkdir -p ./redis-cluster/${port}/data; \
done
在机器上分别启动redis
一台机器
for port in `seq 9001 9006`; do \
docker run -itd --name redis${port} \
-v /root/redis/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
-v /root/redis/redis-cluster/${port}/data:/data \
-p ${port}:${port} -p 1${port}:1${port} \
--env TZ=Asia/Shanghai --restart=always \
192.168.48.90:80/ecs-component/ecs-redis:6.0.9-nopersistence;done
三台机器
for port in `seq 9001 9002`; do \
docker run -itd --name redis${port} \
-v /root/redis/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
-v /root/redis/redis-cluster/${port}/data:/data \
-p ${port}:${port} -p 1${port}:1${port} \
--env TZ=Asia/Shanghai --restart=always \
192.168.48.90:80/ecs-component/ecs-redis:6.0.9-nopersistence;done
进入任一redis容器启动redis集群
一台机器
docker exec -it redis9001 redis-cli --cluster create 192.168.48.33:9001 192.168.48.33:9002 192.168.48.33:9003 192.168.48.33:9004 192.168.48.33:9005 192.168.48.33:9006 --cluster-replicas 1
三台机器
docker exec -it redis9001 redis-cli --cluster create 192.168.48.33:9001 192.168.48.33:9002 192.168.48.91:9001 192.168.48.91:9002 192.168.2.172:9001 192.168.2.172:9002 --cluster-replicas 1