RDD 論文ノート
Resilient Distributed Datasets (RDDs) は、分散システムに対するメモリ抽象化です。
本質的には、制限の厳しい共有メモリモデルであり、粗粒度の transformation 操作のみを提供します。
動機
問題
反復的(iterative)な分散計算には、反復間でのデータ再利用を(効率的に)行う能力が必要です。
現状
- 当時(2012年)の分散計算フレームワークには、クラスタメモリを十分に活用(再利用)できる抽象化が欠けていました。
- 既存のフレームワークでデータを再利用する唯一の方法は、複数回の分散計算を起動することでした。
したがって、問題が原理的に解けることは保証されていましたが、データの再利用は依然としてこの種の計算の性能上のボトルネックでした。過度に頻繁な I/O により、大量のリソースが浪費されていたのです。
これらの問題を解決しようとする研究はいくつかありましたが、特定の計算パターンにしか対応しておらず、汎用的ではありませんでした。
主な課題は、計算の細粒度性、汎用性、耐障害性の三者間のトレードオフにありました。
RDD
RDD は、分散計算クラスタに対するメモリ抽象化を提供し、上記の問題を大きく解決しました。その手法は、三者の中で相対的に最も重要度の低い一点、すなわち「計算の粒度」を捨てることでした。
基本
RDD の性質:
- 不変(Immutable)
- 遅延評価(Lazy)
RDD がサポートする操作:
- transformation - 遅延操作
- map
- filter
- …
- actions - 計算の起動
- count
- collect
- save
- …
- persist (キャッシュ)
Spark は RDD を実装し、DryadLINQ に似たプログラミングインターフェースを提供しています。
RDD の利点
主に、(クラスタメモリをモデル化する)類似の抽象化と比較して、RDD は細粒度のデータ操作を犠牲にすることで、他の側面(汎用性、耐障害性、性能低下時の挙動、一貫性、遅延タスク問題、使いやすさ)において優れた性能を発揮します。
RDD の制限
RDD は、大量の細粒度な読み書きを伴う非同期計算(例:クローラのストレージシステム)には適していません。このようなアプリケーションに対して、著者は他のフレームワークを提案していますが、ここでは詳述しません。
Spark のプログラミングインターフェース
簡潔で効率的であるため、Scala で実装されています。
この部分では著者がいくつかの例を挙げていますが、ここでは省略します。
RDD の表現
RDD は DAG を用いて表現されます。
依存関係
- 狭い依存関係(narrow dependencies) - 各親 RDD は、最大で1つの子 RDD に依存されます。
- 広い依存関係(wide dependencies) - 1つの親 RDD が、少なくとも1つの子 RDD に依存されます。
実装
- クラスタ管理には Mesos を使用
- ジョブスケジューリングは省略
- インタプリタ統合は省略
- メモリ管理は省略
評価
- 反復タスクにおいて Hadoop の 20 倍の性能
- ユーザー分析プログラムにおいて Hadoop の 40 倍の性能を報告
- ノード障害後も迅速に再計算が可能
- 1TB のデータに対するクエリの遅延は 5-7 秒
詳細は省略します。
考察
彼らは、RDD の汎用性を示すために、Spark を用いて他の分散計算フレームワークを模倣するという徹底的な試みを行いました。
具体的な内容は省略します。
まとめ
- RDD/Spark の最大の利点は、クラスタ全体のメモリをモデル化することです。これにより、分散計算は中間結果をメモリに保存できるようになり、同じデータセットに対する高速な連続計算が可能になります。このすべては、メモリがハードディスクよりも一桁速いという前提に基づいています(そのため、Spark が Hadoop に対して 40 倍の性能向上を実現できました)。 ソフトウェア革新の理論的限界は、ハードウェアの物理的制約によって決まるということがわかります。