IT 论文精读 · PAPER 68

Spark RDD(弹性分布式数据集)

Zaharia 等 · UC Berkeley AMPLab · NSDI 2012

EN →

这篇论文干了什么?

2012 年,加州大学伯克利分校的一群人提出了 RDD(弹性分布式数据集),并拿它做出了 Spark——今天处理海量数据几乎绕不开的那个引擎。在它之前这类活儿要交给 Hadoop MapReduce;RDD 让同样的活儿快一个数量级,还顺手让「在上百台机器上敲一句话、几秒出结果」成了日常。

先说个怪事

一百台机器凑成集群算大数据,最怕的不是慢,是中途有机器坏掉——总有一两台掉线,它手上那份数据和算了一半的结果就没了。老办法的对策很实在:每做完一步就把中间结果完整写到硬盘、还存三份,谁坏了就捞回来重来。

问题出在要反复算很多遍的活儿——训练模型、算网页排名,同一批数据得过几十遍,而每遍都要写一次硬盘再读一次。数据明明没变却被搬进搬出几十趟,时间几乎全花在搬运上。

那个点子

那就把数据留在内存里别搬走啊——可机器一坏,内存里的东西是真没了。于是回到老问题:不存三份、不落硬盘,坏了怎么办?

RDD 的答案很妙:别存结果,存做法。

打个比方。后厨备了二十盘半成品,怕丢,常规做法是每盘复制两份进冷库——又占地方又费时间。RDD 说不用:给你一张菜谱,写清这盘由哪盘经哪一步做出来、那盘又来自更早的哪盘,一路追到最开始那袋原料。丢了哪盘就照菜谱重做哪盘,别的不用动;菜谱几行字,几乎不花钱。论文把它叫血统(lineage)。

这张菜谱凭什么写得下

凭一条自我约束:只允许「整批」的做法——这盘每样都切一刀、把不辣的都挑出去、这两盘按名字配对;不允许「单独给第 37 号土豆加半勺盐」这种零碎改动。

这条约束才是命门:若允许零碎改动,要记的就不是几行菜谱而是几百万条流水账,那还不如直接存结果;只记整批动作,菜谱才短到能抄一份放每台机器上。而大数据的活儿本就绝大多数是「对全部数据做同一件事」,这条约束基本不疼。

还有一条:一盘做好就不许再改。正因为不许改,照菜谱重做的那盘和丢掉的那盘一定一模一样——重算才敢算数。

带来了什么

数据能安心待在内存里反复用,迭代的活儿快出十几倍;机器坏了也不用整个任务重来,只并行重算丢掉的那一小块。它还改变了人和数据的关系:过去在几 TB 数据上问个问题要等几十分钟,现在像用计算器一样一句一问、几秒一答。

诚实一句代价:这套办法吃内存,也只对「整批处理」的活儿有效——要「来一条改一条」的零碎实时更新,它帮不上忙。

一句话记住

把数据切块摊在集群内存里、只许整批变换、做好就不许改;容错不靠复印三份,而靠记住「它是怎么一步步做出来的」,丢了哪块就重算哪块。于是数据能留在内存里反复用——迭代的活儿快一个数量级,也能几秒钟回答一个 TB 级的问题。

想看血统图、窄依赖/宽依赖的结构和实验数字? → 切到精读版