feat:一亿用户数据迁移

This commit is contained in:
amos
2026-02-04 15:42:42 +08:00
parent c0e168f0c0
commit 71b2fdbcbb
4 changed files with 1286 additions and 0 deletions

View File

@@ -0,0 +1,406 @@
# 应急预案
## 常见问题及处理方案
### 问题1双写失败率突然升高
**现象:**
- 双写成功率从 99.9% 下降到 90%
- 补偿队列快速堆积
**可能原因:**
1. 新库连接池耗尽
2. 新库性能问题(慢查询、锁等待)
3. 网络问题
4. 新库磁盘满
**处理步骤:**
1. **立即检查新库状态**
```sql
-- 查看连接数
SHOW PROCESSLIST;
-- 查看慢查询
SHOW FULL PROCESSLIST;
-- 查看锁等待
SELECT * FROM information_schema.innodb_locks;
```
2. **如果是连接池问题**
- 临时扩大连接池配置
- 重启应用实例
3. **如果是性能问题**
- 分析慢查询,优化索引
- Kill 掉异常的长事务
4. **如果无法快速解决**
- 关闭双写开关
- 等问题解决后重新开启
- 补偿队列的数据后续补偿
**回滚方案:**
```yaml
migration:
dual-write:
enabled: false # 关闭双写
```
---
### 问题2数据迁移影响线上性能
**现象:**
- 老库 CPU 飙升到 90%
- 接口响应时间变慢
- 用户投诉
**可能原因:**
1. 迁移脚本没有限流
2. 迁移脚本查询没有索引
3. 迁移时间选择不当(高峰期)
**处理步骤:**
1. **立即暂停迁移脚本**
- 停止所有迁移任务
- 观察老库 CPU 是否恢复
2. **分析慢查询**
```sql
-- 查看正在执行的查询
SHOW FULL PROCESSLIST;
-- 查看慢查询日志
SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 10;
```
3. **优化迁移脚本**
- 增加 sleep 时间100ms → 500ms
- 减少批次大小1000 → 500
- 添加必要的索引
- 选择低峰期迁移(凌晨 2-6 点)
4. **重新启动迁移**
- 从断点继续迁移
- 实时监控老库性能
**预防措施:**
- 迁移前在测试环境压测
- 设置 CPU 阈值,超过自动暂停
- 错峰迁移
---
### 问题3灰度读取新库失败率高
**现象:**
- 新库读取成功率只有 95%
- 频繁降级到老库
- 用户偶尔看到数据不一致
**可能原因:**
1. 新库数据不完整(迁移未完成)
2. 新库性能问题
3. 分片路由错误
4. 新库某些分片故障
**处理步骤:**
1. **立即降低灰度比例**
```yaml
migration:
read:
gray-percent: 1 # 从 10% 降到 1%
```
2. **分析失败原因**
- 查看错误日志,定位具体问题
- 检查是否有数据缺失
- 检查是否有分片故障
3. **数据缺失问题**
- 对比老库和新库数据
- 补充缺失的数据
- 重新校验
4. **性能问题**
- 优化慢查询
- 添加索引
- 调整连接池配置
5. **分片故障**
- 修复故障分片
- 或者临时屏蔽故障分片
6. **问题解决后逐步放开**
- 1% → 5% → 10% → 50% → 100%
- 每次放开后观察 1-2 天
**回滚方案:**
```yaml
migration:
read:
from-new: false # 完全关闭新库读取
gray-percent: 0
```
---
### 问题4数据不一致
**现象:**
- 数据校验发现不一致率 > 1%
- 用户反馈数据错误
**可能原因:**
1. 双写失败未补偿
2. 迁移脚本有 bug
3. 并发更新导致数据覆盖
4. 分片路由错误
**处理步骤:**
1. **立即停止灰度**
```yaml
migration:
read:
from-new: false
gray-percent: 0
```
2. **定位不一致的数据**
- 导出不一致的 user_id 列表
- 分析不一致的原因
3. **修复数据**
- 以老库为准,修复新库数据
- 或者重新迁移这部分数据
4. **修复 bug**
- 如果是代码 bug修复后重新部署
- 如果是迁移脚本 bug修复后重新迁移
5. **全量校验**
- 修复后进行全量数据校验
- 确保一致性 > 99.9%
6. **重新开始灰度**
- 从 1% 开始重新灰度
**预防措施:**
- 迁移前充分测试
- 双写失败必须补偿
- 定期数据校验
---
### 问题5新库性能不如老库
**现象:**
- 新库响应时间是老库的 2 倍
- 新库 CPU 使用率高
- 用户感知到变慢
**可能原因:**
1. 索引缺失或不合理
2. 分片策略不合理(数据倾斜)
3. 连接池配置不合理
4. 硬件配置不足
**处理步骤:**
1. **立即降低灰度比例**
```yaml
migration:
read:
gray-percent: 10 # 降低到 10%
```
2. **分析慢查询**
```sql
-- 查看慢查询
SELECT * FROM mysql.slow_log
WHERE start_time > NOW() - INTERVAL 1 HOUR
ORDER BY query_time DESC
LIMIT 20;
```
3. **优化索引**
- 对比老库和新库的索引
- 添加缺失的索引
- 删除冗余的索引
4. **检查数据倾斜**
```sql
-- 检查每个分片的数据量
SELECT COUNT(*) FROM users_0;
SELECT COUNT(*) FROM users_1;
...
```
- 如果数据倾斜严重,考虑调整分片策略
5. **调整配置**
- 连接池大小
- 缓存配置
- 硬件资源CPU、内存、磁盘
6. **优化后重新灰度**
- 从 10% 开始重新灰度
- 观察性能是否改善
**回滚方案:**
- 如果优化后仍然不行,考虑放弃分库分表
- 或者重新设计分片策略
---
### 问题6补偿队列堆积
**现象:**
- 补偿队列长度持续增长
- 从 1000 增长到 10 万
- 补偿任务处理不过来
**可能原因:**
1. 新库持续故障
2. 补偿任务处理速度慢
3. 补偿任务本身有 bug
**处理步骤:**
1. **检查新库状态**
- 如果新库故障,先修复新库
- 如果新库正常,继续下一步
2. **增加补偿任务并发度**
- 增加补偿任务的线程数
- 或者启动多个补偿任务实例
3. **分批处理**
- 不要一次性处理所有队列
- 分批处理,避免压垮新库
4. **如果队列过大**
- 考虑临时关闭双写
- 等队列处理完再重新开启
**预防措施:**
- 补偿任务要有限流
- 补偿队列要有长度告警
- 双写失败率要及时告警
---
## 回滚决策树
```
发现问题
问题是否影响用户?
↓ 是
影响面 > 10%
↓ 是
立即回滚
↓ 否
降低灰度比例,观察
↓ 否
问题是否可以快速修复(< 30分钟
↓ 是
修复问题,继续观察
↓ 否
回滚,等修复后重新上线
```
---
## 回滚操作手册
### 从阶段3回滚关闭双写
```yaml
migration:
dual-write:
enabled: false
compensation:
enabled: false
```
**影响:** 新数据不再同步到新库
### 从阶段6回滚关闭灰度
```yaml
migration:
read:
from-new: false
gray-percent: 0
```
**影响:** 所有读取回到老库
### 从阶段7回滚切回老库
```yaml
migration:
dual-write:
enabled: true # 继续双写
read:
from-new: false # 读取切回老库
gray-percent: 0
```
**影响:** 完全回到老库
---
## 值班要求
### 值班时间
- 阶段3-67×24 小时值班
- 阶段7观察期 2 周7×24 小时值班
### 值班人员
- 主值班1 人(负责处理问题)
- 备值班1 人(主值班无法处理时接手)
- DBA1 人(数据库问题支持)
### 值班职责
1. 实时监控告警
2. 发现问题立即处理
3. 无法处理立即上报
4. 记录问题和处理过程
### 联系方式
- 主值班:手机 + 钉钉
- 备值班:手机 + 钉钉
- DBA手机 + 钉钉
- 技术负责人:手机
---
## 应急演练
### 演练内容
1. 双写失败处理
2. 灰度回滚
3. 数据不一致修复
4. 新库故障切换
### 演练频率
- 上线前:至少演练 2 次
- 上线后:每周演练 1 次
### 演练要求
- 全员参与
- 记录演练过程
- 总结改进点
---
## 总结
**核心原则:**
1. **快速发现**:监控要全面,告警要及时
2. **快速决策**:问题影响面大,立即回滚
3. **快速恢复**:回滚操作要简单,一键完成
4. **事后复盘**:每次问题都要复盘,避免再犯

