CS PAPERS DEEP-READ · PAPER 68

Resilient Distributed Datasets (Spark RDD)

Zaharia, Chowdhury, Das, Dave, Franklin, Shenker, Stoica et al. · UC Berkeley AMPLab · NSDI 2012

中文 →

What did this paper do?

In 2012 a group at UC Berkeley proposed RDDs (Resilient Distributed Datasets) and built Spark on top of them — the engine almost every company now reaches for when the data is too big for one machine. Before it, that job went to Hadoop MapReduce. RDDs made the same work an order of magnitude faster in a lot of cases, and made "type one line, a hundred machines answer in seconds" an ordinary thing to do.

Start with something odd

When you gang a hundred machines together to crunch data, the thing to fear is not slowness — it is a machine dying halfway through. Run a hundred of them for a few hours and one or two will drop out, taking their slice of data and their half-finished work with them. The old answer was blunt and effective: after every step, write the intermediate results all the way out to disk, in triplicate. When a machine dies, fetch the results back and carry on.

The trouble shows up in work that has to go over the same data again and again — training a model, ranking web pages, dozens of passes over one batch. The old way writes to disk and reads back on every single pass. The data never changed, yet it got hauled in and out dozens of times. Nearly all the time went into hauling, not into computing.

The idea

So leave the data in memory and stop hauling it — except now, when a machine dies, what was in its memory is genuinely gone. Which puts the old question back: no triplicate copies, no disk, so what happens when something breaks?

The RDD answer is lovely: don't store the results, store the method.

Picture a kitchen with twenty trays of prepped ingredients. Afraid of losing them, most people would photograph every tray and stash two spare copies in the walk-in — bulky and slow. RDDs say: no need. Here is a recipe card — this tray came from that tray via this one step, that tray came from an earlier one, and the chain runs all the way back to the original sack of produce. Lose a tray and you remake that one tray from the card; every other tray is untouched. The card is a few lines of text, so keeping it costs essentially nothing. The paper calls this card the dataset's lineage.

Why the recipe card stays short

Because of one piece of self-restraint: only whole-tray steps are allowed — chop everything on this tray, throw out everything that isn't spicy, pair these two trays up by name. What is not allowed is "add half a spoon of salt to potato number 37."

That restriction is the whole trick. Allow the fiddly per-item edits and what you must record is not a few lines but millions of ledger entries — at which point you may as well have stored the results. Record only whole-tray moves and the card stays short enough to hand a copy to every machine in the building. And since big-data work is overwhelmingly "do the same thing to all of it," giving up the fiddly edits barely hurts.

One more rule: once a tray is made it may never be altered — changing it means making a new tray. Precisely because nothing can be altered underneath you, a tray remade from the card is identical to the one you lost. That is what makes remaking count as recovery.

What it bought

Data can now sit in memory and be reused with confidence, so repetitive work got more than ten times faster. A dead machine no longer restarts the whole job — only the lost pieces get remade, and they can be remade on many machines at once. Better still, it changed how people relate to data: a question over a few terabytes used to mean a coffee break; now you can ask one after another like using a calculator, seconds per answer.

One honest cost: this approach is hungry for memory, and it only works for whole-batch jobs — if what you want is to update one record at a time as news arrives, RDDs cannot help you; that is a different kind of system's job.

One line to remember

Spread the data across cluster memory in blocks, allow only whole-dataset transformations, and never let a block be altered once made. Then fault tolerance needs no triplicate copies — just a record of how each block was produced, so a lost block can be rebuilt from its recipe. That is what lets data stay in memory and be reused: iterative jobs get an order of magnitude faster, and a terabyte can answer a question in seconds.

Want the lineage graph, the narrow/wide dependency split, and the numbers? → Switch to the deep read