# Hifast S3 备份集成 Runbook 本文档记录 `2026-05-13` 已经实际确认和完成的 S3 备份集成状态,以及后续如何把它和当前 `AWS 主生产 + 104 外部备用` 架构结合起来。 ## 1. 当前已完成状态 - 已创建 S3 备份桶:`hifast-prod-backups-200810848252-ap-east-1` - Region: `ap-east-1` - Public access: blocked - Versioning: enabled - 已确认 RDS 主库 `hifast-mysql-prod-v2` 自动备份已启用: - retention: `7 days` - `2026-05-13` 已有自动快照 - 已确认 `104.238.220.230` MySQL 外部从库健康,可作为逻辑备份源: - `Replica_IO_Running: Yes` - `Replica_SQL_Running: Yes` - `Seconds_Behind_Source: 0` - 已确认 `104.238.220.230` Redis 从库健康,可作为 RDB 备份源: - `role:slave` - `master_link_status:up` ## 2. 推荐组合方案 当前最稳的做法不是只依赖一种备份,而是保留两层: 1. `RDS automated backup` 2. `104` 从库导出的逻辑备份上传到 S3 原因: - RDS 自动备份适合快速恢复整库 - S3 逻辑备份适合独立下载、跨环境恢复、长期归档 - 从 `104` 导出 MySQL / Redis 备份,对 AWS 主生产扰动最小 ## 3. 仓库已补充内容 - MySQL 备份脚本: - [`deploy/scripts/mysql_backup_to_s3.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/mysql_backup_to_s3.sh) - Redis RDB 备份脚本: - [`deploy/scripts/redis_rdb_backup_to_s3.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/redis_rdb_backup_to_s3.sh) - 环境变量模板: - [`deploy/aws/ap-east-1/configs/backup-to-s3.env.example`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/aws/ap-east-1/configs/backup-to-s3.env.example) - 主从切换环境变量模板: - [`deploy/aws/ap-east-1/configs/replica-ops.env.example`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/aws/ap-east-1/configs/replica-ops.env.example) - 数据迁移交互工具: - [`deploy/scripts/hifast_data_sync_tool.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/hifast_data_sync_tool.sh) - 主从运维交互工具: - 统一入口仍使用 [`deploy/scripts/hifast_data_sync_tool.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/hifast_data_sync_tool.sh) ## 4. 建议部署位置 ### 4.1 MySQL 优先部署在 `104.238.220.230`: - 直接从本地 MySQL 从库导出 - 不占用 AWS RDS 主库的备份窗口 - 故障时备份和备用节点仍在同一台机器上 ### 4.2 Redis 优先部署在 `104.238.220.230`: - 直接从 Redis 从库导出 `RDB` - 不影响 AWS Redis 主库对外服务 ## 5. 104 当前还缺的东西 截至 `2026-05-13`,`104` 已具备: - `mysql` - `mysqldump` - `gzip` 但仍缺: - `aws cli` - 一套最小权限的 S3 上传凭证 ## 6. 推荐权限模型 当前最实用的选择有两种: 1. `104` 使用专用 IAM 用户的最小权限 `AK/SK` 2. 未来如果备份转到 AWS EC2,再改为 `EC2 Instance Role` 按现有拓扑,推荐先走第 1 种,因为 MySQL 和 Redis 的备份源都在 `104`。 ### 6.1 最小权限策略示例 ```json { "Version": "2012-10-17", "Statement": [ { "Sid": "ListBackupBucket", "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": "arn:aws:s3:::hifast-prod-backups-200810848252-ap-east-1" }, { "Sid": "WriteBackupObjects", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:AbortMultipartUpload" ], "Resource": "arn:aws:s3:::hifast-prod-backups-200810848252-ap-east-1/*" } ] } ``` 说明: - 不建议给 `s3:*` - 不建议把 AK/SK 写进 repo - 建议只写入 `104` 本机的 `/root/.aws/credentials` ## 7. 104 安装与配置步骤 ### 7.1 安装 `aws cli` ```bash apt-get update apt-get install -y awscli ``` ### 7.2 写入 AWS 凭证 ```bash mkdir -p /root/.aws chmod 700 /root/.aws cat >/root/.aws/credentials <<'EOF' [default] aws_access_key_id=CHANGE_ME aws_secret_access_key=CHANGE_ME EOF chmod 600 /root/.aws/credentials ``` ### 7.3 准备环境变量文件 ```bash cp deploy/aws/ap-east-1/configs/backup-to-s3.env.example /root/backup-to-s3.env chmod 600 /root/backup-to-s3.env ``` 把下面这些值改成真实值: - `MYSQL_PASSWORD` - `REDIS_PASSWORD` - `HOST_TAG` 如果 MySQL 就跑在 `104` 本机,可保持: - `MYSQL_HOST=127.0.0.1` 如果 Redis 就跑在 `104` 本机,可保持: - `REDIS_HOST=127.0.0.1` ## 8. 手工执行方式 ### 8.1 MySQL 逻辑备份 ```bash set -a source /root/backup-to-s3.env set +a bash deploy/scripts/mysql_backup_to_s3.sh ``` 默认产物: - 本地:`/var/backups/hifast/*.sql.gz` - S3:`s3://hifast-prod-backups-200810848252-ap-east-1/mysql//` ### 8.2 Redis RDB 备份 ```bash set -a source /root/backup-to-s3.env set +a S3_PREFIX=redis bash deploy/scripts/redis_rdb_backup_to_s3.sh ``` 默认产物: - 本地:`/var/backups/hifast/*.rdb.gz` - S3:`s3://hifast-prod-backups-200810848252-ap-east-1/redis//` ## 9. 定时任务建议 ### 9.1 MySQL 每天凌晨执行 ```cron 15 3 * * * . /root/backup-to-s3.env && /bin/bash /opt/ppanel/deploy/scripts/mysql_backup_to_s3.sh >>/var/log/hifast-mysql-backup.log 2>&1 ``` ### 9.2 Redis 每天凌晨执行 ```cron 45 3 * * * . /root/backup-to-s3.env && S3_PREFIX=redis /bin/bash /opt/ppanel/deploy/scripts/redis_rdb_backup_to_s3.sh >>/var/log/hifast-redis-backup.log 2>&1 ``` 说明: - MySQL 和 Redis 建议错峰执行 - 本地临时文件默认只保留 `3` 天 - 长期保留建议通过 S3 Lifecycle 管理,而不是靠本机 cron 删除 ## 10. 恢复思路 ### 10.1 MySQL 1. 从 S3 下载目标 `sql.gz` 2. 校验 `.sha256` 3. 解压 4. 导入目标 MySQL 示例: ```bash aws s3 cp s3://hifast-prod-backups-200810848252-ap-east-1/mysql/104-standby/20260513T120000Z_104-standby_hifast.sql.gz . aws s3 cp s3://hifast-prod-backups-200810848252-ap-east-1/mysql/104-standby/20260513T120000Z_104-standby_hifast.sql.gz.sha256 . sha256sum -c 20260513T120000Z_104-standby_hifast.sql.gz.sha256 gunzip -c 20260513T120000Z_104-standby_hifast.sql.gz | mysql -h -u -p ``` ### 10.2 Redis 1. 从 S3 下载目标 `rdb.gz` 2. 校验 `.sha256` 3. 解压得到 `dump.rdb` 4. 在维护窗口内替换 Redis 数据文件后重启 ## 11. 当前推荐落地顺序 1. 保持当前 `RDS automated backup` 不变 2. 在 `104` 安装 `aws cli` 3. 创建最小权限 S3 上传凭证并仅保存到 `104` 4. 先手工执行一轮 MySQL 备份上传 5. 验证 S3 对象、校验文件、恢复可读性 6. 再补 Redis RDB 备份 7. 最后加 cron 和 S3 Lifecycle ## 12. 104 上的交互式运维脚本 为了减少手工敲命令,仓库里现在统一使用一套交互式总入口。 ### 12.1 统一入口 ```bash bash deploy/scripts/hifast_data_sync_tool.sh /root/replica-ops.env ``` 菜单支持: - 备份 MySQL 到 S3 - 备份 Redis 到 S3 - 导出 MySQL dump - 导入 MySQL dump 到 AWS RDS - 导出后直接导入 - 导出 Redis RDB - 导入 Redis RDB 到 Docker / 宿主机 Redis - 查看 MySQL / Redis 当前主从状态 - 强制重拉 MySQL 主从 - 强制重拉 Redis 主从 - 把 MySQL 从库提升为可写主库 - 把 Redis 从库提升为主库