View File

@@ -0,0 +1,355 @@
# 1亿用户数据分库分表迁移方案
## 背景
- **数据量**1亿用户数据
- **数据库**MySQL
- **分片策略**:按 user_id 取模
- **QPS**1000
- **要求**:线上业务零影响,可随时回滚
---
## 整体架构
### 分片规划
```
1亿用户 → 8个库 × 16张表 = 128个分片
每个分片约 78万 数据
user_db_0 ~ user_db_7
users_0 ~ users_15
路由规则:
db_index = user_id % 8
table_index = (user_id / 8) % 16
```
**为什么这样分?**
- 8个库方便后续扩容到16、32个库
- 16张表单表控制在100万以内性能最优
- 总共128个分片数据足够分散
---
## 核心思路
**渐进式迁移,每一步都可回滚**
整个过程分为 **8个阶段**,像开关一样,每个阶段都可以随时回退到上一步。
---
## 迁移阶段
### 阶段0当前状态基线
```
写 → 老库
读 → 老库
```
- 这是现状,作为基线
- 任何时候出问题都可以回到这个状态
**风险**:无
**回滚**:不需要
---
### 阶段1准备新库1天
```
写 → 老库
读 → 老库
新库 → 创建好,但不使用
```
**做什么:**
- 创建 8 个新数据库
- 每个库创建 16 张表(总共 128 个分片)
- 引入分库分表中间件ShardingSphere
- 配置分片规则user_id % 8 定位库user_id / 8 % 16 定位表)
- 测试环境验证分片逻辑是否正确
**风险**:无(线上还没用新库)
**回滚**:不需要
---
### 阶段2代码改造2天
```
写 → 老库
读 → 老库
代码 → 支持双写,但开关关闭
```
**做什么:**
- 代码层面支持"双数据源"(老库 + 新库)
- 增加配置开关(双写开关、读取开关、灰度比例)
- 写操作:主写老库,可选异步写新库
- 读操作:可选从老库或新库读,支持灰度
- 双写失败不影响主流程,记录到队列补偿
- 增加补偿任务,定期重试失败的写操作
**风险**:无(开关默认关闭,逻辑不变)
**回滚**:不需要
---
### 阶段3开启双写1天
```
写 → 老库(主)+ 新库(异步)
读 → 老库
```
**做什么:**
- 打开双写开关
- 所有新增/修改/删除操作同时写入两个库
- 老库写成功就算成功,新库写失败不影响业务
- 新库写失败的记录到 Redis 队列,后台补偿任务重试
**目的:**
- 从这一刻开始,新数据实时同步到新库
- 为后续迁移历史数据做准备
**监控指标:**
- 双写失败率(应该 < 0.1%
- 补偿队列长度(应该很短)
- 新库写入 QPS应该接近老库
**风险**:低
- 读取仍然从老库,用户无感知
- 新库写失败不影响业务
- 最多就是新库数据不完整,但不影响线上
**回滚**:关闭双写开关即可
---
### 阶段4历史数据迁移3-7天
```
写 → 老库 + 新库(双写继续)
读 → 老库
迁移 → 老库历史数据 → 新库(离线任务)
```
**做什么:**
- 写一个离线迁移脚本
- 从老库分批读取历史数据(每次 1000 条)
- 写入新库(用 INSERT IGNORE 避免和双写冲突)
- 每批次之间 sleep 100ms避免影响线上数据库
- 多线程并行迁移(比如 10 个线程)
**关键点:**
- 迁移期间双写继续,保证新数据不丢
- 用 INSERT IGNORE 去重(因为双写可能已经写入)
- 限流很重要,不能影响线上数据库性能
- 记录迁移进度,支持断点续传
**时间估算:**
- 1 亿数据,每批 1000 条,每批 sleep 100ms
- 单线程约 3 小时10 线程并行约 20 分钟
- 但为了安全,建议分多天慢慢迁移
**监控指标:**
- 迁移进度(已迁移多少条)
- 迁移失败率
- 老库/新库的 CPU、IO、慢查询
**风险**:低
- 读写仍然走老库,用户无感知
- 迁移脚本只是读老库、写新库,不影响业务逻辑
- 最坏情况就是迁移失败,重新跑一遍
**回滚**:停止迁移脚本即可
---
### 阶段5数据校验1-2天
```
写 → 老库 + 新库(双写继续)
读 → 老库
校验 → 随机抽样对比两个库的数据
```
**做什么:**
- 随机抽取 1 万个 user_id
- 分别从老库和新库查询
- 对比数据是否一致
- 记录不一致的数据,人工排查原因
**目的:**
- 确认数据迁移完整性
- 发现潜在问题(比如某些边界情况没处理好)
**风险**:无(只是读取对比)
**回滚**:不需要
---
### 阶段6灰度读取7-14天
```
写 → 老库 + 新库(双写继续)
读 → 老库(主)+ 新库(灰度 1% → 10% → 50% → 100%
```
**做什么:**
- 逐步放开从新库读取的流量
- 第 1 天1% 流量读新库(按 user_id % 100 < 1
- 第 3 天10% 流量读新库
- 第 5 天50% 流量读新库
- 第 7 天100% 流量读新库
- 新库读取失败自动降级到老库
**目的:**
- 验证新库的性能和稳定性
- 小流量试错,发现问题影响面小
**监控指标:**
- 新库查询成功率(应该 > 99.9%
- 新库响应时间(应该和老库差不多)
- 降级次数(应该很少)
- 业务指标(订单量、支付成功率等)
**风险**:中
- 灰度流量可能受影响(但可以降级)
- 新库可能有性能问题(慢查询、连接池不够等)
**回滚**:调整灰度比例或关闭新库读取
---
### 阶段7完全切换观察 1-2 周后)
```
写 → 新库(主)+ 老库(备份)
读 → 新库
```
**做什么:**
- 新库成为主库
- 写操作主写新库,异步写老库(作为备份)
- 读操作 100% 从新库读
- 老库继续保留,作为降级方案
**目的:**
- 新库正式上线
- 老库作为保险,万一新库出问题可以快速切回
**监控指标:**
- 新库的所有指标QPS、响应时间、错误率
- 业务指标
- 老库作为对照组
**风险**:中
- 新库成为主库,出问题影响面大
- 但可以快速切回老库
**回滚**:切换写入和读取开关,回到老库
---
### 阶段8下线老库观察 1-2 周后)
```
写 → 新库
读 → 新库
老库 → 归档或删除
```
**做什么:**
- 关闭双写老库
- 老库数据归档备份
- 下线老库
**风险**:低(已经稳定运行很久了)
---
## 时间规划
| 阶段 | 时间 | 风险 | 可回滚 |
|------|------|------|--------|
| 0. 当前状态 | - | 无 | - |
| 1. 准备新库 | 1天 | 无 | ✅ |
| 2. 代码改造 | 2天 | 无 | ✅ |
| 3. 开启双写 | 1天 | 低 | ✅ |
| 4. 数据迁移 | 3-7天 | 低 | ✅ |
| 5. 数据校验 | 1-2天 | 无 | ✅ |
| 6. 灰度读取 | 7-14天 | 中 | ✅ |
| 7. 完全切换 | 观察1-2周 | 中 | ✅ |
| 8. 下线老库 | 1天 | 低 | ❌ |
**总计3-5 周**
---
## 关键设计思想
### 1. 渐进式切换
- 不是一步到位,而是分 8 个阶段
- 每个阶段都可以观察、验证、回滚
- 出问题影响面可控
### 2. 双写保证一致性
- 迁移期间新数据实时同步
- 历史数据离线迁移
- 两者结合保证数据完整
### 3. 异步 + 补偿保证可靠性
- 双写新库失败不影响主流程
- 失败的记录到队列,后台重试
- 最终一致性
### 4. 灰度 + 降级保证稳定性
- 小流量试错,发现问题影响面小
- 新库失败自动降级到老库
- 用户无感知
### 5. 监控 + 告警保证可观测性
- 每个阶段都有明确的监控指标
- 异常及时告警
- 数据驱动决策(什么时候进入下一阶段)
---
## 核心优势
1. **零停机**:整个过程不需要停服
2. **可回滚**:每一步都可以回退
3. **低风险**:渐进式切换,影响面可控
4. **可观测**:每个阶段都有明确的监控指标
5. **可验证**:数据校验、灰度验证,确保正确性
---
## 常见问题
### Q1双写期间数据不一致怎么办
- 异步双写失败会记录到队列,后台补偿
- 定期抽样校验,发现不一致及时修复
- 最终一致性,不是强一致性
### Q2迁移期间更新/删除怎么处理?
- 双写模式下,更新/删除同时操作两个库
- 迁移脚本用 INSERT IGNORE不会覆盖新数据
### Q3如何保证迁移不影响线上性能
- 限流:每批次之间 sleep
- 错峰:凌晨低峰期迁移
- 监控:实时监控数据库负载,超阈值暂停
### Q4新库性能不如老库怎么办
- 灰度阶段会发现
- 可以优化索引、调整分片策略
- 实在不行可以回滚
### Q5如果中途想放弃怎么办
- 关闭所有开关,回到阶段 0
- 新库数据可以保留,也可以删除
- 对线上业务无影响
---
## 总结
这个方案的核心就是:**小步快跑,随时可退**。
每一步都很小,风险可控,出问题可以快速回滚。通过渐进式迁移,保证线上业务零影响。

View File

@@ -0,0 +1,316 @@
# 监控指标
## 核心监控指标
### 1. 双写监控
#### 双写成功率
```
指标dual_write_success_rate
计算:成功次数 / 总次数 * 100%
阈值:> 99.9%
告警:< 99% 立即告警
```
#### 双写失败次数
```
指标dual_write_fail_count
计算:每分钟失败次数
阈值:< 10 次/分钟
告警:> 100 次/分钟 立即告警
```
#### 补偿队列长度
```
指标compensation_queue_length
计算Redis 队列长度
阈值:< 1000
告警:> 10000 立即告警
```
#### 补偿成功率
```
指标compensation_success_rate
计算:补偿成功次数 / 补偿总次数 * 100%
阈值:> 95%
告警:< 80% 告警
```
---
### 2. 数据库性能监控
#### QPS每秒查询数
```
老库 QPSold_db_qps
新库 QPSnew_db_qps
阈值:
- 老库1000 QPS当前基线
- 新库:应该接近老库
告警:
- 新库 QPS 突然下降 > 50%
- 新库 QPS 超过老库 2 倍(可能有问题)
```
#### 响应时间
```
老库平均响应时间old_db_avg_rt
新库平均响应时间new_db_avg_rt
阈值:
- 老库:< 50ms当前基线
- 新库:应该和老库差不多
告警:
- 新库响应时间 > 老库 2 倍
- 新库响应时间 > 100ms
```
#### 慢查询
```
老库慢查询数old_db_slow_query_count
新库慢查询数new_db_slow_query_count
阈值:< 10 次/分钟
告警:> 100 次/分钟
```
#### CPU 使用率
```
老库 CPUold_db_cpu_usage
新库 CPUnew_db_cpu_usage
阈值:< 70%
告警:> 80%
```
#### 连接数
```
老库连接数old_db_connection_count
新库连接数new_db_connection_count
阈值:< 最大连接数的 80%
告警:> 最大连接数的 90%
```
---
### 3. 数据一致性监控
#### 数据校验不一致率
```
指标data_inconsistency_rate
计算:不一致数量 / 抽样总数 * 100%
阈值:< 0.1%
告警:> 1% 告警
```
#### 数据迁移进度
```
指标migration_progress
计算:已迁移数量 / 总数量 * 100%
展示:实时进度条
```
#### 数据迁移失败率
```
指标migration_fail_rate
计算:失败数量 / 总数量 * 100%
阈值:< 0.1%
告警:> 1% 告警
```
---
### 4. 灰度读取监控
#### 新库读取成功率
```
指标new_db_read_success_rate
计算:成功次数 / 总次数 * 100%
阈值:> 99.9%
告警:< 99% 立即告警
```
#### 降级次数
```
指标fallback_count
计算:每分钟降级到老库的次数
阈值:< 10 次/分钟
告警:> 100 次/分钟 立即告警
```
#### 灰度流量占比
```
指标gray_traffic_percent
计算:新库读取次数 / 总读取次数 * 100%
预期:应该等于配置的灰度比例
告警:偏差 > 10%
```
---
### 5. 业务指标监控
#### 订单量
```
指标order_count
计算:每分钟订单数
基线:迁移前的平均值
告警:下降 > 20%
```
#### 支付成功率
```
指标payment_success_rate
计算:支付成功次数 / 支付总次数 * 100%
基线:迁移前的平均值
告警:下降 > 5%
```
#### 接口错误率
```
指标api_error_rate
计算:错误次数 / 总次数 * 100%
基线:迁移前的平均值
告警:上升 > 2 倍
```
---
## 监控大盘
### 阶段3双写阶段
```
核心指标:
- 双写成功率
- 补偿队列长度
- 新库 QPS
- 新库响应时间
次要指标:
- 老库 CPU/连接数
- 新库 CPU/连接数
```
### 阶段4数据迁移阶段
```
核心指标:
- 迁移进度
- 迁移失败率
- 老库 CPU/IO
- 新库 CPU/IO
次要指标:
- 双写成功率
- 慢查询数
```
### 阶段6灰度读取阶段
```
核心指标:
- 新库读取成功率
- 降级次数
- 新库响应时间
- 业务指标(订单量、支付成功率)
次要指标:
- 灰度流量占比
- 新库慢查询
```
### 阶段7完全切换阶段
```
核心指标:
- 新库 QPS
- 新库响应时间
- 新库错误率
- 业务指标
次要指标:
- 新库 CPU/连接数
- 慢查询数
```
---
## 告警规则
### P0 告警(立即处理)
- 新库读取成功率 < 99%
- 双写成功率 < 99%
- 业务指标下降 > 20%
- 新库 CPU > 90%
### P1 告警30分钟内处理
- 补偿队列长度 > 10000
- 降级次数 > 100 次/分钟
- 新库响应时间 > 100ms
- 数据不一致率 > 1%
### P2 告警1小时内处理
- 慢查询数 > 100 次/分钟
- 新库连接数 > 90%
- 迁移失败率 > 1%
---
## 监控工具
### 推荐工具
- **Prometheus + Grafana**:指标采集和展示
- **ELK**:日志分析
- **Skywalking / Zipkin**:链路追踪
- **钉钉/企业微信**:告警通知
### 自定义监控
```java
// 示例:记录双写成功率
@Component
public class MigrationMetrics {
@Autowired
private MeterRegistry meterRegistry;
public void recordDualWriteSuccess() {
meterRegistry.counter("dual_write_success").increment();
}
public void recordDualWriteFail() {
meterRegistry.counter("dual_write_fail").increment();
}
}
```
---
## 监控检查清单
### 每日检查
- [ ] 双写成功率是否正常
- [ ] 补偿队列是否堆积
- [ ] 新库性能是否正常
- [ ] 业务指标是否正常
### 每周检查
- [ ] 数据一致性抽样校验
- [ ] 慢查询分析和优化
- [ ] 告警规则是否合理
- [ ] 监控大盘是否完善
### 灰度前检查
- [ ] 所有监控指标是否正常
- [ ] 告警规则是否配置
- [ ] 回滚方案是否准备好
- [ ] 值班人员是否到位
---
## 注意事项
1. **监控要全面**:覆盖数据库、应用、业务各个层面
2. **告警要及时**:关键指标异常立即告警
3. **大盘要直观**:一眼看出系统状态
4. **数据要留存**:至少保留 30 天,用于问题排查

View File

@@ -0,0 +1,209 @@
# 配置开关设计
## 配置项
```yaml
migration:
# 双写配置
dual-write:
enabled: false # 双写开关,默认关闭
# 读取配置
read:
from-new: false # 是否从新库读取,默认关闭
gray-percent: 0 # 灰度比例 0-100默认 0
# 补偿配置
compensation:
enabled: false # 补偿任务开关,默认关闭
```
---
## 各阶段配置
### 阶段0-2准备阶段
```yaml
migration:
dual-write:
enabled: false
read:
from-new: false
gray-percent: 0
compensation:
enabled: false
```
**说明**:所有开关关闭,线上逻辑不变
---
### 阶段3开启双写
```yaml
migration:
dual-write:
enabled: true # 开启双写
read:
from-new: false # 仍从老库读
gray-percent: 0
compensation:
enabled: true # 开启补偿任务
```
**说明**
- 写入同时写两个库
- 读取仍从老库
- 补偿任务处理失败的写入
---
### 阶段4-5数据迁移和校验
```yaml
migration:
dual-write:
enabled: true # 双写继续
read:
from-new: false # 仍从老库读
gray-percent: 0
compensation:
enabled: true
```
**说明**:配置不变,后台运行迁移脚本
---
### 阶段6灰度读取
#### 第1天1% 流量
```yaml
migration:
dual-write:
enabled: true
read:
from-new: true # 开启新库读取
gray-percent: 1 # 1% 流量
compensation:
enabled: true
```
#### 第3天10% 流量
```yaml
migration:
read:
gray-percent: 10 # 调整为 10%
```
#### 第5天50% 流量
```yaml
migration:
read:
gray-percent: 50 # 调整为 50%
```
#### 第7天100% 流量
```yaml
migration:
read:
gray-percent: 100 # 调整为 100%
```
**说明**
- 逐步放开新库读取流量
- 双写继续,保证数据一致性
- 观察新库性能和稳定性
---
### 阶段7完全切换
```yaml
migration:
dual-write:
enabled: true # 继续双写(反向,主写新库)
read:
from-new: true
gray-percent: 100 # 100% 从新库读
compensation:
enabled: true
```
**说明**
- 新库成为主库
- 老库作为备份继续双写
- 观察 1-2 周
---
### 阶段8下线老库
```yaml
migration:
dual-write:
enabled: false # 关闭双写
read:
from-new: true
gray-percent: 100
compensation:
enabled: false # 关闭补偿
```
**说明**
- 完全使用新库
- 老库可以下线
---
## 配置管理建议
### 1. 使用配置中心
- Nacos / Apollo / Spring Cloud Config
- 配置实时生效,无需重启
- 支持灰度发布
### 2. 配置版本管理
- 每次修改配置记录版本
- 支持快速回滚到上一个版本
### 3. 配置变更审批
- 配置变更需要审批
- 重要配置(如灰度比例)需要多人确认
### 4. 配置监控告警
- 监控配置变更
- 配置异常及时告警
---
## 回滚策略
### 从阶段3回滚到阶段2
```yaml
migration:
dual-write:
enabled: false # 关闭双写
compensation:
enabled: false
```
### 从阶段6回滚到阶段5
```yaml
migration:
read:
from-new: false # 关闭新库读取
gray-percent: 0
```
### 从阶段7回滚到阶段6
```yaml
migration:
read:
gray-percent: 50 # 降低灰度比例
```
---
## 注意事项
1. **配置变更要谨慎**:每次变更前确认影响范围
2. **灰度要渐进**:不要一次性放开太多流量
3. **监控要及时**:配置变更后立即观察监控指标
4. **回滚要快速**:发现问题立即回滚,不要犹豫