雅博Tweetはじめに前回は、Sparkで処理を実行したときのボトルネック箇所と、その対策について解説しました。今回は、「本検証のシナリオではどのようなクラスタ構成が良いか」検証した結果を解説します。Spark2.0のパラメータチューニング最適なクラスタ構成を検討するにあたり、今回はSparkの(設定ファイルspark-defaults.confに記述できる)パラメータのうちいくつかをチューニングします。Sparkのバージョンは2.0処理対象のデータは365日分の消費電力量データSparkのシャッフルファイル出力先ディスクはHDFSと共用(前回解説したもの)パーティション数のチューニングSparkはデータを「パーティション」という単位で並列処理します。処理の流れは以下の通りです(図1)。今回はシャッフル処理後の適切なパーティション数を検証します。(1)データソースからデータを読み出しデータソースがHDFSの場合、Sparkはブロック単位でHDFS上のファイル群を読み出し、各ブロックをパーティションとして扱います。Sparkのパーティション数はHDFSから読み出したBlock数と同じです。(2)データを並列に変換処理1パーティションを1タスクで並列に変換処理していきます。処理の途中でパーティション間のデータ交換(シャッフル)を行います。このときパーティション数はデフォルト設定で200個に変更されます。(4)データストアにデータを書き込み変換処理が完了したら、処理結果をパーティション単位で並列にデータストアへ書き込みます。APIを使用してシャッフル処理(図1(3))すると、パーティション数が200個(デフォルト値)に変更されます。デフォルト設定では1パーティションを1コア(で動作する1タスク)が処理するため、最低でもコア数以上のパーティションがないと最適な設定とは言えません。シャッフル処理後の適切なパーティション数は処理に依存します。本検証でSparkに割り当てたコア数は210個です。そこでシャッフル処理後のパーティション数を200個(デフォルト値)と210個から5040個(割当コア数の24倍)の間で設定し、それぞれの処理時間を測定して最適なパラメータ設定値を求めます。検証結果シャッフル処理後のパーティション数設定と処理時間の関係を図2に示します。図2:シャッフル後のパーティション数設定と処理時間この結果から、次のことが分かります。パーティション数が630個から1,470個の間では処理時間が約3,000秒で推移したパーティション数が1,050個のとき、処理時間は最短で2,936秒であったデフォルト設定(200個)に比べて約700秒、本検証の初期設定(210個)と比べて約1,070秒短縮パーティション数が420個のときは処理が失敗した最適パーティション数の考察Sparkを実システムに適用する際には、コア数のほかに次のような要素にも影響を受けるため、事前に検証して最適なパーティション数を探る必要があります。ディスク台数(パーティション数はディスクへの並列書き込み数となるため)データ量(1パーティションあたりの保持データ量)本検証では、パーティション数を1,050個に設定すると最も高速に処理を実行できたので、この値を最適な設定値とします(表1)。このパラメータ設定はspark-defaults.confに記述します。シャッフル後のパーティション数を420個に設定したときに処理が失敗した原因は不明です。Sparkはメモリが少ない場合にデータをディスクに書き出して確保しますが、タイミングによって確保に失敗することがあるようです。spark.sql.shuffle.partitionsSparkへのメモリ割当量のチューニング最適メモリ割当量の検証内容Sparkにクラスタの全メモリを割り当てることはできません。クラスタではSparkのほかにOSやHadoopデーモンがメモリを使用するためです。前回、シャッフルファイルがディスクに書き込まれるとき、OSのページキャッシュが使われることを解説しました。今回の集計処理はシャッフルするデータ量が多く、ページキャッシュ用にある程度のメモリを確保する必要があります。そこで本検証では、Sparkに割り当てるメモリ容量をクラスタの全メモリの75%に相当する1,728GB(デフォルト設定)から15%に相当する345GBの間で設定し、それぞれの処理時間を測定して最適なパラメータ設定値を求めます。検証結果Sparkに割り当てるメモリ容量を変化させたときの処理時間を図3に示します。図3:Sparkへのメモリ割当量と処理時間この結果から、次のことが分かります。Sparkへのメモリ割当量を減らしても処理時間に大きな変化は見られないまた本検証中に次のような事象に遭遇し、対応しました。メモリ割当量を減らすと、エグゼキュータのコンテナがYARNによって停止されることがある本検証ではSparkへのメモリ割当量を619GB以下に設定したときにコンテナが停止されました。エグゼキュータに割り当てるメモリのオーバヘッド確保容量を増やすことでコンテナ停止を回避できたコンテナ停止時にSparkのログを参照すると、オーバヘッド確保容量を調整するようメッセージが出力されました。よって今回は、メモリ割当量691GB、576GBのときにメモリオーバヘッドを20%に、メモリ割当量460GBのときにメモリオーバヘッドを30%に設定しました。最短の処理時間は2,848秒で、1,728GB(デフォルト設定)のときの2,936秒から約3%の高速化を達成しました。平均処理時間は2,915.6秒、標準偏差は47.6なので性能向上していると言えます。よって、本検証では処理時間が最短だったSparkへのメモリ割当量806GB(クラスタ全体の約35%)を最適値に定めます(表2)。このパラメータ設定はspark-defaults.confに記述します。spark.executor.memorySparkへのメモリ割当量が1,728GBのときのメモリ使用量の推移を図4に、メモリ割当量が460GBのときのメモリ使用量の推移を図5に示します。CacheがOSのページキャッシュ、UsedがSparkの使用メモリです。今回の検証内容のようにシャッフルのディスクI/O量が大きい場合は、Spark用のメモリを減らした分だけOSのページキャッシュが使用できるメモリが増え、ディスクI/Oが減少するため、結果として処理時間はあまり変わらなかったと考えられます。図5:Sparkへのメモリ割当量460GBのときのメモリ使用量の変化よって、Sparkへのメモリ割当量は多ければ良いというわけではありません。前回で触れたシャッフル処理時のディスクアクセスを考慮して、ある程度のメモリをOSのページキャッシュ用に使わせるべきです。Sparkへ割り当てるメモリを増やすほどOSのページキャッシュに使えるメモリが減るため、メモリにシャッフルファイルが収まらずシャッフル処理(のディスクアクセス)に時間を浪費する恐れが高まります。この場合は、やはりクラスタに搭載するメモリ容量を十分に用意すべきです。シャッフルデータ量が多い場合は、シャッフル処理時にエグゼキュータへ割り当てられたメモリ容量を超過して、エグゼキュータのコンテナがYARNによって停止されることがあります。この事象はSparkに割り当てるメモリが少ないほど発生しやすいです。エグゼキュータに割り当てるメモリのオーバヘッド確保容量をデフォルト値の10%から増やす(表3)ことで回避できました。このパラメータ設定はSparkの設定ファイルspark-defaults.confに記述します。spark.yarn.executor.memoryOverhead(※):エグゼキュータ自身が使用するメモリ容量。デフォルトでは384MBもしくはSpark割当量の10%のうち、大きいほうの値が使用されるエグゼキュータ数のチューニングここでは、Sparkへのメモリ割当量を806GB(クラスタ全体の約35%)に設定した状態で検証します。最適エグゼキュータ数の検証内容エグゼキュータ数を増加させると、エグゼキュータ間での通信などを処理するオーバヘッドが増加します。一方で1エグゼキュータに割り当てるメモリ量が小さくなり、Javaのガベージコレクション(GC)にかかる時間やキャッシュミス、TLBミスが減少します。そこで本検証では、エグゼキュータ数を11個から65個の間で設定し、それぞれの処理時間を測定して最適なパラメータ設定値を求めます。エグゼキュータ数を変化させた場合も、その増減に合わせてCPUコア数とメモリ量を調整することで、Sparkに割り当てる合計CPUコア数は210個、メモリ量は806GBで一定となるようにします。検証結果Sparkに割り当てるエグゼキュータ数を変化させたときの処理時間を図6に示します。図6:エグゼキュータ数と処理時間この結果から、次のことが分かります。エグゼキュータ数を増やすと処理時間が短縮できる傾向があるエグゼキュータ数が41個(初期設定)の場合に処理時間が最短(2,848秒)であった最適エグゼキュータ数の考察エグゼキュータ数を11個から41個まで増加させた間は処理時間が短縮され、65個に増加した場合は29個に設定したときと同程度の処理時間に戻っています。ここが、エグゼキュータあたりのリソースを絞ったことによるGCにかかる時間やキャッシュミスを低減できたことよりも、エグゼキュータ間で発生する処理のオーバヘッドが大きくなる境界と考えられます。よって、本検証ではエグゼキュータ数41個(本検証の初期設定)を最適設定値として定めます(表4)。このパラメータ設定はspark-defaults.confに記述します。spark.executor.instancesコア数のチューニングここでは、Sparkのエグゼキュータ数を41個(本検証の初期設定値)に設定した状態で検証します。最適コア数の検証内容Sparkにクラスタの全CPUコアを割り当てることはできません。クラスタではSparkのほかにOSやHadoopデーモンがメモリと同様にCPUコアを使用するためです。Sparkにコア数を多く割り当てても、処理性能は向上しない可能性があります。waitに費やすかもしれないからです。そこで本検証では、SparkへのCPUコア割当数を210個(初期設定)から46個(ドライバ5コア・エグゼキュータ1コア)の間で設定し、それぞれの処理時間を測定して最適なパラメータ設定値を求めます。検証結果Sparkに割り当てるCPUコア数を変化させたときの処理時間を7に示します。図7:CPUコア割当数と処理時間この結果から、次のことが分かります。割当コア数を減らすほど処理時間は増加しました。よって、最も割当コア数が多い本検証の初期値である210個を最適設定値として定めます(表5)。このパラメータ設定はspark-defaults.confに記述します。本連載で全4回にわたって検証したパラメータチューニングを振り返ります。2.0に各チューニングを施した場合の処理時間を図8にまとめます。チューニングを実施することで、本検証での初期設定時に比べて約4.7倍の高速化を達成しました。2.0)クラスタ構成の考え方の一例を表6~9に示します。OSインストール領域:1シャッフル用:多いほど良いHDFS用:多いほど良いHDFSのブロックはデフォルトで3台に複製されるため、最低4台のWorkerノードを用意するべきです。Workerノード間は10Gbps回線での接続を推奨します。Sparkのシャッフルファイル出力先(YARN)とHDFSは同じディスクを共用します。OSインストール領域のディスクは多量のアクセスによりハングする恐れがあるため、シャッフルファイル出力先とは共用しないことを推奨します。ノードに搭載されたディスクのうち、OSインストール先ディスク以外を使う。ノードに搭載されたディスクのうち、OSインストール先ディスク以外を使う。HDFSが使うディスクと共用しても構わない。spark.sql.shuffle.partitionsOSとHive(ORCFile)の推奨パラメータ設定は第6回の時と同じです。おわりに本連載も、今回で最終回となります。最後にポイントをまとめます。本検証のシナリオ(電力データの集計処理)ではデータ結合を含む多段の集約処理を含むため、Sparkのシャッフル処理が頻発しディスクアクセスが処理時間の大半を占めました。2.0に移行してもリリースノート記載の「Spark1系と比べて2倍から10倍」という処理性能は得られないと思われます。Spark活用のためにはクラスタに十分なメモリ容量を搭載することSparkはシャッフルファイルを含むすべてのデータがメモリ(ページキャッシュ)に収まるとき、最も性能を発揮できます。扱うデータ量は処理によって異なるため、小規模なデータで予め試行し、必要なメモリ容量を見積もることを推奨します。メモリの増設が必要な場合はクラスタをスケールアウトしてメモリ総容量を増やすか、1ノード当たりの物理メモリ容量を増やすことになるかと思います。パラメータチューニングは慎重にSparkを用いたHadoopクラスタを構築する際は、机上での設計だけでなく実際の処理やデータを使って試行錯誤しながら慎重にパラメータ等を設定する必要があることに注意してください。ページキャッシュにシャッフルファイルが収まらないとき、シャッフルファイル出力先をHDFSが使うディスクと共用する形で追加することで約3.6倍の性能向上を実現しました。この方法はHDFSのディスクアクセス性能を低下させるため、シャッフルファイルがページキャッシュに収まる場合は処理性能が若干低下します。パーティション数のように実際に試してみないと最適値が分からないパラメータもあります。最後になりましたが、本連載がSparkを用いたデータ分析システム構築の一助になれば幸いです。日立製作所2012年入社。IaaS稼働監視サービスの基盤開発、OpenStackを題材にしたクラウド基盤の運用管理に関する研究、CloudFoundryの検証・評価業務などを経て、現在はICT事業統括本部OSSソリューションセンタにてビッグデータに関するソリューション開発やOSSの検証業務に従事。日立製作所OSSソリューションセンタ所属。これまでにストレージシステムとその管理ソフトウェアの開発を手掛けてきた。現在はHadoopやSpark、Kafkaを中心としたビッグデータ関連OSSの導入支援やソリューション開発、およびビッグデータを活用したデータ分析業務を担当している。Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。ITがお届けするポッドキャストです。