You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bash脚本中验证Redis Dump文件是否成功恢复?

Redis恢复后如何在Bash脚本中验证成功?

我有一个Bash脚本,负责从S3下载Redis dump文件、替换Redis容器并加载dump文件,流程如下:

  • 从S3下载最新的Redis dump文件
  • 停止并删除现有同名Redis容器
  • 启动新容器并挂载下载的dump文件
  • 等待容器就绪

手动进入容器用redis-cli能看到所有键,但不知道怎么在脚本里自动验证恢复是否成功。仅用dbsize > 0判断可靠吗?有没有更严谨的方法?

附上我的脚本:

#!/usr/bin/env bash
 
# https://www.shellcheck.net/ VERIFIED
set -e
set -E
set -o pipefail
set -u
# set -x

log="/tmp/error.txt"
exec 2>>"$log"

handle_error() {    
    # ...handle error
    exit 1
}

handle_exit() {
    # ...handle exit
    exit 0
}

trap 'handle_exit $?' EXIT
trap 'handle_error $?' ERR

bucket='something-something'
container_name="my_redis_container"
dump_file_directory="/tmp"
host="localhost"
port="6379"

dump_file_name=$(aws s3 ls $bucket --recursive | sort | tail -n 1 | awk '{print $4}')

aws s3 cp "s3://${bucket}/${dump_file_name}"  "/tmp/${dump_file_name}"

docker ps -aq --filter "name=${container_name}" | grep -q . && docker stop "${container_name}" && docker rm -fv "${container_name}"

docker run --detach --name "${container_name}" --publish "${port}:${port}" --volume "/tmp/${dump_file_name}:/data/dump.rdb" redis

# Wait for the Docker container to be ready
until docker exec -it "${container_name}" redis-cli -h "${host}" -p "${port}" ping; do
    sleep 1
done

# HOW TO VERIFY IF REDIS WAS RESTORED SUCCESSFULLY HERE???

先说说dbsize > 0的可靠性

仅用dbsize > 0判断并不完全可靠:

  • 如果dump文件本身是空的,恢复后dbsize为0,能准确识别失败;
  • 但如果dump文件损坏、加载过程出错,Redis可能启动后只加载部分数据,甚至直接忽略损坏文件启动空实例,这时候dbsize > 0可能误判成功,也可能漏判问题。

所以需要更严谨的验证逻辑。

更合适的验证方法

1. 先校验dump文件完整性(恢复前)

在下载完成后,先确保dump文件本身没问题,避免用损坏文件恢复:

# 方法1:用Redis官方工具检查dump文件有效性
docker run --rm -v "/tmp/${dump_file_name}:/tmp/dump.rdb" redis redis-check-rdb /tmp/dump.rdb

# 方法2:如果S3上存了dump的MD5校验文件,直接校验
aws s3 cp "s3://${bucket}/${dump_file_name}.md5" "/tmp/${dump_file_name}.md5"
cd /tmp && md5sum -c "${dump_file_name}.md5"

如果文件损坏,以上命令会返回非0退出码,触发脚本set -e规则终止执行。

2. 校验业务关键键或键数量

如果知道dump对应的预期键数量,可以直接对比:

# 从S3获取预存的预期键数量(比如存在expected_dbsize.txt中)
expected_dbsize=$(aws s3 cp "s3://${bucket}/expected_dbsize.txt" -)
actual_dbsize=$(docker exec "${container_name}" redis-cli dbsize)

if [ "$actual_dbsize" -ne "$expected_dbsize" ]; then
    echo "恢复失败:预期键数量$expected_dbsize,实际$actual_dbsize"
    exit 1
fi

如果不知道总数量,就校验几个业务核心键的存在和值的正确性:

# 校验关键键是否存在
docker exec "${container_name}" redis-cli EXISTS "user:1000" | grep -q 1 || { echo "关键键user:1000不存在"; exit 1; }

# 校验关键键的值是否正确
expected_value="admin"
actual_value=$(docker exec "${container_name}" redis-cli GET "user:1000:role")
if [ "$actual_value" != "$expected_value" ]; then
    echo "关键键值不匹配:预期$expected_value,实际$actual_value"
    exit 1
fi

3. 检查Redis日志的恢复记录

Redis成功加载dump文件时,会在日志输出类似DB loaded from disk: X.X seconds的内容,可以通过日志验证:

# 等待日志出现加载成功记录,超时设为30秒(可根据dump大小调整)
timeout 30s docker logs -f "${container_name}" | grep -q "DB loaded from disk" || { echo "未检测到Redis加载dump文件的日志"; exit 1; }

4. 组合验证(推荐)

把以上方法组合,形成多层校验,确保万无一失:

# 1. 检查dump文件有效性
docker run --rm -v "/tmp/${dump_file_name}:/tmp/dump.rdb" redis redis-check-rdb /tmp/dump.rdb

# 2. 等待容器就绪(优化原逻辑,去掉-it避免终端问题)
until docker exec "${container_name}" redis-cli -h "${host}" -p "${port}" ping | grep -q PONG; do
    sleep 1
done

# 3. 检查日志中的加载记录
timeout 30s docker logs -f "${container_name}" | grep -q "DB loaded from disk"

# 4. 校验关键键
docker exec "${container_name}" redis-cli EXISTS "user:1000" | grep -q 1

# 5. 可选:对比键数量
expected_dbsize=$(aws s3 cp "s3://${bucket}/expected_dbsize.txt" -)
actual_dbsize=$(docker exec "${container_name}" redis-cli dbsize)
[ "$actual_dbsize" -eq "$expected_dbsize" ]

内容的提问来源于stack exchange,提问作者PirateApp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:29:59