ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

自建Hadoop迁移MaxCompute最佳实践:从成本评估到灰度切换

自建Hadoop迁移MaxCompute最佳实践:从成本评估到灰度切换

如果你也经历过凌晨三点被 DataNode 磁盘写满的告警叫醒,起来手动做副本均衡,大概率能理解为什么一提到“迁移上云”,整个数据组的人都两眼放光。作为一个刚把企业自建 Hadoop 集群迁移到 MaxCompute 的参与者和复盘者,这一路踩过的坑、验证过的方法和最终沉淀下来的流程,我认为值得单独写一篇完整记录。

先说清楚本文能带来什么。它不是一份操作手册式的命令清单,而是围绕“企业自建 Hadoop 迁移至 MaxCompute 最佳实践”这件事,从成本评估、迁移前摸底、数据搬运、作业改造、灰度切换、上线后调优六个阶段展开,覆盖了你在正式动手前最容易忽略的问题:哪些数据一定要迁、哪些作业根本不需要迁、Hive SQL 会在哪里翻车、双跑到底要跑多久、回滚条件怎么定义。

适合谁来读?一类是正在背 Hadoop 运维包袱、想找个稳妥出路的工程师;另一类是已经定了迁移计划、但不确定自己盘点得够不够全面的数据团队负责人。读完你会发现,迁移的真正难点从来不是“把文件搬过去”,而是搬完之后能不能让业务方毫无感知地继续跑。

1. 自建 Hadoop 集群的隐性负债:这笔账值得先算清楚

很多人把迁移上云的动机理解成“听说云上便宜”,这个认知是错的。自建 Hadoop 迁到 MaxCompute 的决策,通常不是因为云上存储单价更低,而是因为自建集群的隐性负债已经高到影响业务迭代速度了。这笔账,最好在立项前就算明白。

1.1 三副本不是存储成本,而是三倍账单

HDFS 默认三副本机制保证了数据可靠性,但代价是实际存储量是有效数据的 3 倍。举例来说,如果你的仓库里有效数据约 500TB,HDFS 物理占用往往是 1.5PB 左右。如果你做了二级压缩,这个比例会小一些,但在绝大多数没有系统治理过的集群里,三副本就是实打实的三倍账单。

具体算一笔账:假设单个存储节点的综合成本——包含整机采购、机柜、电费、三年维保均摊——每 TB 大约在 1200 到 2000 元之间,取中间值 1500 元,1.5PB 节点成本约为 225 万元。而且这笔钱是固定的,哪怕你的集群每日实际计算量只有 20%,存储成本依然按峰值规划扣除。

更让管理团队头疼的是硬件更新周期。机器三年一换,每次扩容都要重新走采购流程。如果业务刚好赶上大促或临时分析需求,等机器到货,需求已经过去了。云上 MaxCompute 这种按量付费的存储计算分离架构,正好消掉这部分资源等待成本。这也是我推荐在立项汇报里直接用“三年 TCO 对比”而不是“单 TB 价格对比”的原因——后者反而会得出自建更便宜的误导结论。

1.2 运维长尾:小文件、NameNode 告警和退役节点

真正让我下定决心迁移的,不是存储账单,而是日常运维的琐碎程度。以 NameNode 为例,每个 HDFS 文件或目录的元数据大约占用 150 字节内存,听起来不多,但当你的集群里积压了上亿个小文件时,NameNode 堆内存就会被吃到几十 GB,Full GC 频繁,集群出现“活着的假死”状态。

我经历过最夸张的一次:某个日志采集任务每天生成 200 万个小文件,光文件数就把 NameNode 拖垮了。你去排查时,第一反应是让上游做小文件合并,但合并本身又会引出一轮新的资源争抢。

节点退役也够折腾。退役一个 DataNode,不是直接把节点下线就行,需要先调整副本因子,等待数据复制完成,再手动确认该节点没有承载任何 Block,整个过程快则几小时,慢则一个工作日。如果退役操作赶上了跑批高峰,还可能影响任务 SLI。所以很多团队干脆不敢做节点置换,硬件故障了就原地维修,集群架构越来越“僵尸化”。

这些运维成本有一个共同特点:平时不会出现在任何一张采购账单里,但会持续吞噬工程师时间。迁移到 MaxCompute 之后,节点管理、磁盘均衡、NameNode 内存调优这些事情全部从工作清单里消失,省出来的精力可以投回业务模型优化上。

