Redis16-redis集群滚动升级

  • 将redis集群从5.0.14升级到6.0.8

1、准备升级

1、查看redis集群

  • 可以看到该redis集群一共有6个节点(3主3从)。
    • 三主(master)分别是:
      • 10.1.1.11:7001
      • 10.1.1.12:7001
      • 10.1.1.13:7001
    • 三从(slave)分别是:
      • 10.1.1.11:7002
      • 10.1.1.12:7002
      • 10.1.1.13:7002
]# redis-cli -h 10.1.1.11 -p 7001 -a admin
10.1.1.11:7001> cluster nodes
2b56e66b209da72814e9a7a110fa3d212ebd558c 10.1.1.11:7001@17001 myself,master - 0 1675303371000 1 connected 0-5460
a7e6ccc25f2eb0b44fba3725794a38b77fb2ea30 10.1.1.13:7001@17001 master - 0 1675303370068 5 connected 10923-16383
8f5924b07e45a3c13a76bb59fab1cabc26b2f2ce 10.1.1.12:7002@17002 slave 2b56e66b209da72814e9a7a110fa3d212ebd558c 0 1675303369000 4 connected
196007b57fc57344597107194b1fa6c7339e04db 10.1.1.11:7002@17002 slave a7e6ccc25f2eb0b44fba3725794a38b77fb2ea30 0 1675303371085 5 connected
62713f8095076290e41e937109bc3b03e58922d8 10.1.1.12:7001@17001 master - 0 1675303372103 3 connected 5461-10922
fe49aafd59b216faadf7f265e8a290d9797e89b8 10.1.1.13:7002@17002 slave 62713f8095076290e41e937109bc3b03e58922d8 0 1675303369049 6 connected
  • 现有redis集群必须满足下面3个条件,否就不能进行升级。
    • (1)角色为master的节点,必须在不同的机器上。
    • (2)所有节点的状态都必须是connected。
    • (3)角色为slave的节点的主节点必须在其他机器上,如下图所示。

2、向研发确认连接redis的方式

  • 是否通过一串地址的方式访问数据库:
    • 10.1.1.11:7001,10.1.1.11:7002,10.1.1.12:7001,10.1.1.12:7002,10.1.1.13:7001,10.1.1.13:7002

3、向集群中写入模拟数据

  • 在实际生产中,该步骤不需要执行
]# for i in {1..1000}; do redis-cli -h 10.1.1.11 -p 7001 -a admin -c set key${i} value${i} > /dev/null 2>&1; done

2、备份所有主节点的数据

//(1)在所有存在主节点的机器上执行备份数据的脚本
]# sudo sh /opt/sh/redis-backup.sh 60 15

//(2)查看备份的数据
]# tar zvft /data/redis-backup/2023-02-02/7001.tar.gz 
drwxr-xr-x root/root         0 2023-02-02 01:32 7001/
-rw-r--r-- root/root     64385 2023-02-02 01:32 7001/redis-7001.conf
-rw-r----- root/root     12782 2023-02-02 01:32 7001/appendonly.aof
-rw-r----- root/root      5704 2023-02-02 01:32 7001/dump.rdb
  • redis-backup.sh脚本
#!/bin/bash
                                                                    
###-------------版本变更记录-------------------
###  日期          描述              作者
###--------------------------------------------
###  2023-01-27    Redis备份         麦龙飞

###使用方法是:sh ./redis-backup.sh 60 15
###参数1:如果bgsave命令在60个时间单位内没完成,就是会备份失败。一个时间单位是5s
###参数2:备份文件最少保留15天

if [[ -z $1 ]]; then
    bgsave_time=60
else
    bgsave_time=$1
fi

if [[ -z $2 ]]; then
    backup_keepday=15
else
    backup_keepday=$2
fi

#获取当前时间-秒
backup_time=$(date "+%F %T")
#获取当前时间-天
backup_day=$(date +"%Y-%m-%d")

#redis安装目录
apps_dir=/usr/local
#redis数据备份的目录
redis_backup_dir=/data/redis-backup
#redis端口列表
redis_port="[7001, 7002]"
port_list=$(echo "${redis_port}" | grep -Eo "[0-9]{0,6}")
#机器IP地址
ip_address=10.1.1.11

