# AWS RDS + EC2 Redis 到外部备用服务器 Runbook 目标:让 `104.238.220.230` 持续作为 AWS 主生产环境的异地备用节点,承接: - MySQL 外部只读从库 - Redis 外部从库 - 故障时的快速提升与业务切换 本文档以 `2026-05-13` 的真实现网状态为准,覆盖: - 当前已经落地的主从架构 - 日常验收命令 - 主从故障排查 - 全量重建从库 - “新建规范 RDS 再切换”的生产级收敛路线 - 故障切换与回滚 ## 1. 当前已确认资源 ### 1.1 AWS 主生产 - Region: `ap-east-1` - AWS app EC2: - Name: `hifast-hk-app-01` - Public IP: `18.163.33.75` - Private IP: `10.0.1.201` - AWS MySQL: - Type: `RDS MySQL` - Instance: `hifast-mysql-prod-v2` - Endpoint: `hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com` - Version: `8.4.8` - DB Name: `hifast` - Admin user: `admin` - Admin password: keep it in a secret store, do not write plaintext into repo docs - Replication user: `repl` - Replication password: keep it in a secret store, do not write plaintext into repo docs - AWS Redis: - Location: `hifast-hk-app-01` - Deployment: `Docker` - Container: `hifast-redis` - Version: `redis:8.2.1` - Listen: `0.0.0.0:6379` - Password: keep it in a secret store, do not write plaintext into repo docs ### 1.2 外部备用服务器 - Host: `104.238.220.230` - OS: `Ubuntu 24.04 LTS` - SSH user: `root` - MySQL version: `8.4.9` - Redis version: `8.6.3` - 当前角色: - MySQL external replica - Redis replica - 备用应用节点 ### 1.3 当前应用真实运行方式 AWS 应用机上的 `ppanel-server` 当前不是 systemd 托管,而是 Docker Compose 服务: - Compose file: `/opt/ppanel/docker-compose.cloud.yml` - Config file: `/opt/ppanel/configs/ppanel.yaml` - Container name: `ppanel-server` - Current MySQL target: `hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com:3306` - Current Redis target: `127.0.0.1:6379` 也就是说,后续所有应用侧切换步骤,都应该以修改: - `/opt/ppanel/configs/ppanel.yaml` 并执行: ```bash cd /opt/ppanel docker compose -f docker-compose.cloud.yml up -d ppanel-server ``` 作为准。 ## 2. 当前健康基线 截至 `2026-05-13`,已确认以下状态成立: - `104` MySQL: - `Source_Host = hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com` - `Replica_IO_Running: Yes` - `Replica_SQL_Running: Yes` - `Seconds_Behind_Source: 0` - `read_only = ON` - `super_read_only = ON` - AWS Redis 主库: - `role:master` - `connected_slaves:1` - `104` Redis: - `role:slave` - `master_link_status:up` - AWS 应用: - `curl http://127.0.0.1:8080/v1/common/heartbeat` 返回 `code=200` 这说明当前状态已经达到: - 主生产可用 - 外部备用持续同步 - Redis 已回到真实本机链路 ## 3. 当前网络前提 ### 3.1 安全组 当前实际生效的安全组如下: - `hifast-hk-app-core-sg` - `22/tcp <- 0.0.0.0/0` - `6379/tcp <- 104.238.220.230/32` - `8080/tcp <- hifast-hk-web-sg` - `hifast-hk-rds-core-sg` - `3306/tcp <- 104.238.220.230/32` - `3306/tcp <- hifast-hk-app-core-sg` - `hifast-hk-web-sg` - `22/80/443 <- 0.0.0.0/0` ### 3.2 当前结构性限制 当前 `104 -> RDS` 公网复制链路虽然可用,但依赖的是: - `hifast-mysql-prod-v2` 为 `Publicly accessible = Yes` - RDS ENI 仍位于 `hifast-hk-private-1b` - `private-1b` 被临时挂到了公网路由表 这不是最终规范的生产形态。 当前这条路线已经完成,后续更推荐的动作是: 1. 持续确认应用主库目标保持在 `hifast-mysql-prod-v2` 2. 持续确认 `104` 复制目标保持在 `hifast-mysql-prod-v2` 3. 根据回收窗口安排旧 RDS 下线 4. 按网络收敛计划处理 `private-1b` 路由语义 ## 4. 日常验收命令 ### 4.1 验收 MySQL 主从 在 `104` 执行: ```bash mysql -e "SHOW REPLICA STATUS\G" ``` 重点看: - `Source_Host` - `Replica_IO_Running` - `Replica_SQL_Running` - `Seconds_Behind_Source` - `Last_IO_Error` - `Last_SQL_Error` 成功标准: - `Replica_IO_Running: Yes` - `Replica_SQL_Running: Yes` - `Seconds_Behind_Source: 0` 或较小 ### 4.2 验收 Redis 主从 在 AWS app EC2 执行: ```bash docker exec hifast-redis redis-cli -a '0BVz9XOHf7KUfEuoFJRK-dURdKUGFiZ8QeaHpysHnKeKhLskZb55HPK121lFsKtr' INFO replication ``` 重点看: - `role:master` - `connected_slaves:1` 在 `104` 执行: ```bash redis-cli INFO replication ``` 重点看: - `role:slave` - `master_host:18.163.33.75` - `master_port:6379` - `master_link_status:up` ### 4.3 验收应用 在 AWS app EC2 执行: ```bash curl -sf http://127.0.0.1:8080/v1/common/heartbeat ``` 期望返回: - `{"code":200,...}` 查看容器: ```bash cd /opt/ppanel docker compose -f docker-compose.cloud.yml ps ``` 期望: - `ppanel-server` 为 `Up` - `hifast-redis` 为 `Up` ## 5. MySQL 复制故障排查 ### 5.1 先看复制状态 ```bash mysql -e "SHOW REPLICA STATUS\G" ``` 重点判断: - `Replica_IO_Running = No` - `Replica_SQL_Running = No` - `Last_IO_Error` - `Last_SQL_Error` ### 5.2 常见场景 #### 场景 A:网络或白名单断开 表现: - `Replica_IO_Running: No` - `Last_IO_Error` 出现连接失败、超时、拒绝访问 排查: ```bash mysql -h hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com -u repl -p -e "SELECT 1;" ``` 处理: - 检查 RDS SG 是否仍保留 `104.238.220.230/32 -> 3306` - 检查 RDS 是否仍为 `Publicly accessible = Yes` - 如果后续已迁到新规范 RDS,则检查新实例的 SG 和公网可达性 #### 场景 B:主库 binlog 位点丢失 表现: - `Last_IO_Error` 或 `Last_SQL_Error` 指向缺失 binlog 处理: - 不要硬跳过 - 直接执行全量重建从库 #### 场景 C:SQL 执行报错 表现: - `Replica_SQL_Running: No` - `Last_SQL_Error` 有实际 SQL 冲突信息 处理建议: - 如果只是临时演练环境,可重建从库 - 如果已经进入生产切换阶段,不建议盲目 `sql_slave_skip_counter` - 优先保守做法仍是重新全量初始化 ## 6. Redis 复制故障排查 ### 6.1 看 `104` 从库状态 ```bash redis-cli INFO replication ``` 重点: - `role` - `master_host` - `master_link_status` ### 6.2 看 AWS 主库状态 ```bash docker exec hifast-redis redis-cli -a '0BVz9XOHf7KUfEuoFJRK-dURdKUGFiZ8QeaHpysHnKeKhLskZb55HPK121lFsKtr' INFO replication ``` 重点: - `role:master` - `connected_slaves` ### 6.3 常见问题 #### 场景 A:安全组断开 表现: - `master_link_status:down` 处理: - 确认 `hifast-hk-app-core-sg` 仍保留: - `6379/tcp <- 104.238.220.230/32` #### 场景 B:主库密码漂移 表现: - 从库重连失败 - 日志出现 `NOAUTH` 处理: - 统一更新 `/etc/redis/redis.conf` 中的: - `masterauth` - 然后: ```bash systemctl restart redis-server redis-cli INFO replication ``` ## 7. 全量重建 MySQL 从库 适用场景: - 主从中断且无法安全追平 - `6666@qq.com` 这类写入在主库存在、从库未同步 - binlog 不连续 - 需要回到最稳妥状态 ### 7.1 在主库导出 在一台可连 RDS 的机器上执行: ```bash mysqldump \ -h hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com \ -u admin \ -p \ --single-transaction \ --routines \ --triggers \ --events \ --set-gtid-purged=OFF \ hifast > hifast-full.sql ``` 如果需要同步账号权限,也可以额外单独导出授权对象;但当前业务库恢复重点是 `hifast` 数据库本身。 ### 7.2 清理 `104` 当前复制 在 `104` 执行: ```sql STOP REPLICA; RESET REPLICA ALL; ``` ### 7.3 重新导入业务库 在 `104` 执行: ```bash mysql -e "DROP DATABASE IF EXISTS hifast; CREATE DATABASE hifast CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;" mysql hifast < hifast-full.sql ``` ### 7.4 重新挂复制 当前现网是非 GTID 自动定位,使用 file/position 模式。 先在主库取位点: ```sql SHOW MASTER STATUS; ``` 然后在 `104` 执行: ```sql CHANGE REPLICATION SOURCE TO SOURCE_HOST='hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com', SOURCE_PORT=3306, SOURCE_USER='repl', SOURCE_PASSWORD='', SOURCE_LOG_FILE='', SOURCE_LOG_POS=, SOURCE_SSL=1; START REPLICA; SHOW REPLICA STATUS\G ``` ### 7.5 验收 确认: - `Replica_IO_Running: Yes` - `Replica_SQL_Running: Yes` - `Seconds_Behind_Source: 0` - `read_only = ON` - `super_read_only = ON` ## 8. 重新配置 Redis 从库 当前 `104` Redis 为原生安装,不使用 Docker。 ### 8.1 临时切回从库 ```bash redis-cli CONFIG SET masterauth '0BVz9XOHf7KUfEuoFJRK-dURdKUGFiZ8QeaHpysHnKeKhLskZb55HPK121lFsKtr' redis-cli REPLICAOF 18.163.33.75 6379 redis-cli CONFIG SET replica-read-only yes redis-cli INFO replication ``` ### 8.2 持久化配置 检查 `/etc/redis/redis.conf` 至少包含: ```conf replicaof 18.163.33.75 6379 masterauth 0BVz9XOHf7KUfEuoFJRK-dURdKUGFiZ8QeaHpysHnKeKhLskZb55HPK121lFsKtr replica-read-only yes ``` 然后: ```bash systemctl restart redis-server redis-cli INFO replication ``` ## 9. 生产级收敛路线:新建规范 RDS 再切换 这条路线已经完成,当前现网主库已经切到 `hifast-mysql-prod-v2`。下面内容保留为迁移归档参考,不再表示待执行。 ### 9.1 目标 把当前临时方案: - `private-1b` 挂公网路由 收敛成: - RDS 使用纯公网 DB subnet group - 安全组仍只对白名单和应用组开放 ### 9.2 已准备好的资源 - 已建 DB subnet group: - `hifast-hk-rds-public-only-sgprep` - 子网: - `hifast-hk-public-1a` - `hifast-hk-public-1b` ### 9.3 新 RDS 建议参数 新实例建议名: - `hifast-mysql-prod-v2` 建议保持与旧主库一致: - Engine: `mysql` - Version: `8.4.8` - Class: `db.r7g.xlarge` - Storage: `gp3` - Size: `200 GB` - IOPS: `3000` - Throughput: `125` - Publicly accessible: `Yes` - Multi-AZ: `No` 或按预算单独评估 - Deletion protection: `On` - Performance Insights: `On` - Backup retention: `7` - DB subnet group: `hifast-hk-rds-public-only-sgprep` - VPC SG: `hifast-hk-rds-core-sg` ### 9.4 迁移步骤 1. 已创建新 RDS `hifast-mysql-prod-v2` 2. 在旧主库导出 `hifast` 3. 导入新库 4. 在新库创建 `repl` 用户并配置 binlog retention 5. 修改 AWS app EC2 上 `/opt/ppanel/configs/ppanel.yaml` 的 `MySQL.Addr` 6. 重启 `ppanel-server` 容器 7. 在 `104` 上 `STOP REPLICA; RESET REPLICA ALL;` 8. 指向新 RDS endpoint 重新挂复制 9. 验收应用与主从 10. 验收通过后,安排旧 RDS 下线,并推进 `private-1b` 恢复私网路由 ### 9.5 应用切换命令 在 AWS app EC2: 1. 备份配置 ```bash cp /opt/ppanel/configs/ppanel.yaml /opt/ppanel/configs/ppanel.yaml.bak.$(date +%Y%m%d%H%M%S) ``` 2. 编辑: - `/opt/ppanel/configs/ppanel.yaml` 把: ```yaml MySQL: Addr: hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com:3306 ``` 改成: ```yaml MySQL: Addr: hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com:3306 ``` 3. 重启应用容器: ```bash cd /opt/ppanel docker compose -f docker-compose.cloud.yml up -d ppanel-server ``` 4. 验证: ```bash curl -sf http://127.0.0.1:8080/v1/common/heartbeat docker compose -f docker-compose.cloud.yml logs --tail=100 ppanel-server ``` ### 9.6 `104` 改挂新 RDS ```sql STOP REPLICA; RESET REPLICA ALL; CHANGE REPLICATION SOURCE TO SOURCE_HOST='', SOURCE_PORT=3306, SOURCE_USER='repl', SOURCE_PASSWORD='', SOURCE_LOG_FILE='', SOURCE_LOG_POS=, SOURCE_SSL=1; START REPLICA; SHOW REPLICA STATUS\G ``` ### 9.7 切换验收 至少确认: - AWS 应用心跳正常 - 新 RDS 可正常读写 - `104` 复制恢复为 `Yes/Yes` - `Seconds_Behind_Source` 追到 `0` - Navicat 可从允许的白名单来源连接新 RDS ### 9.8 回滚 如果新 RDS 切换后应用异常: 1. 立即把 `/opt/ppanel/configs/ppanel.yaml` 中 `MySQL.Addr` 改回旧 endpoint 2. 重启 `ppanel-server` 3. 暂不处理 `104`,先恢复主生产 4. 复盘新库数据、权限、参数、网络 ## 10. AWS 故障时的备用接管 ### 10.1 Redis 提升为主库 在 `104`: ```bash redis-cli REPLICAOF NO ONE redis-cli INFO replication ``` 期望: - `role:master` ### 10.2 MySQL 提升为可写主库 在 `104`: ```sql STOP REPLICA; RESET REPLICA ALL; SET GLOBAL super_read_only=OFF; SET GLOBAL read_only=OFF; ``` 再确认: ```sql SHOW VARIABLES LIKE 'read_only'; SHOW VARIABLES LIKE 'super_read_only'; ``` 期望: - `OFF` - `OFF` ### 10.3 应用切到 `104` 本机数据层 如果 `104` 上也部署同样的 PPanel 服务,则应用配置应改为: - MySQL 指向 `127.0.0.1:3306` 或本机 socket - Redis 指向 `127.0.0.1:6379` ### 10.4 最后切入口 数据层和应用层都确认可写后,再做: - DNS 切换 - 或 Nginx / 上游切流量 原则: - 先数据接管 - 再应用确认 - 最后入口切换 ## 11. 日常巡检建议 建议至少每天巡检一次: 1. `104` MySQL `SHOW REPLICA STATUS\G` 2. `104` Redis `INFO replication` 3. AWS Redis 主库 `INFO replication` 4. AWS app 心跳 `/v1/common/heartbeat` 5. `docker compose -f /opt/ppanel/docker-compose.cloud.yml ps` 如果后续要做真正的生产级自动化,再补: - MySQL 复制延迟告警 - Redis 主从断链告警 - 应用心跳失败告警 - RDS 连接失败告警 - 定期灾备切换演练