Redis集群不停机升级
背景
现有的Redis
集群是由Redis
4.x部署的,现在根据需要,要将Redis
4.x升级到Redis
5.0.10版本,且现有的Redis
集群不能停机。下面以本地的机器为例进行操作演示。
操作步骤
下载&安装Redis 5.0.10
目前的Redis集群部署在 /usr/local/redis
目录下, /usr/local
下执行命令下载Redis
5.0.10
cd /usr/local
wget http://download.redis.io/releases/redis-5.0.10.tar.gz
然后进行解压安装
tar -zxvf redis-5.0.10.tar.gz
cd redis-5.0.10
make & make install
从节点替换
先进入Redis
4集群的安装目录,执行命令查看目前的集群节点以及主从结构
# 进入目录
cd /usr/local/redis/bin/
# 其中 xxx 是Redis集群的密码
./redis-cli -h 172.30.32.114 -p 7001 -a 'xxx' cluster nodes
注意,xxx是集群密码,密码必须加上英文输入法下的单括号,不然会报错
我们以 7001(主)和7002(从)这一对为例进行演示
Redis5版本的7002节点替换
然后回到 /usr/local
目录,执行命令,创建redis5-cluster
、bin
、data
、log
和cfg
等文件夹。
mkdir -p /usr/local/redis5-cluster
mkdir -p /usr/local/redis5-cluster/bin
mkdir -p /usr/local/redis5-cluster/data
mkdir -p /usr/local/redis5-cluster/log
mkdir -p /usr/local/redis5-cluster/cfg
如下所示:
执行命令,将redis-5.0.10/src
目录下的所有命令全部复制到 redis5-cluster/bin
目录下
cp -r /usr/local/redis-5.0.10/src/* /usr/local/redis5-cluster/bin/
进入到redis5-cluster/cfg
目录下,执行 vim redis-7002.conf
命令,然后将下面的内容复制进去,保存即可。
# 后台运行设置
daemonize yes
# PID 文件路径
pidfile /usr/local/redis5-cluster/data/redis-7002.pid
# 关闭保护模式
protected-mode no
# 监听端口号
port 7002
# TCP backlog,即等待处理的连接队列长度
tcp-backlog 511
# 绑定当前机器 IP
bind 172.30.32.114
# Unix socket 文件路径
unixsocket /usr/local/redis5-cluster/data/redis-7002.sock
# Unix socket 权限
unixsocketperm 700
# 客户端空闲超时时间(秒)
timeout 300
# TCP keepalive 时间间隔(秒)
tcp-keepalive 60
# 是否使用 supervisor 管理
supervised no
# 日志级别(debug, verbose, notice, warning)
loglevel warning
# 日志文件路径
logfile /usr/local/redis5-cluster/log/redis-7002.log
# 数据库数量
databases 16
# RDB 快照保存策略
save 900 1
save 300 10
save 60 10000
# 如果执行 BGSAVE 出错,停止写操作
stop-writes-on-bgsave-error yes
# RDB 文件是否压缩
rdbcompression yes
# RDB 文件是否校验
rdbchecksum yes
# RDB 文件名
dbfilename dump-7002.rdb
# 数据目录
dir /usr/local/redis5-cluster/data
# 主节点认证密码
masterauth xxx
# 从节点在同步过程中是否继续服务
slave-serve-stale-data yes
# 从节点是否只读
slave-read-only yes
# 是否使用无磁盘复制
repl-diskless-sync no
# 无磁盘复制延迟时间(秒)
repl-diskless-sync-delay 5
# 是否禁用 TCP nodelay
repl-disable-tcp-nodelay no
# 从节点优先级
slave-priority 100
# 密码
requirepass xxx
# 最大客户端连接数
maxclients 10000
# 最大内存限制(字节)
maxmemory 10737418240
# 内存淘汰策略
maxmemory-policy allkeys-lru
# LRU/LFU 算法采样数量
maxmemory-samples 5
# 是否懒惰地执行 eviction
lazyfree-lazy-eviction no
# 是否懒惰地执行过期 key 的清理
lazyfree-lazy-expire no
# 是否懒惰地执行服务器删除操作
lazyfree-lazy-server-del no
# 从节点是否懒惰地执行 flush
slave-lazy-flush no
# 是否启用 AOF 日志
appendonly yes
# AOF 文件名
appendfilename "appendonly-7002.aof"
# AOF 文件同步策略(always, everysec, no)
appendfsync no
# 在重写 AOF 文件时是否禁用 appendfsync
no-appendfsync-on-rewrite yes
# AOF 自动重写触发条件百分比
auto-aof-rewrite-percentage 100
# AOF 自动重写最小大小
auto-aof-rewrite-min-size 64mb
# 如果 AOF 文件损坏,尝试截断加载
aof-load-truncated yes
# 是否使用 RDB 格式作为 AOF 前缀
aof-use-rdb-preamble no
# Lua 脚本执行时间限制(毫秒)
lua-time-limit 5000
# 是否启用集群模式
cluster-enabled yes
# 集群配置文件路径
cluster-config-file /usr/local/redis5-cluster/data/nodes-7002.conf
# 集群节点超时时间(毫秒)
cluster-node-timeout 15000
# 慢查询日志最大长度
slowlog-max-len 128
# 延迟监控阈值(微秒)
latency-monitor-threshold 0
# 监听 keyspace 事件
notify-keyspace-events ""
# Hash 类型的最大 ziplist 元素数量
hash-max-ziplist-entries 512
# Hash 类型的最大 ziplist 值大小
hash-max-ziplist-value 64
# List 类型的最大 ziplist 元素数量
list-max-ziplist-entries 512
# List 类型的最大 ziplist 值大小
list-max-ziplist-value 64
# List 压缩深度
list-compress-depth 0
# Set 类型的最大 intset 元素数量
set-max-intset-entries 512
# ZSet 类型的最大 ziplist 元素数量
zset-max-ziplist-entries 128
# ZSet 类型的最大 ziplist 值大小
zset-max-ziplist-value 64
# HyperLogLog 类型的最大稀疏表示大小
hll-sparse-max-bytes 3000
# 是否激活 rehashing
activerehashing yes
# 客户端输出缓冲区限制(正常客户端)
client-output-buffer-limit normal 0 0 0
# 客户端输出缓冲区限制(从节点)
client-output-buffer-limit slave 256mb 64mb 60
# 客户端输出缓冲区限制(发布订阅客户端)
client-output-buffer-limit pubsub 32mb 8mb 60
# 事件循环频率(每秒次数)
hz 10
# AOF 重写时是否使用增量 fsync
aof-rewrite-incremental-fsync yes
# LFU 日志因子
lfu-log-factor 10
# LFU 衰减时间(秒)
lfu-decay-time 1
# 是否启用主动 defragmentation
activedefrag no
然后进入到旧的Redis
集群的安装目录中,将原先的Redis
4版本的的7002节点关闭,再启动Redis
5版本的7002节点,之后再将7002节点加入到集群中,并将其设置为7001的从节点。命令如下:
# 进入Redis4版本集群的bin目录
cd /usr/local/redis/bin/
# 停止 Redis4版本的7002节点
./redis-cli -h 172.30.32.114 -p 7002 -a 'xxx' shutdown
# 进入到redis5-cluster的bin目录
cd /usr/local/redis5-cluster/bin/
# 启动 redis5版本的7002节点
./redis-server ../cfg/redis-7002.conf &
# 进入Redis4版本集群的bin目录
cd /usr/local/redis/bin/
# 将redis5版本的7002节点加入到集群中
./redis-cli -h 172.30.32.114 -p 7002 -a 'xxx' cluster meet 172.30.32.114 7001
查看7001主节点的node_id
./redis-cli -h 172.30.32.114 -p 7001 -a 'xxx' cluster nodes
此时将7002节点设置为7001节点的从节点:
./redis-cli -h 172.30.32.114 -p 7002 -a 'xxx' cluster replicate 0caba7e5cd031abd24eb6ac8897fd3841a5c98c3
执行命令,根据node_id
判断7002是否已变成7001的从节点
./redis-cli -h 172.30.32.114 -p 7001 -a 'xxx' cluster nodes
剩余从节点的替换
其他从节点的替换参照上面即可,以7003(主)&7004(从)替换为例,过程如下:
创建配置文件:
# 进入到redis5-cluster的cfg目录
cd /usr/local/redis5-cluster/cfg
vim redis-7004.conf
redis-7004.conf
参考redis-7002.conf
即可,将所有的7002替换为7004即可
进入Redis
4版本集群的bin
目录:
cd /usr/local/redis/bin/
关闭旧的7003节点:
./redis-cli -h 172.30.32.114 -p 7004 -a 'xxx' shutdown
进入到redis5-cluster
的bin
目录:
cd /usr/local/redis5-cluster/bin
启动新版本的7004节点:
./redis-server ../cfg/redis-7004.conf &
进入Redis
4版本集群的bin
目录:
cd /usr/local/redis/bin/
将7004节点加入到集群中:
./redis-cli -h 172.30.32.114 -p 7004 -a 'xxx' cluster meet 172.30.32.114 7003
查看7003主节点的node_id
:
./redis-cli -h 172.30.32.114 -p 7003 -a 'xxx' cluster nodes
将7004节点设置为7003节点的从节点:
./redis-cli -h 172.30.32.114 -p 7004 -a 'xxx' cluster replicate 7003_node_id
查看是否7004是否成为7003的从节点:
./redis-cli -h 172.30.32.114 -p 7003 -a 'xxx' cluster nodes
这样就完成了一个从节点的替换。
主节点替换
7001主节点替换
先查看7001主节点信息
# 进入Redis4版本集群的bin目录
cd /usr/local/redis/bin/
# 查看7001主节点信息
./redis-cli -c -h 172.30.32.114 -p 7001 -a 'xxx' cluster nodes | grep master
比如现在想升级7001主节点,则需要先将其master
地位转移到他的从节点7002上,执行命令:
# 7002 是7001的从节点
./redis-cli -c -h 172.30.32.114 -p 7002 -a 'xxx' cluster failover
注意,这里的7002是7001主节点对应的其中一个从节点的端口,这里不能是7001端口,不然会报错,ERR You should send CLUSTER FAILOVER to a replica。
再次查看主节点,发现7002已经变成了主节点,7001变成了7002的从节点。
此时7001就是7002的从节点,此时将7001节点升级到Redis
5.0.10即可,其步骤可以参考从节点升级即可。命令如下:
# 创建配置文件:
cd /usr/local/redis5-cluster/cfg
# redis-7001.conf参考redis-7002.conf即可,将所有的7002替换为7001即可
vim redis-7001.conf
# 进入Redis4版本集群的bin目录
cd /usr/local/redis/bin/
# 停止7001节点
./redis-cli -h 172.30.32.114 -p 7001 -a 'xxx' shutdown
# 进入到redis5-cluster的bin目录
cd /usr/local/redis5-cluster/bin
# 启动新版本的7001节点
./redis-server ../cfg/redis-7001.conf &
# 进入Redis4版本集群的bin目录
cd /usr/local/redis/bin/
# 将7001节点加入到集群中
./redis-cli -h 172.30.32.114 -p 7001 -a 'xxx' cluster meet 172.30.32.114 7002
# 查看 7002主节点的node_id
./redis-cli -h 172.30.32.114 -p 7002 -a 'xxx' cluster nodes | grep 7002
# 将 7001 节点设置为 7002 节点的从节点
./redis-cli -h 172.30.32.114 -p 7001 -a 'xxx' cluster replicate 7002_node_id
# 查看是否7001是否成为7002的从节点:
./redis-cli -h 172.30.32.114 -p 7001 -a 'xxx' cluster nodes
这样就完成了一个从节点的替换。
执行命令,验证主从是否进行了同步:
./redis-cli -h 172.30.32.114 -p 7001 -a 'xxx' info replication
确认master_link_status
显示为up
,并且 master_last_io_seconds_ago
显示为较小的值。
执行命令,验证主从一致性:
# 主节点设置值:
./redis-cli -c -h 172.30.32.114 -p 7002 -a 'xxx' set test_m_s_7001_7002 test
从节点获取值:
# 连接客户端
./redis-cli -c -h 172.30.32.114 -p 7001 -a 'xxx' get test_m_s_7001_7002
其他主节点的替换
剩余主节点参考上诉操作即可,以7003主节点替换为例,过程如下:
进入Redis
4版本集群的bin
目录:
cd /usr/local/redis/bin
查看7003主节点信息,找到他的从节点的端口:
./redis-cli -c -h 172.30.32.114 -p 7003 -a 'xxx' cluster nodes
7003主节点故障转移,这里假设7004是7003的一个从节点:
./redis-cli -c -h 172.30.32.114 -p 7004 -a 'xxx' cluster failover
关闭旧的7003主节点:
./redis-cli -h 172.30.32.114 -p 7003 -a 'xxx' shutdown
进入到新版本Redis
的命令目录:
cd /usr/local/redis5-cluster/bin
启动7003节点:
./redis-server ../cfg/redis-7003.conf &
进入到旧的集群的安装目录:
cd /usr/local/redis/bin
将Redis5
版本的7003节点加入到集群中:
./redis-cli -h 172.30.32.114 -p 7003 -a 'xxx' cluster meet 172.30.32.114 7004
查看7004主节点的node_id
:
./redis-cli -h 172.30.32.114 -p 7004 -a 'xxx' cluster nodes | grep 7004
将7003节点设置为7004节点的从节点:
./redis-cli -h 172.30.32.114 -p 7003 -a 'xxx' cluster replicate 7004_node_id
验证主从是否进行了同步,确认master_link_status
显示为up
,并且master_last_io_seconds_ago
显示为较小的值。
./redis-cli -h 172.30.32.114 -p 7003 -a 'xxx' info replication
执行命令,验证主从一致性。
主节点设置值:
./redis-cli -c -h 172.30.32.114 -p 7004 -a 'xxx' set test_m_s_7003_7004 test
从节点获取值:
./redis-cli -c -h 172.30.32.114 -p 7003 -a 'xxx' get test_m_s_7003_7004