1.3 什么样的情况才真正适合迁 MaxCompute

不是所有自建 Hadoop 都该迁。我自己的判断标准是三条:

  • 存量作业以离线批处理为主,占比超过七成。
  • 数据规模在几十 TB 到数 PB 之间,且增长曲线平稳。
  • 团队对 Hadoop 底层原理的掌握程度一般,多数靠维护文档和社区经验在支撑。

反过来,如果你的业务强依赖 HBase 做高并发点查、日常有大量上千并发的 Adhoc 查询,或者大量作业使用了非常底层的 MapReduce API 且无人能重构,我建议先把这些场景单独摘出来,评估是否保留一部分自建集群,只迁移可替换的部分。迁移不是“要么全走、要么全留”的选择题,而是“把非核心、高运维成本的部分先交出去”的策略。

2. 动手前的家底盘点:数据、任务、依赖一个都不能漏

迁移最怕什么?最怕等到切换那天才发现某个上游表没迁、某个调度任务还在读旧集群路径。所以迁移前两周,不建议碰任何迁移工具,先把家底摸清楚。

2.1 数据盘点:量和热度分开统计

数据盘点不能只看总大小,要把“存储量”和“热度”分开统计。有些表几 TB 但三个月没人查一次,属于典型的冷数据;有些表只有几百 GB,却是十几个核心任务的上游,优先级完全不同。

我的做法是先按目录层级统计:

# 查看各业务库的总体积 hdfs dfs -du -h /data/warehouse | sort -hr | head -50 # 查看某个表目录下的文件数量 hdfs dfs -count -v -h /data/warehouse/dw_order 输出里的 file count 和 dir count 要特别注意,它能直接告诉你这个小文件问题藏在哪张表里。

热度信息可以从两个渠道拿:一是 Hive 元数据里表的最后访问时间,二是调度平台里任务的血缘关系。后者更可靠,因为有些表虽然被调度任务引用,但任务本身已经停跑了,这类表可以直接进入“暂不迁移”清单。

最终输出一张盘点表,字段至少包括:业务域、表名、存储量、文件数、最近访问时间、上游源系统、下游消费任务数、热度等级。这张表是后面制定迁移顺序的唯一依据,没有它,后续所有工作都会变成拍脑袋。

2.2 作业清单与血缘梳理:没人能靠记忆搬迁上百个任务

如果团队超过三个人,我不建议靠任何人的脑子来梳理作业。直接从调度平台导出全部任务 DAG,再配合资源管理器的历史 Application 列表,能还原出九成以上的实际作业情况。

需要登记的信息有:任务名、任务类型(Hive SQL、Spark、MapReduce、Shell、Flink)、调度周期、依赖的上游表、产出的下游表、影响到的报表或接口、负责人。

这里我踩过一个教训:有一类任务平时根本不跑,只在月底补数据时通过临时脚本触发,结果盘点时被漏掉了。等我们完成核心链路切换,月底跑数才发现数据是空的,又倒回去重新补迁。后来我们规定:凡是能在调度平台里找到运行记录、脚本目录里存在但平台没纳管的流水账作业,也要人工补充登记,宁可重复不可遗漏。

血缘梳理还有一个好处:能帮你识别哪些表是“脏数据中转站”。如果一张表只被一个任务读、且该任务每次都全量覆盖,大概率是临时中间表。这类表根本不需要迁移,跑完主链路后在 MaxCompute 里临时建一张就行,可以大量减少搬迁体积。

2.3 兼容性预检:Hive SQL 迁移前做一次“体检”

MaxCompute 的 SQL 语法在 2.0 之后对 Hive 有较高兼容度,但“较高”不等于“完全一致”。迁移前建议先做一次静态扫描,把存量 SQL 里容易翻车的写法全部标记出来。

我在预检中归纳出的高发差异点有三类:

  • 自定义 SerDe:Hive 里常用 RegexSerDe、MultiDelimitSerDe 解析非结构化日志,而 MaxCompute 原生对这类自定义序列化方式支持很弱,往往需要改用 SQL 内置函数或 UDF 重写。
  • 动态分区写入:Hive 里INSERT OVERWRITE TABLE t PARTITION(dt) SELECT ...配合动态分区参数使用非常普遍,MaxCompute 的语义和限制不同,特别是分区数量过多时直接报错。
  • 内置函数细节:比如hash()、pmod()这类函数的边界行为和 Hive 有微妙差异,日期格式化函数在不同版本里的返回格式也可能不同。

