先说说我自己的感受。搞数据平台这么多年,最烦的就是Spark跑批这件事:集群要提前养、内存要反复调、S3请求费像抽血一样一点点流失,等跑批稳定了,运维的活儿还没完。Amazon EMR Serverless Storage 这个新特性,算是把“无服务器Spark+分层存储”这条路彻底打通了,我实际迁移了一个日志ETL作业之后,账单相比传统EMR集群省了接近一半,官网口径更是直接说最高省55%。这篇东西我打算把当时折腾的完整思路、配置步骤、踩坑记录都整理出来,给正在纠结“要不要迁EMR Serverless”的同学一个参考。
先说清楚这个内容到底适合谁:团队正在用Amazon EMR自建集群跑Spark批处理,或者被S3请求费用折腾到怀疑人生,又或者压根不想再管主节点、核心节点、弹性伸缩这些基础设施,那么EMR Serverless Storage值得仔细看一遍。就算是刚接触AWS的朋友,只要对Spark有基本概念,这篇文章也能帮你少走弯路。
1. EMR Serverless Storage 到底解决了什么问题
1.1 传统Spark跑批:钱花在哪了,人累在哪了
先拆一下自建EMR集群的成本结构。假设你按需开一个10节点r5.2xlarge的集群,每节点4 vCPU、16GB内存,按区域价格折合每小时大约3到5美元,一个月跑300小时,光计算费用就是900到1500美元。这还只是“机器开着”的钱,实际跑批期间资源利用率能到70%就算烧高香了,因为Spark作业提交前后有启动和收尾阶段,节点空转是常态,不是你想省就能省的。
第二种成本更隐蔽,就是S3请求费。Spark跑ETL,最典型的就是读取源数据、shuffle中间结果、写最终结果。shuffle这个东西特别讨厌——reduce阶段要从所有mapper节点拉取中间数据,在传统EMR集群里,中间数据先写本地磁盘或内存,然后再网络传输,如果配置不当,大面积shuffle会瞬间打满磁盘IO,而EMR Serverless早期版本因为是无状态的,中间数据被迫落到S3,每次shuffle都是一堆GET/PUT请求,量一大账单立刻起飞。
第三种成本是运维人力。自建集群得盯版本升级、节点故障替换、Spark参数调优、安全组配置、IAM角色。就算任务都跑在EMR上,监控告警、扩容计划、资源争抢这些事也足够让一个数据团队疲于奔命。很多团队嘴上说“我们用Spark很顺利”,实际上日常都在给基础设施“擦屁股”。
1.2 Storage的核心思路:把“中间数据”从S3搬到本地
EMR Serverless Storage的关键变化,是给无服务器计算环境引入了本地磁盘缓存。听起来很基础对吧?但底层逻辑完全是针对上面那些痛点设计的。
传统EMR集群里,Spark的shuffle中间数据可以写本地磁盘,因为节点是固定的、生命周期长。而EMR Serverless的executor是动态创建销毁的,没有固定“本地盘”可以依赖,所以早期架构只能把所有中间数据flush到S3,保证executor哪怕被杀了数据也不丢。这个保守设计换来的是无状态弹性,代价就是shuffle延迟高、S3请求多、存储成本大。
Storage特性做的事情是:在每台计算实例上启用高性能NVMe本地盘,让Spark的shuffle数据、临时文件、部分RDD缓存可以优先写本地,而不是一上来就去S3。这样既保留了无服务器的弹性调度,又让数据在节点生命周期内尽量留在“热区”。从架构上看,数据不再全部走远端对象存储,而是“本地缓存为主,S3兜底”。
那为什么不彻底不用S3?因为本地盘是易失的,executor一旦被回收,上面的shuffle数据就没了,这时候上游必须从S3重新拉取。所以Storage并不是推翻S3,而是把存储分成了“热”“温”“冷”三层,让中间数据这种短生命周期数据尽量留在热层,S3只负责最终落盘和容灾。这个设计跟大数据的cache语义一脉相承,但放在无服务器环境里就是质变。
1.3 55%的成本节省是怎么算出来的
官网能给出55%这个数字,不是拍脑袋。我拆解一下这个数字可能的构成,方便你自己评估迁移收益。
最大的一块,是S3请求费用的消失。以我自己的日志ETL为例,数据量大约每天1.2TB,源文件按小时分片存在S3,SQL里涉及大量join和groupBy,shuffle量很大。之前跑在EMR集群上,每天光S3的GET/PUT/POST请求费用在25到35美元之间浮动,因为shuffle中间数据每次都写到S3,一天下来几十万次请求很正常。迁到EMR Serverless Storage之后,shuffle写S3的路径被本地NVMe盘接管了,S3请求量直接降了90%以上,每天这块成本肉眼可见地掉到5美元以内。
第二块,是集群空转费用。EMR Serverless按任务实际消耗的vCPU和内存计费,没有“集群开着等任务”的概念。传统集群即使凌晨没有作业,或者作业之间有空档,只要机器开着就在烧钱。我那个场景每周作业总时长约35小时,但集群从创建到销毁一共开机190小时,剩下155小时全在空转。Serverless模式下只按任务实际执行时间算,这部分省下来非常夸张。
第三块是存储副本相关的费用。新版Storage特性在上线后,对部分场景移除了数据冗余存储相关的额外计费,这直接影响那些需要大量复用中间结果的作业。如果你的作业大量使用persist(StorageLevel.DISK_ONLY)或checkpoint,这块节省会特别明显。
综合下来,55%这个数字在“重shuffle、多中间结果、作业时间集中但集群必须常开”的场景里完全可以出现。如果你的作业本身就是轻量级的,读一次S3算完就写回,那节省比例会低一些,大概
