ハードウェアのプロビジョニング

Spark開発者によく寄せられる質問は、Spark用のハードウェアをどのように構成するかということです。適切なハードウェアは状況によって異なりますが、以下のような推奨事項があります。

ストレージシステム

ほとんどのSparkジョブは、外部ストレージシステム(例:Hadoopファイルシステム、またはHBase)から入力データを読み取る必要があるため、このシステムにできるだけ近い場所に配置することが重要です。以下をお勧めします。

ローカルディスク

Sparkはメモリ内で多くの計算を実行できますが、RAMに収まらないデータを保存したり、ステージ間で中間出力を保持したりするために、ローカルディスクを使用します。ノードあたり4〜8個のディスクを、RAIDなしで(別々のマウントポイントとして)構成することをお勧めします。Linuxでは、不要な書き込みを減らすために、noatimeオプションを使用してディスクをマウントします。Sparkでは、ローカルディスクのカンマ区切りのリストとして構成spark.local.dir変数を構成します。HDFSを実行している場合は、HDFSと同じディスクを使用しても問題ありません。

メモリ

一般に、Sparkはマシンあたり8 GiBから数百ギガバイトのメモリでうまく動作します。いずれの場合も、Sparkにメモリの最大75%のみを割り当てることをお勧めします。残りはオペレーティングシステムとバッファキャッシュ用に残します。

必要なメモリ量は、アプリケーションによって異なります。特定のデータセットサイズでアプリケーションがどれくらいのメモリを使用するかを判断するには、データセットの一部をSpark RDDにロードし、Sparkの監視UI(http://<driver-node>:4040)の[ストレージ]タブを使用して、メモリ内のサイズを確認します。メモリ使用量はストレージレベルとシリアル化形式によって大きく影響されることに注意してください。メモリ使用量を減らすためのヒントについては、チューニングガイドを参照してください。

最後に、Java VMは常に200 GiBを超えるRAMでうまく動作するとは限らないことに注意してください。これよりも多くのRAMを搭載したマシンを購入する場合は、単一ノードで複数のExecutorを起動できます。Sparkのスタンドアロンモードでは、ワーカーは利用可能なメモリとコアに応じて複数のExecutorを起動する役割を担い、各Executorは別のJava VMで起動されます。

ネットワーク

私たちの経験では、データがメモリにある場合、多くのSparkアプリケーションはネットワークバウンドになります。10ギガビット以上のネットワークを使用するのが、これらのアプリケーションを高速化するための最良の方法です。これは、グループ化、削減、およびSQL結合などの「分散削減」アプリケーションでは特に当てはまります。任意のアプリケーションでは、アプリケーションの監視UI(http://<driver-node>:4040)から、Sparkがネットワーク上でどれだけのデータをシャッフルするかを確認できます。

CPUコア

Sparkは、スレッド間の共有を最小限に抑えるため、マシンあたり数十個のCPUコアにうまくスケールします。マシンあたり少なくとも8〜16個のコアをプロビジョニングする必要があります。ワークロードのCPUコストによっては、さらに多く必要になる場合もあります。データがメモリにある場合、ほとんどのアプリケーションはCPUバウンドまたはネットワークバウンドのいずれかです。