比较好的做法是,把预检发现的每一条差异都记录到一张“兼容性问题清单”里,标注是“语法差异”“函数差异”还是“功能缺失”,后面作业改造阶段就按这张清单逐条处理,不用反复试错。

2.4 带宽和时间窗口的简单推算

评估迁移工期前,先算物理上限。假设要迁 200TB 有效数据,迁移窗口 48 小时,专线带宽 1Gbps。理论上 1Gbps 每秒约 125MB,200TB 需要约 20010241024/125 ≈ 167 万秒,约 465 小时,显然不够。

所以真正的问题不是“用多少带宽”,而是“迁移的数据量能不能先降下来”。这里两个思路最有效:一是只迁热数据,冷数据走离线介质;二是先做数据清理,把已经过期且无下游依赖的临时表直接删掉,我见过不少集群清理后能直接砍掉 30% 的搬迁量。

如果必须全量搬迁,那就要在设计阶段明确:专线带宽至少 10Gbps,或者拆成多轮窗口,分批迁移,每批做完校验再迁下一批。总之,先算账再干活,比上线后临时调带宽靠谱得多。

3. 数据迁移管道的选择与校验:全量、增量、对账

数据迁移是整件事里最机械、但最不能出错的环节。机械在于流程固定,不能出错在于一旦数据少了一个分区,下游报表可能隔天就出问题。

3.1 历史数据全量迁移的三种常见做法

根据数据量和网络条件,历史数据迁移通常有三条路可以选:

方式适用场景优点缺点
数据传输工具直拉 HDFS网络条件好、数据量中等全程可视化、断点续传源端频繁扫描会影响 HDFS 读写
先转 Parquet 再经对象存储中转数据量大、需要归档保留压缩率高、传输稳定可重试多一步中间过程,增加一天左右时间
离线介质搬运单次数十 TB 以上且网络带宽不足不受带宽限制、适合冷数据周期长,硬件成本需要单独评估

第一种方式适合数据量在几十 TB 以内、网络延迟和带宽都有保障的场景。第二种方式我实际用下来最稳妥:先把 HDFS 上的数据导出成 Parquet 格式,传到对象存储,再用 MaxCompute 外表方式直接读取并写入正式表。Parquet 的列式存储不仅压缩率高,传输时的丢包重试成本也低,因为中间产物在对象存储上是永久存在的,失败了直接从断点继续,不需要重跑源端数据导出。

3.2 增量同步:卡住时间窗口的不是管道,而是源端扫描

全量迁移做完之后,紧接着就是增量同步。对日志型数据(例如访问日志、埋点日志),我推荐按分区追平:先把历史分区补齐,再在上游链路里直接切换输出到新平台。这个方案最简单,也最容易验证——每个分区的数据条数是否一致,一眼就能看出来。

麻烦的是有更新操作的业务表。Hive 里如果采用“按天全量快照”的方式,那还好办,每天把当天快照分区同步过去即可。但如果源表是反复 update 的 HBase 或 MySQL 同步表,就需要引入实时同步管道,通过主键或者 binlog 变更事件同步到 MaxCompute。这里要提醒一下:MaxCompute 本身不对主键做强制约束,需要你在建表时设计好“主键 + 分区 + 去重”的模型,同步任务写出前做一次去重,不然数据重复会让下游 sum 类指标悄然翻倍。

还有一个容易忽略的点:增量同步任务要在源集群高峰时段避开读取。可以设置限流,或者把同步调度放在业务低峰期,避免大量读操作影响源 HDFS 上还在跑的保留任务。

3.3 数据校验:行数对齐只是起点

我见过很多团队的校验方案就是“数一下行数一样不”,然后做完就宣布迁移成功。行数一样不够,因为 NULL 值的分布、重复记录、枚举值漂移都可能让行数相同但数据内容不同。

我实践下来比较可靠的组合是这样:

-- 校验一:基础行数 SELECT COUNT(*) FROM new_table WHERE dt = '2025-01-01'; -- 校验二:核心键去重数 SELECT COUNT(DISTINCT order_id) FROM new_table WHERE dt = '2025-01-01'; -- 校验三:关键指标求和 SELECT SUM(order_amount) FROM new_table WHERE dt = '2025-01-01';

