HadoopTimes

実践 機械学習:レコメンデーションにおけるイノベーション
技術情報

MapReduceの入力分割サイズとMapR-FSのチャンクサイズを理解する

MapR-FS を適切に設定することでパフォーマンスを改善する

MapReduce ジョブの効率にはさまざまな要素が関わってきます。本稿では、MapReduce 入力分割サイズとMapR-FS チャンクサイズについて論じ、それら2つをうまく設定することでジョブの実行時間がどのように改善するか、あるいは悪化するかについて見ていきます。

いま、Map/Reduce によって処理しようとしている10GB のファイルがあるとします。まず考えられるのは、標準のWholeFileInputFormat クラスを使ってこれを処理することです。その場合、10GB全て を単一のmapタスクで処理することになります。

しかしもちろん、map/reduce ジョブの実行時間を減らしたいのであれば、並列して2つ以上のタスクを走らせる必要があります。そこで別の方法として、FileInputFormatを選択し、入力ファイルが分割可能であることを示すパラメーターを設定することが考えられます。これは、単一の入力ファイルの異なる部分に対して、複数のmapタスクを実行できることを意味します。このパラメーターを分割サイズと呼びます。仮に分割サイズを1GBに設定したとすると、10GBの単一ファイルに対して、それぞれが個別に1GBずつの範囲を担当する、10のmapタスクが処理を行うことになります。

場合によっては、reduceタスクが処理するための前段階として、mapタスクが入力データをソートする必要が生じることがあります。ソートが必要になる場合、mapタスクが入力データをattempt JVM に割り当てられたメモリー容量内で処理できることが重要となります。もしメモリーが不足すると、ソートを実行するノードのハードディスクを使う必要が生じます。たとえば、mapタスクが1GBの入力データを処理しなければならないのに、ソートに使えるメモリーが100MBしかないとしましょう。

mapタスクは入力データのレコードを100MBに達するまで読み込み、メモリー内でソートします。それが完了すると、mapタスクはソート済みの100MBのチャンクをディスクに書き出します。そして次の100MBを読み込み、ソートし、書き出し、といった具合に、1GB全てを読み込みソートが終了するまで続きます。こうしてmapタスクが全ての入力データを読み込み、100MBずつのソート済みセグメントが完成したならば、今度はディスクに保存されたそれらをもう一度読み込みなおして、最終的に求めるソート順となるように書き込んでいく必要があります。

つまり、1GBの入力データを処理するためには、ハードディスクに対して約2GB分のリードと約2GB分のライトが実行されることになります。これは、データの全体を一度でメモリーに読み込み、ソートした内容を一度でディスクに書き込むことに比べ、非効率だと言えます。こうした非効率な処理が行われているかどうかは、mapタスクのカウンターを見れば知ることができます。カウンターの表示が、X個の入力レコードを読み込み、X個のレコードをディスクに書き込んだことになっていれば、mapタスクの処理は効率的だったことになります。しかし、書き込まれたレコードがX個よりもかなり多いならば、mapタスクの処理が非効率だったことが分かります。