Hadoopクラスターでの実行
先ほどの例では、jaqlからリテラルで直接呼び出しているため、Hadoopクラスターへは飛んでいきません。大量のデータを処理するなら、HDFSにファイルを置き、transform文を使ってプラグインを呼び出します。
[idcuser@vhost2044 ~]$ jaqlshell
Initializing Jaql - < version: 0.5.2; build time: November 07, 2011, 14:58:20; built for hadoop: 0.20 >
jaql> date = [{"name":"米持", "add":"神奈川"},{"name":"高橋", "add":"東京"}];
jaql> addClassPath("/home/idcuser/scripts/yone.jaql.jar");
true
jaql> toArray = javaudf("yone.jaql.ToArray");
jaql> date -> transform toArray($.name, $.add);
[
[
"米持",
"神奈川"
],
[
"高橋",
"東京"
]
]
jaql>
ここで、dataオブジェクトを「read(hdfs("filename.json"))」などから読み込み、HDFSファイルやフォルダーを指定すれば、HDFS上にある大量データを、このオペレーターで処理できます。当然、このオペレーターは各ノードに自動的に配布され、分散処理されます。
外部ライブラリの統合
Java実装のJaql関数で、外部ライブラリを統合するには、このjarファイルを作っただけでは不十分です。jarに別のjarを入れても、そのjarがロードできないようです。
そこで、外部jarを使う場合には、Hadoopを実行しているマシン上に、ライブラリ群が利用するリソースファイルをコピーして置いたり、jarが検索できるようにしたりする必要があります。Jaqlは、データ量がとても少ない場合はMapReduceをサブミットせずにローカル実行するため、Masterノードにも同じ構成をする必要があります。
リソース
外部ライブラリが、特定のフォルダーに準備されたリソースを利用する場合は、そのフォルダー群をすべてのノードに準備します。MapReduceのタスクは、自動的に準備されるフォルダーで実行されるため、「カレントフォルダーにある」という前提で動作するようなライブラリは統合に苦労します。
ライブラリjar
jarファイルは、jaqlshellの実行フォルダーに置いてもロードできません。Master、Slaveを含め、すべてのノードの、MapReduceタスクが検索できるパスに置く必要があります。MapReduceの実行環境をいじらずにjarを検索しやすい場所としては、jdk/jre/lib/extがあります。ただし、ここに共通ライブラリを置くと、そのライブラリがさらに検索する別のjarもそこに置かないと見つからないという現象が起きるので、必ずしもベストとは言えません。
まとめ
今回、Jaqlの拡張には、大きくわけて以下の方法があることを解説しました。
- Jaql関数の定義とモジュール化
- JavaによるJaql関数の実装
以上を活用して、Jaqlジョブを効率的に開発し、MapReduceが活用しやすい環境を作ってみてください。