三个口径在源集群和新平台各跑一遍,结果逐一对比。SUM 类指标对重复数据非常敏感,一旦重复,sum 会有明显偏差,比单纯行数对比可靠得多。

校验结果建议每天自动生成一张“数据同步校验表”,字段包括:表名、分区、源集群行数、新平台行数、差异率、校验状态。差异率阈值一般定在 0.1% 以内,超过就直接拦截切换流程。我习惯在这个环节加一个“连续三天校验通过才允许切生产”的硬性要求,短时间跑对不算对,稳定才算。

3.4 小文件合并,越早做越省心

前面提到源集群已经积累大量小文件时,一定要在数据导出前做一次合并。否则一个只有 1GB 的分区,在 HDFS 里可能是几千个 1MB 的小文件,导出的 Parquet 也会继承这种碎片化特征,进入 MaxCompute 后扫描效率非常差。

合并方法不复杂,用一个 Spark 作业按分区读取源表,重新写出时把目标文件控制在 128MB 到 256MB 之间。唯一要注意的是合并任务本身会消耗大量源集群 CPU,最好放在业务低峰期执行。

我吃过一次亏:有一个分区因为合并中途任务失败,三个小时没发现,导致后续增量同步一直追不平,最后只能重刷那一个分区。所以合并任务要做监控,原则上每个合并作业结束之后都要检查目标文件数是否符合预期。

4. 作业迁移中最容易被低估的摩擦:SQL 差异与 UDF 改造

数据搬过去了,作业跑不起来或者结果对不上,才是迁移项目的真正分水岭。很多人以为“SQL 是通用的,复制过去改个连接串就行”,实际上一跑全是泪。

4.1 Hive SQL 语法差异清单

我整理一下自己迁移时遇到最多、也最容易让新手卡壳的几个差异点。

第一个是explode配合lateral view的写法。Hive 里很常见的:

SELECT id, tag FROM t LATERAL VIEW EXPLODE(SPLIT(tags, ',')) tmp AS tag;

在 MaxCompute 里大体能兼容,但如果源数据里 tags 字段存在空值或分隔符不一致,结果会有细小的差异。建议写完后专门用边界数据做几条用例对比,不要只拿正常数据测试。

第二个是动态分区。Hive 里用动态分区写数据,要先打开hive.exec.dynamic.partition=true,然后在 SQL 里省略分区列。MaxCompute 支持动态分区,但对单次写入的分区数有限制,如果源表的日期列跨度特别大,一次写入几百个分区,任务会直接失败。解决办法是加一层“按月份分桶”的处理,把一个宽时间跨度的写入拆成多个子任务,每个子任务只处理一个月的数据。

第三个是timestamp精度和时区。Hive 里CURRENT_TIMESTAMP返回的时间往往跟随集群时区,MaxCompute 默认是 UTC 存储、展示层可以转本地时区。如果你的报表是按东八区统计每日数据的,迁移后必须显式转换,不然所有按天分区的指标都会整体偏移 8 小时。这个坑隐蔽,而且一旦上线很难自查,我建议在预检阶段就把所有“日期时间函数使用清单”统一列出来,逐条人工确认时区逻辑。

4.2 自研 UDF 的迁移与替代方案

UDF 是迁移中“每看一个都头疼”的东西。原则是:能不用就不用,能用 SQL 实现就绝不写代码。比如很多 UDF 只是做字符串拆分、正则匹配、JSON 解析,MaxCompute 的内置函数基本能覆盖,直接用 SQL 重构更稳定。

确需保留 UDF 的场景,优先考虑 Python UDF,改动成本低:

from odps.udf import annotate @annotate("string->string") class ParseLog(object): def evaluate(self, line): # 这里写你的解析逻辑 return line.strip().split('\t')[1]

Java UDF 也能迁,但要注意依赖冲突,特别是带了一堆第三方包的 Hive UDF,直接打成 fat jar 传到新平台,经常遇到类冲突。我的建议是重写时精简依赖,只用最核心的 SDK 和工具类,其他能用平台内置库替换的就替换掉。

另一个容易踩的坑是 UDF 的 NULL 语义。Hive UDF 里处理 NULL 的方式和 MaxCompute 有一定差异,有的 UDF 对 null 入参返回 null,有的返回空字符串。迁移后建议给每个 UDF 补充一张“入参-出参”用例表,把 null、空串、全角空格这些边界情况都跑一遍,别想当然。

