如何在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
相关产品推荐
相关产品推荐

