Hadoop の人気を考えると、そのエコシステムが拡大しているのは驚くことではありません。なかでも特に進化している 1 つの分野は、Hadoop アプリケーションのプログラミングです。Map および Reduce アプリケーションのプログラミングはものすごく複雑というわけではありませんが、プログラミングするにはある程度のソフトウェア開発の経験が必要になります。これを変えるのが、Apache Pig です。Pig は簡易化された手続き型言語で MapReduce を抽象化し、Hadoop アプリケーション用のインターフェースとして SQL (Structured Query Language) のようなインターフェースを公開します。したがって、個々の MapReduce アプリケーションを作成する代わりに Pig Latin で 1 つのスクリプトを作成すれば、そのスクリプトをクラスター全体で自動的に並列化させ、分散させることができます。
まずは、Pig の単純な例でこの言語について分析しましょう。Hadoop の興味深い使用法の 1
つは、指定した基準を満たすレコードを大規模なデータ・セットで検索するというものです (Linux では、grep として知られる検索方法です)。リスト 1 に、この検索が Pig
ではいかに単純なプロセスであるかを示します。リストに示されている 3 行のうち、実際に検索を行っているのは 1 行だけです。最初の行は、単にテスト・データ・セット
(メッセージ・ログ) をバッグ (タプルのコレクションを表します) に読み込んでいるだけに過ぎません。次に、このデータ ($0 として表現された、タプル内の唯一のエントリー、またはフィールド 1) を正規表現でフィルタリングして、文字列 WARN を検索します。バッグはこの段階で、文字列 WARN が含まれるメッセージから抽出されたすべてのタプルを表しています。このバッグを、最後にホスト・ファイルシステムに作成される warnings という名前の新規ファイルに保管します。
リスト 1. 単純な Pig Latin スクリプト
messages = LOAD 'messages'; warns = FILTER messages BY $0 MATCHES '.*WARN+.*'; STORE warns INTO 'warnings'; |
このように、上記の単純なスクリプトは単純なフローを実装しますが、従来の MapReduce モデルで直接実装したとすると、必要なコードは飛躍的に増えることになります。Pig を使用しない開発に比べると、Pig を使用したほうが遥かに簡単に Hadoop を習得して、データの処理を開始することができます。
次は、Pig 言語をさらに詳しく探ります。その後、他の例でこの言語の機能について見ていきます。
Pig Latin は、ステートメントを実行する比較的単純な言語です。「ステートメント」とは、入力 (タプルのセットを表すバッグなど) を取り、別のバッグを出力する処理のことです。「バッグ」はリレーショナル・データベースに見られるリレーションであり、テーブルと似ています (この場合、タプルが行を表し、個々のタプルはフィールドで構成されます)。
多くの場合、Pig Latin で作成されるスクリプトはある特定の形式に従います。その形式とは、ファイルシステムからデータを読み取り、そのデータに対していくつかの処理を行い (データを 1 つ以上の方法で変換)、最終的なリレーションをファイルシステムに書き込むというものです。このパターンは、リスト 1 に示したその最も単純な形 (1 つの変換のみを行う形) にも表れています。
Pig には豊富なデータ型があり、上位レベルの概念 (バッグ、タプル、マップなど) だけでなく、単純なデータ型 (int、long、float、double、chararray、bytearray など)
もサポートしています。単純なデータ型には、一連の算術演算子 (add、subtract、multiply、divide、module など) に加え、bincond という条件演算子もあります。この条件演算子は、C ternary 演算子と同じように機能します。さらに、ご想像のとおり、正規表現を使用した充実のパターン・マッチングを含め、比較演算子一式が揃っています。
すべての Pig Latin ステートメントは、リレーションで演算を行います (このことから、ステートメントは「リレーショナル演算子」と呼ばれます)。リスト 1
に示されているように、リレーショナル演算子には、ファイルシステム内でデータのロードおよび保管を行うためのものがあります。データをフィルタリングするには、リレーションの行を繰り返し処理する
FILTER
を使用することができます。これは、リレーションから後続の処理には必要のないデータを取り除くために一般的に使われている機能です。一方、リレーションの行ではなく列を繰り返し処理する必要がある場合には、FOREACH 演算子を使用することができます。FOREACH
では、繰り返し処理中に FILTER や ORDER などの演算処理をネストしてデータの変換を行うことができます。
ORDER 演算子では、1 つ以上のフィールドに基づいてリレーションをソートすることができます。JOIN 演算子は、共通のフィールドに基づいて 2
つ以上のリレーションの内部結合または外部結合を行います。ユーザーが定義した表現に基づいてリレーションを 2 つ以上のリレーションに分割するには、SPLIT 演算子を使用することができます。さらに、GROUP 演算子は 1
つ以上のリレーションに含まれるデータを、特定の表現に基づいてグループ化します。表 1 に、Pig のリレーショナル演算子の一部を記載します。
表 1. Pig Latin リレーショナル演算子の一部リスト
| 演算子 | 説明 |
|---|---|
FILTER | 条件に基づき、リレーションからタプルのセットを選択します。 |
FOREACH | リレーション内のタプルを繰り返し処理して、データを変換します。 |
GROUP | 1 つ以上のリレーションに含まれるデータをグループ化します。 |
JOIN | 2 つ以上のリレーションを結合 (内部結合または外部結合) します。 |
LOAD | ファイルシステムからデータをロードします。 |
ORDER | 1 つ以上のフィールドを基準にリレーションをソートします。 |
SPLIT | 1 つのリレーションを 2 つ以上のリレーションに分割します。 |
STORE | データをファイルシステムに保管します。 |
この表は Pig Latin のすべての演算子を網羅してはいませんが、大規模なデータ・セットを処理する際に極めて役立つ演算処理が記載されています。Pig Latin 言語を完全に学ぶには、「参考文献」を参照してください。Pig には、優れたオンライン・マニュアルが揃っています。次は、これらの演算子が実際にどのように機能するのかを理解するために、Pig Latin スクリプトの作成に取り掛かります。
以前、Hadoop について書いた記事では、Hadoop をパッケージとしてインストールして構成するという方法を採りました。しかし、Cloudera は Hadoop を Linux と一緒に仮想アプライアンスとしてパッケージ化することによって、さらに Hadoop を使いやすくしています。ダウンロードのサイズはかなりありますが、この場合の仮想マシン (VM) は、Hadoop だけでなく Apache Hive と Pig も併せて事前ビルドされ、構成されています。つまり、1 つのダウンロードと無料で入手できる type-2 ハイパーバイザー (VirtualBox または KVM (Kernel-based Virtual Machine)) によって、構成済みですぐに使える Hadoop 環境全体を手に入れられるというわけです。
特定の VM ファイルをダウンロードした後に必要となる作業は、特定のハイパーバイザーに応じた VM を作成することです。「参考文献」で、そのためのステップ・バイ・ステップの手順を調べてください。
VM を作成し終わったら、その VM を VirtualBox で起動してください。すると、VirtualBox が Linux カーネルをブートして、必要なすべての Hadoop デーモンを開始してくれます。ブートが完了したら、まずは Hadoop と Pig と通信するためのターミナルを作成します。
Pig は 2 つのモードのいずれかで使用することができます。一方のモードはローカル・モードで、Hadoop や HDFS (Hadoop Distributed File System) を一切使用しません。このモードでは、すべての処理が単一の Java 仮想マシン (JVM) の中でローカル・システムファイルのコンテキストにおいて行われます。もう一方の MapReduce モードでは、Hadoop ファイルシステムとクラスターが使用されます。
ローカル・モードでPig を使用する場合は、単に Pig を起動して、exectype オプションでローカル・モードを指定します。すると、Grunt シェルが立ち上がり、対話形式で Pig ステートメントを入力できるようになります。
$ pig -x local ... grunt> |
そこからは、各処理の結果を確認しながら、対話形式で Pig Latin スクリプトをコーディングすることができます。試しに、リスト
1 に記載したスクリプトを実行してみてください (リスト 2
を参照)。今回は、データをファイルに保管するのではなく、単純にリレーションのセットとしてダンプ出力します。変更後の出力を見ると、ログの各行 (FILTER で定義した検索基準と一致する行) 自体が (括弧 (()) で区切られた) リレーションであることがわかります。
リスト 2. Pig をローカル・モードで対話形式によって使用する
grunt> messages = LOAD '/var/log/messages'; grunt> warns = FILTER messages BY $0 MATCHES '.*WARN+.*'; grunt> DUMP warns ... (Dec 10 03:56:43 localhost NetworkManager: <WARN> nm_generic_enable_loopback(): error ... (Dec 10 06:10:18 localhost NetworkManager: <WARN> check_one_route(): (eth0) error ... grunt> |
STORE 演算子を指定した場合には、(単純な通常のファイルが生成されるのではなく) 指定した名前のディレクトリー内にデータが生成されることになります。
Mapreduce モードを使用する場合は、まず、Hadoop が実行中であることを確認してください。最も簡単な確認方法は、Hadoop ファイルシステム・ツリーのルートでファイルを一覧表示する処理を実行することです (リスト 3 を参照)
リスト 3. Hadoop が使用可能であることをテストする
$ hadoop dfs -ls / Found 3 items drwxrwxrwx - hue supergroup 0 2011-12-08 05:20 /tmp drwxr-xr-x - hue supergroup 0 2011-12-08 05:20 /user drwxr-xr-x - mapred supergroup 0 2011-12-08 05:20 /var $ |
上記に示されているように、Hadoop が正常に実行されている場合には、このコードによって 1 つ以上のファイルが一覧として表示されます。ここで、Pig をテストしてみます。まずは Pig を起動し、それからディレクトリーを hdfs ルートに変更し、Pig の外部から確認された HDFS の内容が表示されるかどうかを調べます (リスト 4 を参照)。
リスト 4. Pig をテストする
$ pig 2011-12-10 06:39:44,276 [main] INFO org.apache.pig.Main - Logging error messages to... 2011-12-10 06:39:44,601 [main] INFO org.apache.pig.... Connecting to hadoop file \ system at: hdfs://0.0.0.0:8020 2011-12-10 06:39:44,988 [main] INFO org.apache.pig.... connecting to map-reduce \ job tracker at: 0.0.0.0:8021 grunt> cd hdfs:/// grunt> ls hdfs://0.0.0.0/tmp <dir> hdfs://0.0.0.0/user <dir> hdfs://0.0.0.0/var <dir> grunt> |
ここまでのところ、順調に進んでいます。Pig の内部から Hadoop ファイルシステムを確認できることがわかったので、今度は何らかのデータをローカル・ホスト・ファイルシステムから Hadoop ファイルシステムに読み込みます。Pig を使用して、ファイルをローカルから HDFS にコピーしてください (リスト 5 を参照)。
リスト 5. テスト・データを用意する
grunt> mkdir test grunt> cd test grunt> copyFromLocal /etc/passwd passwd grunt> ls hdfs://0.0.0.0/test/passwd<r 1> 1728 |
テスト・データが Hadoop のファイルシステムに安全に保管されたところで、次は別のスクリプトを試してみます。Pig 内では (ファイルが存在することを確認するためだけに)
cat を使用してファイルの内容を表示することができます。この特定の例では、passwd ファイル内でユーザーに対して指定されたシェルの数 (passwd 内の最後の列) を特定します。
まず始めに、passwd ファイルを HDFS から Pig リレーションにロードする必要があります。リレーションへのロードは LOAD
演算子を使用する前に行いますが、この例ではパスワード・ファイルのフィールドを個別のフィールドに構文解析しなければなりません。そのために、このサンプル・コードでは PigStorage 関数を指定します。この関数を使用して、ファイルの区切り文字 (この例では、コロン (:) 文字) を指示することができます。AS キーワードを使用して個々のフィールド
(あるいはスキーマ) およびその型を指定します (リスト 6 を参照)。
リスト 6. ファイルをリレーションに読み込む
grunt> passwd = LOAD '/etc/passwd' USING PigStorage(':') AS (user:chararray, \
passwd:chararray, uid:int, gid:int, userinfo:chararray, home:chararray, \
shell:chararray);
grunt> DUMP passwd;
(root,x,0,0,root,/root,/bin/bash)
(bin,x,1,1,bin,/bin,/sbin/nologin)
...
(cloudera,x,500,500,,/home/cloudera,/bin/bash)
grunt>
|
続いて、GROUP 演算子を使用して、このリレーションに含まれるタプルをシェルごとにグループ分けします (リスト 7
を参照)。ここで、GROUP 演算子の結果を説明するために、もう一度ダンプ出力を実行します。この出力では、使用している個々のシェルごとに、タプルが (内部バッグとして) グループ化されていることに注目してください (シェルは各出力行の先頭に指定されています)。
リスト 7. シェルごとにタプルをグループ化する
grunt> grp_shell = GROUP passwd BY shell;
grunt> DUMP grp_shell;
(/bin/bash,{(cloudera,x,500,500,,/home/cloudera,/bin/bash),(root,x,0,0,...), ...})
(/bin/sync,{(sync,x,5,0,sync,/sbin,/bin/sync)})
(/sbin/shutdown,{(shutdown,x,6,0,shutdown,/sbin,/sbin/shutdown)})
grunt>
|
けれども目的としているのは、passwd ファイル内に指定されたそれぞれのシェルのカウントです。そこで、FOREACH
演算子を使用してグループ内の各タプルを繰り返し処理し、出現するシェルを COUNT によってカウントします (リスト 8 を参照)。
リスト 8. 各シェルのカウントによって結果をグループ分けする
grunt> counts = FOREACH grp_shell GENERATE group, COUNT(passwd); grunt> DUMP counts; ... (/bin/bash,5) (/bin/sync,1) (/bin/false,1) (/bin/halt,1) (/bin/nologin,27) (/bin/shutdown,1) grunt> |
注: このコードをスクリプトとして実行するには、スクリプトをファイルに入力し、そのファイルを myscript.pig
などの名前で保存してから、pig myscript.pig のように実行してください。
Pig では、いくつかの診断演算子をサポートしています。これらの診断演算子を使って、Pig
スクリプトをデバッグすることができます。前のスクリプトの例でおわかりのように、DUMP
は、データだけでなくデータ自体のスキーマも表示できる貴重な演算子です。また、DESCRIBE 演算子を使用すれば、リレーションのスキーマ (フィールドと型) の詳細なフォーマットを生成することもできます。
EXPLAIN 演算子はかなり複雑ですが、有用な演算子です。特定のリレーションについて、EXPLAIN を使用することによって実際の演算子が Map ジョブと Reduce ジョブにどのようにグループ分けされるか (つまり、データがどのようにして得られたか) を表示させることができます。
表 2 に、Pig Latin でサポートされている診断演算子のリストとそれぞれの演算子についての説明を記載します。
表 2. Pig Latin の診断演算子
| 演算子 | 説明 |
|---|---|
DESCRIBE | リレーションのスキーマを返します。 |
DUMP | リレーションの内容を画面にダンプ出力します。 |
EXPLAIN | MapReduce 実行プランを表示します。 |
Pig は、この記事で説明したコンテキストにおいては強力で有用な言語ですが、ユーザー定義関数 (UDF) を使用することで、さらに強力なものにすることができます。Pig スクリプトでは、入力データの構文解析や、出力データ、さらには演算子のフォーマット設定などのためにユーザーが定義した関数を使用することができます。UDFは Java 言語で作成され、Pig でカスタム処理をサポートできるようになっています。UDF は、Pig を特定のアプリケーション・ドメインに拡張する手段となります。UDF の開発について詳しくは、「参考文献」を参照してください。
この短い記事から理解できるように、Pig は Hadoop クラスター内のデータにクエリーを実行できる強力なツールです。その強力さから、Yahoo! ではその Hadoop ワークロードの 40% から 60% が Pig Latin スクリプトから生成されていると概算しているほどです。Yahoo! で使用している 100,000 の CPU のうち、約 50% は Hadoop を実行していることから、相当な数の Pig が実行されていることになります。
その一方、Pig を利用している組織は Yahoo! だけではありません。Pig は、Twitter でログの処理やツイート・データのマイニングのために使われている他、AOL と MapQuest ではアナリティクスやバッチ・データ処理のために、また LinkedIn では知り合いを見つけるために使われています。伝えられるところでは、Ebay では検索を最適化するために Pig を利用しており、adyard ではそのレコメンダー・システムの約半分で Pig が使われています。
ビッグ・データを処理する Pig の強力さを挙げていくと、それだけで一冊の本が書けてしまうほどです。Pig は、Hadoop クラスターでのビッグ・データ処理を開発者でない人でさえも簡単に行えるようにします。Pig は元々 Yahoo! によって 2006年に開発され、それからまもなくして全世界で使用できるように Apache Software Foundation に移譲されました。この移譲が行われたのは、Yahoo! の研究者たちが、Pig が開発者でない人たちに与える力を認識したためです。インフラストラクチャーとしての Hadoop の人気が高まるなか、ビッグ・データとその使用が拡大し続ける状況に対処する際の様相を変えるのは、Hadoop エコシステムに他なりません。
学ぶために
- Pig の最新ニュースと最新ソフトウェア、そして Pig
の導入方法とこのプロジェクトに関与する方法については、Pig の情報源、Apache Web サイトにアクセスしてください。
- インスタンスを稼働させるには、Hadoop
Demo VM が極めて単純な手段となります。この VM には、Hadoop、Hive、そして CentOS Linux オペレーティング・システム上の Pig を含め、必要なものがすべて揃っています。
- Cloudera
Training VM は、Hadoop を導入するには理想的な手段です。この VM によって必要な構成作業は最小限になり、Hadoop と Pig を使用してデータ・セットの処理を簡単に導入できます。
- 「Virtual
appliances and the Open Virtualization Format」(M. Tim Jones 著、developerWorks、2009年10月) では、ソフトウェアの新しい配信形態としての仮想アプライアンスの使用を探っています。仮想アプライアンスにより、(オペレーティング・システムと併せて) 事前構成されたソフトウェアを VM として配布できます。
- Pig
には、リファレンス・マニュアルから説明書、そして他のリソースに至るまで、大量のオンライン・リソースが揃っています。また、わかりやすいマニュアル (パート 1 とパート 2)、スクリプト説明書、UDF ガイドもあります。
- Pig の多大なユーザー人口は、傑出した Web プロパティーを構成しています。Apache の PoweredBy ページで、Pig を使用している多種多様な Web 企業について学んでください。
- developerWorks Linux
ゾーンで、Linux 開発者および管理者向けのハウツー記事とチュートリアル、そしてダウンロード、ディスカッション、フォーラムなど、豊富に揃った資料を探してください。
- developerWorks Open source ゾーンには、オープソースのツールおよびオープンソース技術の使用に関する情報が豊富に揃っています。
- さまざまな IBM 製品や IT 業界のトピックに焦点を絞った developerWorks
の Technical events and webcasts で最新情報を入手してください。
- 無料の
developerWorks Live! briefing に参加して、IBM の製品およびツールについての情報や IT 業界の動向についての情報を迅速に把握してください。
- developerWorks の
on-demand demos で、初心者向けの製品のインストールとセットアップから、熟練開発者向けの高度な機能に至るまで、さまざまに揃ったデモを見てください。
- Twitter で
Tim をフォローしてください。また、Twitter で
developerWorks をフォローすることも、developerWorks で Linux
に関するツイートのフィードに登録することもできます。
製品や技術を入手するために
- ご自分に最適な方法で IBM
製品を評価してください。評価の方法としては、製品の試用版をダウンロードすることも、オンラインで製品を試してみることも、クラウド環境で製品を使用することもできます。また、SOA
Sandbox では、数時間でサービス指向アーキテクチャーの実装方法を効率的に学ぶことができます。
議論するために
- developerWorks コミュニティーに参加してください。ここでは他の developerWorks ユーザーとのつながりを持てる他、開発者によるブログ、フォーラム、グループ、ウィキを調べることができます。

M. Tim Jones は組み込みソフトウェアのエンジニアであり、『Artificial Intelligence: A Systems Approach』、『GNU/Linux Application Programming』(現在、第 2 版です) や『AI Application Programming』(こちらも現在、第 2 版です)、それに『BSD Sockets Programming from a Multilanguage Perspective』などの著者でもあります。技術的な経歴は静止軌道衛星用のカーネル開発から、組み込みシステム・アーキテクチャーやネットワーク・プロトコル開発まで、広範にわたっています。彼はコロラド州ロングモン在住で、Intel に勤務するプラットフォーム・アーキテクトであり、執筆活動も行っています。