4.3 Spark/MapReduce 作业怎么处理

Spark 作业相对好办一点,MaxCompute 提供了云端 Spark 运行环境,开源自研的 Spark 作业基本可以不改代码直接提交。但这不代表零成本:依赖版本、资源规格、日志采集方式都可能不同,至少要在测试环境完整跑通几个代表性作业再批量提交。

MapReduce 是最痛苦的。一个用原生 MR API 写出来的作业,迁到 MaxCompute 上大概率不能直接运行。如果这类作业数量少,可以改写为 Spark 或 SQL;数量多且逻辑复杂,就要和业务方坐下来聊,到底有没有必要保留这些老逻辑。

我参与的项目里有一个用了五六年的 MR 任务,负责清洗日志并生成分桶表。最后我们说服业务方用一段 SQL 加一个 Spark 作业重写了整个流程,跑出来的结果和旧任务完全一致,但运行时间从 40 分钟降到 8 分钟。所以遇到 MR 任务别急着迁,把它当成一次重构机会反而更划算。

5. 上线切换:双跑、灰度、回滚到底怎么排

很多人把迁移项目当成一个技术项目,其实到切换阶段它已经变成了一个风险管理项目。核心目标不是“切得越快越好”,而是“任何时刻都有回头路”。

5.1 双跑不等于双写,先对齐输出口径

双跑指的是新旧两套平台并行运行同一套任务,产出结果互相对比,但前提是数据管道不能双写。如果两条链路同时写入下游同一张结果表,报表会重复计算,数值直接翻倍。

正确做法是:新平台的任务在独立项目空间运行,结果落到独立的校验表;每日定时跑一个对比任务,把新旧两个平台的关键结果表做差集和量级对比。连续跑够至少一个完整业务周期——通常是 7 天——且每天差异都在阈值内,才算双跑验证通过。

双跑期间有几个真实场景要留意:补数据任务怎么双跑、节假日调度怎么双跑、上游接口临时改动怎么双跑。一个比较实用的办法是:对比任务只认结果表,调度任务本身沿用同一张日历表,旧平台跑完触发新平台跑,新平台跑完触发对比任务,这样能避免两边由于调度时间差导致的空窗。

5.2 先低峰后核心,按链路倒序切换

切换顺序我建议按“影响范围从小到大”来排,而不是按“技术复杂度从低到高”来排。

批次切换内容说明
第一批临时表、中间结果表失败影响面最小,用来验证链路稳定性
第二批报表类下游任务供业务验证数据口径,风险相对可控
第三批核心 T+1 批处理链路影响最大的主链路,放最后
最后近实时小时级链路接入实时同步管道,确认无误后再切

每批次之间至少间隔两到三个完整运行日,不要当天早上切一批、下午就切下一批。给每一批都定义明确的“通过条件”,例如连续两天差异率为 0、任务失败重试次数小于 2、耗时不超过旧集群的 1.3 倍。满足条件再走下一批,否则停下来分析。

5.3 回滚预案要写进值班手册

回滚预案不能只是“数据还在旧集群,应该能切回去”这种口头交代,它必须是一份可执行的操作单。

我习惯把回滚条件列成三条硬指标:核心任务连续失败超过 5 次、数据差异率超过阈值且无法在 2 小时内定位、任务延迟超过业务 SLA 一倍以上。满足任意一条,当班负责人在不打扰更高级别审批的前提下,直接启动回滚。

回滚动作包括:把调度平台上的任务切回旧集群、停止增量同步管道、恢复旧集群数据表的读权限、通知下游业务方数据源已回切。每一步都要有具体负责人和预计操作时长。

一批切换完成后,旧集群不要马上释放。我建议保留至少 30 天的只读状态,如果条件允许,保留 90 天再做物理下线。因为有些“一个月才跑一次”的月底报表,很可能在切换一个月后才第一次被触发,那时才发现问题,旧集群还在的话就还能补救。

6. 上线后的第一天到第一个月:慢查询与成本账单的再调整

切换完成并不代表项目结束。新平台跑起来之后,第一周看稳定性,第一个月看成本和性能,这时候才真正体现出“迁移最佳实践”和“迁移完成”的区别。

6.1 慢作业排查:倾斜和膨胀优先

新平台慢作业的原因,和自建集群有相似也有不同。最常见的是两类问题:数据倾斜和全表扫描。

