订阅更新

从EMR迁移到Databricks零故障——Hadoop生态迁移实战

Hadoop手册 第 13 题 约 8 分钟读完

本文目录
  1. 先说结论
  2. 为什么要迁移?——EMR的痛点
  3. 迁移方案:双写双读灰度
  4. 分批迁移策略
  5. SQL方言差异——最大的技术挑战
  6. 数据一致性校验——迁移的质量保障
  7. 迁移后的效果
  8. 面试高频追问
  9. 总结

先说结论

大规模Hadoop生态迁移的核心方法论是'双写双读灰度':不是一刀切换,而是让新旧系统并行运行一段时间,逐步迁移验证。关键步骤:① 评估兼容性差异;② 双写双读灰度方案;③ 分批迁移(按优先级排序);④ 数据一致性校验;⑤ 旧系统下线。整个过程花了约3个月。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

这篇是我职业生涯中最有成就感的项目之一。在某知名出海硬件品牌,我独立负责了从AWS EMR到Databricks的全链路迁移——100+个Spark作业、覆盖数仓全部ETL链路、零故障完成。这个项目不仅是技术挑战,更是方法论和风险控制的考验。面试大厂时讲这个项目经历,面试官通常会追问很多细节。今天把迁移的思路、方案和踩坑完整分享。

为什么要迁移?——EMR的痛点

痛点具体问题Databricks怎么解决
运维复杂NameNode高可用、DataNode均衡、YARN队列调优全托管,零运维
性能不够Hive on MR慢,即使用Spark也缺少AQE等优化Databricks Runtime内置优化
成本高集群按峰值配置,低峰期浪费自动集群、按使用量付费
协作差Notebook体验差,缺少版本控制Databricks Notebook+Repos
数据湖弱Delta Lake支持有限Delta Lake原生支持ACID/Time Travel

迁移方案:双写双读灰度

# 迁移方案的核心思路:双写双读
#
# 阶段一:双写(2周)
#   ETL作业同时在EMR和Databricks上跑
#   两边都写入S3(不同目录)
#   EMR写入: s3://data/warehouse/emr/
#   Databricks写入: s3://data/warehouse/dbr/
#
# 阶段二:数据校验(1周)
#   对比两边的输出结果
#   行数、聚合值、抽样数据是否一致
#   不一致的作业单独排查修复
#
# 阶段三:切读(1周)
#   下游报表和API切换到读Databricks的输出
#   EMR继续跑作为fallback
#
# 阶段四:下线EMR(确认稳定后)
#   停止EMR上的作业
#   保留集群1周做最后的数据备份
#   彻底关闭EMR集群

分批迁移策略

100+个Spark作业不可能同时迁移。我按优先级分了4批:

批次作业类型数量迁移周期风险
第1批独立的数据清洗作业(无下游依赖)30个1周低
第2批DWD层ETL(有下游但可重跑)40个2周中
第3批DWS/ADS层聚合作业(影响报表)25个2周高
第4批核心指标计算(影响业务决策)10个1周极高

原则:从风险低的开始,积累经验后再处理高风险的。第1批相当于练手——即使出问题也不影响下游。到第3、4批时方法论已经成熟了,处理起来更有信心。

SQL方言差异——最大的技术挑战

EMR用的是Hive SQL+Spark SQL,Databricks用的是Spark SQL+Delta Lake SQL。大部分SQL兼容,但约20%的作业需要修改:

-- 差异一:日期函数
-- EMR (Hive): date_sub('2024-01-15', 7)
-- Databricks: date_sub(DATE '2024-01-15', 7)
-- 或: current_date() - INTERVAL 7 DAY
 
-- 差异二:INSERT OVERWRITE
-- EMR (Hive): INSERT OVERWRITE TABLE t PARTITION (dt='2024-01-15')
-- Databricks (Delta): MERGE INTO 或 INSERT OVERWRITE(自动分区)
 
-- 差异三:维度表更新
-- EMR: UNION方式全量覆盖
-- Databricks: MERGE INTO(增量更新,更高效)
-- 我把原来的UNION改成MERGE INTO,代码量减少了70%
 
-- 差异四:Hive特有语法
-- LATERAL VIEW EXPLODE 在Spark SQL里用不同写法
-- Hive的UDF可能不兼容,需要改写成Spark UDF
 
-- 总结:100+作业中约20个需要修改SQL
-- 大部分是日期函数和INSERT语法的微调

数据一致性校验——迁移的质量保障

# 数据一致性校验脚本(简化版)
def validate_table(table_name, dt):
    emr_df = spark.read.parquet(f's3://data/warehouse/emr/{table_name}/dt={dt}')
    dbr_df = spark.read.parquet(f's3://data/warehouse/dbr/{table_name}/dt={dt}')
    
    # 1. 行数校验
    assert emr_df.count() == dbr_df.count(), f'Row count mismatch!'
    
    # 2. 聚合值校验
    for col in numeric_columns:
        emr_sum = emr_df.agg({col: 'sum'}).collect()[0][0]
        dbr_sum = dbr_df.agg({col: 'sum'}).collect()[0][0]
        assert abs(emr_sum - dbr_sum) < 0.01, f'{col} sum mismatch!'
    
    # 3. 抽样校验(随机抽1000行对比)
    # ...
    print(f'{table_name} dt={dt}: PASSED')

我对每一批迁移的每张表都跑了这个校验脚本。100+个作业总共校验了约300张表的数据。发现了3个不一致的问题——全是SQL方言差异导致的,修复后重跑通过。

迁移后的效果

维度迁移前(EMR)迁移后(Databricks)提升
ETL总执行时间5-6小时3小时减少40%
查询延迟平均30秒平均9秒降低70%
月成本~5万美元~3.5万美元降低30%
运维工作量每周约10小时每周约4小时减少60%
存储成本~2万美元~1.3万美元降低35%(Delta压缩+Z-Ordering)

面试高频追问

追问一:迁移过程中最大的风险是什么?

数据不一致。如果新旧系统产出的数据不一样,下游报表和业务决策就会出错。这比作业失败更可怕——作业失败会报错,数据不一致可能静默地产生错误结果。所以数据校验是迁移最重要的环节,我在每一批迁移中都投入了30%+的时间做校验。

追问二:有没有迁移失败回滚过?

有一次。第2批迁移中有一个作业因为Hive UDF在Databricks上不兼容导致输出结果少了一列。校验时发现后回滚到EMR版本,修复UDF兼容性后重新迁移。这就是双写双读的好处——EMR一直在跑作为fallback,随时可以切回去。

追问三:迁移需要停服吗?

不需要。双写双读方案的核心优势就是零停服——新旧系统并行运行,切换是渐进式的。下游业务方几乎感知不到迁移的发生,他们只是某一天开始从Databricks的输出目录读数据而已。

总结

Hadoop生态迁移面试讲清楚四个关键点:① 迁移动因(EMR的痛点和Databricks的优势);② 迁移方法论(双写双读灰度,分批迁移);③ 技术挑战(SQL方言差异、数据一致性校验);④ 量化效果(ETL减少40%、查询降低70%、成本降低30%)。这是一个能讲15-20分钟的完整项目故事,大厂面试非常喜欢。

下一篇聊存储选型:HDFS、S3、OSS到底该用哪个?存算分离是大趋势吗?

你们有做过大数据平台迁移吗?遇到了什么挑战?评论区聊聊~

关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器