#备份配置文件
redis_conf_backup() {
    cp ${redis_home_dir}/conf/*.conf ${redis_backup_dir_today}
}

#备份数据持久化文件
redis_data_backup() {
    #持久化数据
    ${redis_cli_command} bgsave > /dev/null 2>&1
    for ((i=1;i<=${bgsave_time};i++)); do
        #判断bgsave命令是否已经执行完成
        bgsave_status=$(${redis_cli_command} info 2> /dev/null | grep -o "rdb_bgsave_in_progress:0")
        if [[ -n ${bgsave_status} ]]; then
            cp ${redis_home_dir}/data/appendonly.aof ${redis_backup_dir_today}
            cp ${redis_home_dir}/data/dump.rdb ${redis_backup_dir_today}
            echo "${backup_time} ${redis_home_dir}实例使用${i}个时间单位备份成功" >> ${redis_backup_dir}/redis-backup.log
            break
        fi

        sleep 5

        #如果在指定时间单位内bgsave命令没有完成,就会备份失败
        if [[ ${i} -eq ${bgsave_time} ]]; then
            echo "${backup_time} ${redis_home_dir}实例在${i}个时间单位内没有运行完bgsave,备份失败" >> ${redis_backup_dir}/redis-backup.log
        fi
    done
}

#管理备份文件
management_backup() {
    cd ${redis_backup_dir}/${backup_day}
    #压缩当天的备份文件
    tar zfc ${1}.tar.gz ${1} --remove-files

    #清理备份文件(清理相应的端口文件,清理空目录)
    find ${redis_backup_dir}/* -mtime +${backup_keepday} \( \( -type f -iname "${1}*" \) -o \( -type d \) \) -delete
}

#遍历所有端口(reids实例)
for port in ${port_list}; do
    redis_home_dir=${apps_dir}/redis-${port}
    redis_passwd=$(grep "^\s*requirepass" ${redis_home_dir}/conf/redis-${port}.conf | awk '{print $2}')
    redis_cli_command="${redis_home_dir}/bin/redis-cli -h ${ip_address} -p ${port} -a ${redis_passwd}"

    #判断reids实例是否是master,如果是则进行备份
    node_status=$(${redis_cli_command} info 2> /dev/null | grep -o "role:master")
    if [[ -n ${node_status} ]]; then
        #创建备份目录
        redis_backup_dir_today="${redis_backup_dir}/${backup_day}/${port}"
        if [[ ! -d ${redis_backup_dir_today} ]]; then
            mkdir -p ${redis_backup_dir_today}
        fi

        #备份配置文件
        redis_conf_backup
        #备份数据持久化文件
        redis_data_backup
        #管理备份文件(如果备份持久化文件失败,则不清理相应的持久化文件)
        if [[ -f ${redis_backup_dir_today}/dump.rdb ]]; then
            management_backup ${port}
        fi
    fi
done
View Code

3、部署新版本的redis

  • 这里使用ansible-role在每台机器上部署两个新版本的redis实例
    • 只是在每台机器上安装了两个redis,而且没有启动。
//(1)添加主机和账密
]# cat inventory/redis-cluster.hosts
[cluster]
10.1.1.11
10.1.1.12
10.1.1.13
[all:vars]
ansible_user=centoshh
ansible_password=centoshh

//(2)修改redis_port变量
]# cat roles/redis/defaults/main.yaml
redis_port:
  - 7001
  - 7002

//(3)执行ansible-playbook命令
ansible-playbook -i inventory/redis-cluster.hosts playbooks/redis-cluster.yaml -b\
    -e "redis_cluster_enabled=yes" -e "redis_version=6.0.8" \
    --skip-tags start-service --skip-tags create-cluster
  • 查看新部署的redis实例,验证路径
//可以看出redis-7001已经连接到了新的redis实例上
]# ls -l /usr/local/
drwxr-xr-x  3 root root 17 2月   2 01:20 redis-5.0.14
drwxr-xr-x  5 root root 64 2月   2 01:20 redis-5.0.14-6379
drwxr-xr-x  5 root root 64 2月   2 01:24 redis-5.0.14-7001
drwxr-xr-x  5 root root 64 2月   2 01:24 redis-5.0.14-7002
drwxr-xr-x  3 root root 17 2月   2 01:38 redis-6.0.8
drwxr-xr-x  5 root root 64 2月   2 01:40 redis-6.0.8-7001
drwxr-xr-x  5 root root 64 2月   2 01:40 redis-6.0.8-7002
lrwxrwxrwx  1 root root 28 2月   2 01:20 redis-6379 -> /usr/local/redis-5.0.14-6379
lrwxrwxrwx  1 root root 27 2月   2 01:40 redis-7001 -> /usr/local/redis-6.0.8-7001
lrwxrwxrwx  1 root root 27 2月   2 01:40 redis-7002 -> /usr/local/redis-6.0.8-7002

//查看redis实例的路径
]# ls -l /usr/local/redis-6.0.8-7001/
lrwxrwxrwx 1 root root 26 2月   2 01:40 bin -> /usr/local/redis-6.0.8/bin
drwxr-xr-x 2 root root 29 2月   2 01:40 conf
lrwxrwxrwx 1 root root 27 2月   2 01:40 data -> /data/redis-data-6.0.8-7001
drwxr-xr-x 2 root root  6 2月   2 01:40 logs
drwxr-xr-x 2 root root  6 2月   2 01:40 run

4、滚动升级redis集群

  • 先升级从节点,再升级主节点

4.1、升级从节点(7002节点)

1、停止所有从节点

  • (1)停止所有从节点。
]# systemctl stop redis-5.0.14-7002.service
  • (2)验证从节点是否已经关闭

2、将新版本的redis节点加入到集群中

  • (1)启动所有新版本的redis-7002节点
    • 注意,启动的端口要与刚刚停掉的一样
]# systemctl start redis-7002.service
  • (2)查看新的redis-7002节点的状态
    • 可以看到新的redis-7002节点是一个孤儿节点
]# redis-cli -h 10.1.1.11 -p 7002 -a admin
10.1.1.11:7002> cluster nodes
9c199245506337f4cf252f6bda5467fbe98032a9 10.1.1.11:7002@17002 myself,master - 0 0 0 connected
  • (3)将新的redis-7002节点作为从节点加入到集群中
    • 注意,各个从节点与主节点的对应关系
//将新节点10.1.1.11:7002作为a7e6ccc25f2eb0b44fba3725794a38b77fb2ea30(10.1.1.13:7001)的从节点加入到10.1.1.11:7001节点所在的集群。
]# redis-cli -h 10.1.1.11 -p 7001 -a admin --cluster add-node 10.1.1.11:7002 10.1.1.11:7001 \
    --cluster-slave --cluster-master-id a7e6ccc25f2eb0b44fba3725794a38b77fb2ea30

//将新节点10.1.1.12:7002作为2b56e66b209da72814e9a7a110fa3d212ebd558c(10.1.1.11:7001)的从节点加入到10.1.1.11:7001节点所在的集群。
]# redis-cli -h 10.1.1.11 -p 7001 -a admin --cluster add-node 10.1.1.12:7002 10.1.1.11:7001 \
    --cluster-slave --cluster-master-id 2b56e66b209da72814e9a7a110fa3d212ebd558c

//将新节点10.1.1.13:7002作为62713f8095076290e41e937109bc3b03e58922d8(10.1.1.12:7001)的从节点加入到10.1.1.11:7001节点所在的集群。
]# redis-cli -h 10.1.1.11 -p 7001 -a admin --cluster add-node 10.1.1.13:7002 10.1.1.11:7001 \
    --cluster-slave --cluster-master-id 62713f8095076290e41e937109bc3b03e58922d8
  • (4)再次查看新的redis-7002节点的状态
    • 可以看到新的redis-7002节点已经作为从节点已经加入到了集群中。(fail状态的是刚刚停掉的从节点,不用管)

4.2、强制转换主从节点

  • 将从节点强制提升为主节点,同时主节点变成从节点。

1、验证主从同步

  • 验证新的redis-7002从节点是否已经与主节点同步了
//验证新的10.1.1.11:7002从节点是否已经与主节点同步了。主从节点的偏移量一致,就是同步了
]# redis-cli -h 10.1.1.11 -p 7002 -a admin info replication | grep 'repl_offset'
slave_repl_offset:17248
master_repl_offset:17248

//验证新的10.1.1.12:7002从节点是否已经与主节点同步了。
]# redis-cli -h 10.1.1.12 -p 7002 -a admin info replication | grep 'repl_offset'
slave_repl_offset:17362
master_repl_offset:17362

//验证新的10.1.1.13:7002从节点是否已经与主节点同步了。
]# redis-cli -h 10.1.1.13 -p 7002 -a admin info replication | grep 'repl_offset'
slave_repl_offset:17573
master_repl_offset:17573
  • 还有一种方法可以验证主从是否同步了。
//通过查看主节点的各校色,获取各节点的偏移量
]# redis-cli -h 10.1.1.11 -p 7001 -a admin role
1) "master"
2) (integer) 17768
3) 1) 1) "10.1.1.12"
      2) "7002"
      3) "17768"

2、将所有新的redis-7002从节点强制提升为主节点

  • (1)在新的redis-7002从节点上执行命令
//将新的10.1.1.11:7002从节点强制提升为主节点
]# redis-cli -h 10.1.1.11 -p 7002 -a admin CLUSTER FAILOVER

//将新的10.1.1.12:7002从节点强制提升为主节点
]# redis-cli -h 10.1.1.12 -p 7002 -a admin CLUSTER FAILOVER

//将新的10.1.1.13:7002从节点强制提升为主节点
]# redis-cli -h 10.1.1.13 -p 7002 -a admin CLUSTER FAILOVER
  • (2)查看各节点的状态
    • 可以看到新的redis-7002已经成为主节点,而redis-7001节点变成了从节点。

4.3、升级从节点(7001节点)

  • 这时7001节点已经变成了从节点,升级方式同上。
  • 升级后可以不做主从切换
  • 分别通过7001和7002节点查看节点状态。
    • 在7002中包含旧节点状态,这是因为nodes-7002.conf文件的原因。

#                                                                                                                                     #
posted @ 2023-02-01 20:30  麦恒  阅读(560)  评论(1编辑  收藏  举报