简历 preview
简历上 : 支持一套通用的同构数据不停机迁移方案, 支持全量和增量校验 使用 kafka 进行减轻数据库压力 并且动态的根据数据库状态进行切换挂载和运行
方案描述 :
由于我在拆分了 点赞、阅读、收藏相关的微服务, 考虑 微服务中 一个服务一个数据库进行数据隔离。从而实现了一套数据迁移方案 。 因为不修改原有数据存储架构,所以采用同构的方案 , 并且考虑这个服务属于关键服务,因此选用不停机迁移方案
考虑在 100w条数据的情况下,如果进行 校验后立即进行修复会给数据库带来很大的负担因此使用 kafka 进行削峰的处理
另外通过额外重写 gorm 中 connPool 的exec、prepare、query Func 实现 双写
并且通过重写 Commit 和 Rollback 实现双写的事务控制
困难点和改进 :
-
引入 kafka 进行异步的优化 全量校验与修复的过程 。
-
优化单条校验的逻辑 采用批量校验的逻辑。 并且考虑 硬删除 的业务场景,在校验 原表和目标表的 条件下,同步进行 目标表和原表的 差异校验 防止硬删除产生的不一致问题
-
支持使用者动态切换 数据迁移
原表only,读原表写目标表,读目标表写原表,目标表only的配置 -
支持根据数据库状态,判断是否高负载从而判断是否要挂载校验任务 。 并且通过 context cancel() 实现,尽可能只有同一个 全量/增量 校验程序在运行
缺点 :
-
因为 ConnPool 返回值 sql.Result 并不暴露 Error 的设置,所以对于双写的错误并不能很好的暴露出来,只能进行打log和监控
-
事务控制的实现并不能保证一致性,只能做到主表最大可控,但是对于目标表如果失败了 只能等待全量校验与修复
不停机迁移数据
相比较于 停机迁移数据, 主要的困难点在于 一边迁移 一边有新数据产生
并且因为我们切换 原表和目标表 的时候,如果运气不好会导致出现一些数据不一致。 不停机数据迁移很难做到 最终数据一致性
数据校验
为了防止重复写一些 dirty code, 放弃在 dao层维护两个数据库的思路
重建了一套通用的双写逻辑。 由业务方提供 equal 的方法 , 对于某些校验不严格的业务方可以考虑
不需要 time 就可以认为 equal 以及自定义精度误差等等
流量控制 和 性能优化
-
在数据库高负载的情况下会自动挂起全量校验 只有当数据库低负载的时候才会进行
-
尽可能多的进行 异步处理 和 并发处理 。 对于全量数据与校验 采用异步处理, 对于 目标表和原表的校验 以及 目标表和原表的差异校验 采用异步处理的方式进行
面试题
Q: 不停机迁移的基本步骤是什么
-
数据初始化,完成首轮数据的同步 和 数据库表的建立 。 对于 mysql 可以使用 mysqldump 进行同步,如果是异构数据的话,可以考虑内部批量轮询的方式进行首次同步
-
这时候可以考虑启用全量校验进行一次数据的校验与修复
-
读取并写入原表 同时 写入目标表 。 同时进行 全量校验与修复
-
写入并读取目标表 同时写入原表 。 同时进行全量校验与修复 如果业务稳定可以考虑只运行增量校验
-
完全使用目标表
Q : 你的数据校验方案是什么
-
支持 全量的数据校验和增量的数据方案 。 通过用户是否传递 utime + sleepTime 考虑走的是全量校验还是增强校验
-
同步的进行 原表和目标表的校验 以及 目标表和原表的差异 检查 。 批量获取原表的数据 并且批量的获取目标表的数据,使用业务方提供的 equal method 进行比对 ,如果存在不想等的 在轮询完成之后批量通过 kafka 发送给下游修复 。 批量获取目标表的数据,并且检查是否在原表存在,如果不存在同时发送对应的 event 给下游
Q : 你的数据修复方案是什么 ? 如何保证数据正确性? 怎么解决并发问题 ?
-
使用 kafka 进行异步的通知修复 。 kafka 仅仅只是做触发器,并不存放detail信息用于实际修复 。
-
对于数据修复情况只会有3种场景,target 不存在 那么需要insert,not equal 需要进行 update, base_missing 则需要删除 。 考虑 insert & update 的并发问题,使用 upsert 进行控制
-
并不能够在单词修复保证数据的正确性,数据的正确性最终交由多次校验与修复来控制
Q : 在数据迁移的每个阶段,你是怎么考虑保护着数据库的
-
尽可能的进行 批量操作 。 批量的查询数据库,本地机器进行比对
-
使用 kafka 进行异步的校验与修复
-
考虑 调度时机进行 校验任务的运行 , 对于数据库高负载的情况 挂载正在运行的任务
Q : 如果 kafka 瓶颈了怎么办,消息积压了怎么办?
-
优化消费者。 尽可能改成批量消费
-
并行处理数据库修复流程
Q : 为什么 你要使用 Kafka 直接校验之后修复数据不行吗
- 直接进行修复数据 , 会给数据库带来很大的负担 。 Mysql 单库的 读写有瓶颈,尽可能保证 大量的读和写操作不同时进行
Q: 增量校验和修复、业务写数据、全量校验和修复同时进行,有什么并发问题 ? 怎么解决?
-
同时进行会带来更多的数据库操作,带来负担 。 并且我们在事务以及双写操作上必然会有并发问题,在我们切换 目标表和原表的时候 最终总会有不一致的情况 。
-
采用超时控制, 优化任务调度时间 。所有的不一致问题,最终都是由反复校验反复修复解决的
Q : 怎么保证在数据迁移的时候 不影响业务
-
调度时间的控制 。 在低负载的情况下进行
-
可以考虑在内部数据跑完几次全量校验之后 只开启增量校验,每次仅校验一周之内的数据
总分:62 / 100
按「2 年经验、能讲清一个核心项目」来评:能过初筛,但扛不住深挖。
评分拆解
| 维度 | 分数 | 说明 |
|---|---|---|
| 项目背景与动机 | 12/15 | 微服务拆库、同构不停机,动机清楚 |
| 方案完整性 | 14/25 | 四阶段迁移有框架,关键细节和边界含糊 |
| 技术深度 | 10/20 | 提到 ConnPool 双写、Kafka 削峰,但原理讲不透 |
| 问题意识与权衡 | 12/15 | 能主动说缺点,这点加分 |
| 面试表达与结构化 | 8/15 | 有 Q&A,但表述乱、有笔误、答不到位 |
| 与 2 年经验匹配度 | 6/10 | 选题够大,但「最终靠反复校验」像在回避设计 |
优点
- 选题合适:不停机迁移 + 双写 + 校验修复,是面试官愿意追问的「有难度」项目。
- 有诚实的缺点:ConnPool 错误难暴露、事务只能保主表——比空谈「强一致」强很多。
- 有业务抽象意识:业务方提供
Equal,比硬编码字段对比更像工程实践。 - 有保护库的意识:批量、Kafka 削峰、高负载挂起任务,方向对。
- 准备了面试题清单:说明有意识在「被问什么」。
缺点(面试里会被打穿的点)
-
核心一致性说不清
「切换时总会不一致」「最终靠反复校验」可以当结论,但不能当唯一答案。面试官会问:双写失败怎么回滚?阶段切换的窗口期如何缩小?源表为准 / 目标表为准时,修复方向怎么定? -
Kafka 用法站不住脚
「只做触发器、不带 detail」——那消费者靠什么修?再查一次库?查到的是哪一侧?积压时只说「批量消费 / 并行」,没有分区键、幂等、重试、死信、顺序。 -
并发问题答得空
业务写、全量校验、增量修复同时跑,只提「超时 + 调度」不够。应有:同一主键的冲突策略、upsert 的版本/utime 条件、校验批次与写路径的可见性。 -
双写实现太薄
重写 ConnPool / Commit / Rollback 是亮点,但文档几乎没展开:嵌套事务?只读语句?Prepare 缓存?目标库延迟?失败是「打日志继续」还是「业务失败」? -
表达与严谨性差
「挂载」应为「挂起」;「增强校验」应为「增量」;步骤编号重复;句子碎、逻辑跳。面试口述时会显得准备乱。 -
缺可量化结果
100 万量级提了,但没有:迁移耗时、校验一轮多久、峰值 QPS、不一致率下降、切换窗口多长。2 年经验项目,数据是加分项。
建议(按优先级)
1. 把故事讲成一条线(30 秒版)
背景(拆库)→ 约束(不停机、同构)→ 四阶段 → 双写怎么做 → 校验/修复怎么兜底 → 已知局限。每阶段说清「读谁、写谁、以谁为准」。
2. 补齐 5 个必追问答案(写到能口述)
- 双写失败:主成功副失败怎么办?是否影响接口返回?
- 事务:主提交、目标失败时数据状态与补偿路径
- Kafka:消息体设计、幂等键、消费失败重试、为何不直接同步修
- 硬删除:双向 diff 的具体算法(按主键批量 in-query)
- 切换:如何判断可以进下一阶段(不一致率、连续 N 轮全量通过)
3. 准备一组数字
例如:数据量、双写延迟、全量一轮时间、Kafka 吞吐、挂起阈值、最终不一致量级。
4. 把「反复校验」升级成「有界收敛」
说明:在「源为准」阶段修复方向固定;切换前要求不一致 < 阈值;切换后短窗口只开增量;为何认为会收敛而不是越修越乱。
5. 润色简历与口述
- 简历:一句话写清「四阶段双写 + 全量/增量校验 + Kafka 异步修复 + 负载感知调度」
- 去掉口语和错别字;每个 Q 控制在「结论 → 做法 → 权衡」三层
6. 区分「你做了什么」和「方案通用知识」
mysqldump 初始化、四阶段迁移是通识;面试官更想听你改 ConnPool、Equal 抽象、双向校验、挂起任务这些「你亲手做的」。
面试官结论
材料证明你做过这件事,也知道难点在一致性和库压力,作为 2 年经验的项目素材够用。但当前深度停在「知道概念 + 知道会有问题」,还不足以在中高级追问里稳住。
把一致性边界、Kafka 契约、双写失败语义、切换判定补全后,这份准备可以冲到 75–80;再加可量化结果和一次完整口述演练,才更接近「能让面试官点头」的水平。