数据倾斜的典型表现是,Map 阶段很快,Reduce 阶段有个别长尾任务,整个作业卡在最后几个 Task 上下不来。遇到这种情况,我会先看关联键的值分布,找出那些特别大的 Key——比如某个店铺 id 占了全表百分之四十的订单量。调整手段有两种:一是给关联键加/*+ SKEWJOIN(表名(关联键)) */提示,让平台自动将热点 Key 拆分到多个 Reduce 处理;二是人工过滤,把热点 Key 单独提取出来做一轮广播关联,然后再和正常数据 union 回来。

全表扫描的问题主要出在分区裁剪没生效。一个按天分区的订单表,查询时如果用函数包裹了分区列,例如WHERE DATE_FORMAT(dt, 'yyyy-MM') = '2025-01',分区裁剪就会失效,变成扫全表。改成WHERE dt >= '2025-01-01' AND dt < '2025-02-01'后,扫描量可能直接降一个数量级。这类优化收益大、改动小,建议上线第一周把 Top N 慢作业的 SQL 全部过一遍分区条件。

6.2 配额与存储治理:别让成本曲线反向起飞

迁移上云之后,成本从“固定采购”变成了“弹性账单”,如果没人管,月底对账时会被吓一跳。

计算资源方面,我的建议是给不同业务域划分不同的资源配额。跑批类任务使用包年包月配额,保证固定时段内的计算能力;即席查询和分析类任务使用按量付费配额,避免高峰期互相挤兑。这就像给一个家庭的用电分成了“基础生活用电”和“临时大功率用电”,两类分开计费、分开管控,账单才清晰。

存储方面要重点治理两类东西:一类是临时表,很多任务会创建中间结果表,跑完就不管了,如果建表时不设置生命周期,它就一直占空间;另一类是未清理的备份表,迁移过程中的中间数据如果没有设清理策略,也会在账面上持续产生费用。

上线第一周我就建议做一次全项目空间的存储扫描,把大文件、无生命周期的表、一个月没被读取的表全部列出来,和业务方确认后统一治理。这个动作不是为了省多少钱,而是让后续的账单归属明确,每个项目空间都能对应到具体的业务方,不然成本根本无法追溯。

6.3 我踩过的几个坑,以及现在会怎么做

回顾整个迁移过程,有四个坑是我认为最有代表性、也最值得提醒后来者的。

第一个坑是“迁移完成就清理源集群”。当时有一张维度表,迁移时我以为全量同步已经覆盖全部历史分区,就把源端删了。结果一个月后业务方跑同比分析,需要两年前的某个分区,而该分区在迁移时因为源端已经损坏没有被扫描到,数据彻底丢了。从那以后,我要求任何数据删除都要等三个完整业务周期,并且删除前必须和消费方逐条确认。

第二个坑是 Python UDF 的沙箱环境。开发环境跑得好好的解析函数,部署到生产环境后开始报错,折腾半天发现是第三方库版本不一样。解决办法是在项目里固定 requirements,并且把运行环境的兼容性测试纳入上线流程,不能只测功能不管环境。

第三个坑是调度依赖没有完全对齐。新平台的周期任务初始配置时,我把两个原本存在隐式依赖的任务设成了同周期并行。结果某个早上,下游任务先跑完读到了空分区,导致报表数据缺失,而旧集群因为有先后顺序从未出过问题。表面看是调度配置问题,本质是血缘梳理阶段没有把这些“隐性依赖”找出来。所以我会特别强调,盘点血缘时,不仅要看显式依赖,还要看任务之间是否存在时间顺序约定。

第四个坑是资源配额规划过小。迁移初期为了控制成本,给核心项目空间只配了较小的包年包月资源,结果第一个月底报表高峰期任务排队严重。后来把配额上调了一半,任务立刻恢复流畅。经验是:第一次配置时宁可让账单偏高一点,也要保证跑批稳定性,稳定后再根据实际使用曲线逐步下调。成本优化是持续动作,不是上线当天就能一步到位的。

如果让我做第二次迁移,我会把更多时间放在前两周的数据治理而不是搬迁本身。先把该清理的临时数据清掉、把小文件合并完、把作业依赖彻底盘清,后面所有环节都会顺利得多。这也是我在本文开头说“迁移难点从来不是把文件搬过去”的原因——搬,只是力气活;搬得干净、搬得安心,才是真正考验功力的地方。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进