AWSコンソールからEMRを実行するフローについては何となくわかったのではないかと思います。ただ、実際にはコンソールからだと詳細な設定ができなかったりして不便なことも多いため、今後はRuby製のコマンドラインツールを使ってコマンドライン上からEMRを操作していきます。
AWSコンソールからEMRを利用する際に特に困るのが、ひとつのジョブフローの中に複数のステップ(マルチステップ)を登録できない点です。ひとつのジョブフローの中にひとつのステップ(シングルステップ)しか登録できないため、毎回EC2インスタンスの起動と終了が行われます。時間的にもコスト的にもあまり効率的とは言えません。
一方、コマンドラインツールからの利用であれば、例えば3つのステップをひとつのジョブフローとして実行したい場合は以下のような操作で可能となります。
では、コマンドラインツールを導入してみます。EMRの開発者用ツールのページからダウンロードできるので、ダウンロードして展開後、任意の場所に置いてください。
展開したディレクトリに対してPATHを通します。例えばホームディレクトリに配置した場合、このようにPATHを指定することになります。これでelastic-mapreduceというコマンドが使えるようになりました。
ただ、このままではまだ利用できません。このコマンドラインツール用にアクセスキーとシークレットキーの情報を設定した設定ファイルが必要です。.credentials.jsonという名前の設定ファイルをホームディレクトリに置きます。
{
  'access-id': '[アクセスキー]',
  'private-key': '[シークレットキー]',
  'key-pair': '[キーペア名]',
  'key-pair-file': '[キーペアのパス]',
  'region': 'us-east-1',
  'log-uri': 's3n://sasata299/logs' # ログの保存場所
}
これでコマンドラインからelastic-mapreduceコマンドが利用可能になったはずです。試しにヘルプコマンドを実行してきちんと動作するかどうかを確かめてみましょう。ヘルプが表示されればインストールおよび環境設定は成功です。
このコマンドラインツールでは非常にたくさんのオプションが利用できます。各オプションの詳細は次章で詳しく取り扱いますが、まずはここで一度まとめてみます。
| オプション | 説明 | 例 | |
|---|---|---|---|
| --create | ジョブフローを作成する | ||
| -name NAME | 作成するジョブフロー名を指定する | ||
| --alive | すべてのステップが実行されたときにジョブフローを自動的に停止しないようにする | ||
| --with-termination-protection | 操作ミスを防ぐために終了保護モードでジョブフローを作成する | ||
| --ami-version | 起動するAMIのバージョンを指定する。指定しない場合最新のAMIが利用される | ||
| --num-instances NUM | ジョブフローとして起動するインスタンスの数を指定する | ||
| --instance-type TYPE | インスタンスタイプのタイプを指定する | ||
| --slave-instance-type TYPE | スレーブインスタンスのタイプを指定する | m1.medium | |
| --master-instance-type TYPE | マスターインスタンスのタイプを指定する。スレーブインスタンスと同じである必要は無い | m1.small | |
| --key-pair KEY_PAIR | キーペア名を指定する | ||
| --availability-zone A_ZONE | ジョブフローを実行するアベイラビリティゾーンを指定する | us-east-1a | |
| --info INFO | ジョブフローに付加的な情報を指定する | ||
| --hadoop-version VERSION | ジョブフローにインストールすべきHadoopのバージョンを指定する | ||
| --plain-output | 返り値としてジョブフローIDをシンプルなテキストとして返す | ||
| --instance-group ROLE | ジョブフロー作成時にインスタンスグループの役割を指定する | ||
| --bid-price | スポットインスタンス購入のための入札価格を指定する | ||
では、ここからはコマンドラインツールを実際に利用しながらEMRを利用してみましょう。まず、ジョブフローの起動からです。
ここではスポットインスタンスを利用してEMRクラスタを組んでみます。マスターインスタンスグループ、コアインスタンスグループをそれぞれ1台、タスクインスタンスグループを2台起動するものとします。それぞれスポットインスタンスの価格が0.02ドル、もしくは0.01ドルまでであれば利用するようにしてみました。なお、--aliveオプションを付けていて、--terminateオプションを付けて明示的に終了させるまでは勝手に終了してしまうことのないようにしています。
起動リクエストが正しく送信されればレスポンスとしてジョブフローID(j-xxxxx)が表示されます。ステップの追加や終了指示などはこのジョブフローIDに対して行うことになります。
EMRクラスタが起動したら※33、EC2インスタンスのときと同じようにしてマスターノードにSSHログインすることができます。ただし、ユーザ名はec2-userではなくhadoopなので注意してください。
※33 AWSコンソール上もしくはelastic-mapreduce --listでWAITINGと表示されれば起動が完了しています
もしくはジョブフローを指定してelastic-mapreduceコマンドの--sshオプションでログインすることも可能です。
ログインするとこのような画面が表示されると思います。
なお、起動したジョブフローの状況は--listオプションで見ることが出来ます。--activeオプションを付けて現在アクティブなものだけを表示したり、--describeオプションでより詳細な情報を見たりすることも可能です。
ジョブフローの一覧ではさきほどAWSコンソールから起動して現在は停止しているジョブフローの情報も表示されていますが、--activeオプションを付けると現在起動しているジョブフローの情報だけに絞られていることがわかります。
| オプション | 説明 | 例 | |
|---|---|---|---|
| --list | 直近2日以内に作成されたジョブフローの一覧を表示する | ||
| --describe | ジョブフローの詳細な構成内容をJSON形式で表示する | ||
| --print-hive-version | 現在稼働中のHiveのバージョンを表示する | ||
| --state NAME | 出力するジョブフローの状態を指定する | WAITING | |
| --active | STARTING,WAITING,SHUTTING_DOWNな状態のジョブフローの一覧を表示する | ||
| --all | 直近2 ヶ月以内のすべてのジョブフローの一覧を表示する | ||
| --created-after DATETIME | 指定した日時以降に作成されたジョブフローの一覧を表示する | 2012-07-18T18:00:00 | |
| --created-before DATETIME | 指定した日時以前に作成されたジョブフローの一覧を表示する | 2012-07-18T18:00:00 | |
| --no-steps | ジョブフローの一覧を表示する際にステップ一覧を表示しない | ||
さて、ではこのジョブフローに対してステップを登録してみます。動作確認として、さきほどのAWSコンソール上とまったく同じステップをWordCountという名前で追加してみましょう。このような形になります。複雑そうに見えますが、--inputオプション、--mapperオプション、--reducerオプションの値はあらかじめEMR側で用意されているものを利用しているだけです。
ステップ追加時のオプションも簡単にまとめておくので参考にしてください。
| オプション | 説明 | 例 | |
|---|---|---|---|
| --stream | Hadoop Streamingを実行するときに指定する | ||
| --input INPUT | 入力データのフルパスを指定する | s3n://path/to/input | |
| --output OUTPUT | 結果ファイルの出力先を指定する | s3n://path/to/output | |
| --mapper MAPPER | Mapperのフルパスを指定する | ||
| --reducer REDUCER | Reducerのフルパスを指定する | ||
| --cache CACHE_FILE | キャッシュにロードすべきファイルを指定する | s3n://mybucket/hoge#hoge | |
| --cache-archive CACHE_FILE | キャッシュにアンパックすべきファイルを指定する | s3n://mybucket/sample.jar | |
| --jobconf KEY=VALUE | Hadoopに渡したい変数とその値を指定する | mapred.task.timeout=800000 | |
| --step-name STEP_NAME | ステップの名前を指定する | ||
| --step-action STEP_ACTION | ステップの異常発生時に取るべきアクションを指定する | ||
これで先ほどと同じようなワードカウントのHadoopジョブがステップとして登録されました。他に実行を待っているステップも無いので、このステップはすぐに実行されます。ジョブフローの情報を見てみれば、WorldCountというステップがこのジョブフローに対して登録されていることも確認できると思います。
なお、EMRでもネームノードやジョブトラッカーの進捗状況などをブラウザから確認できるのですが、通常のHadoopの場合とはポート番号が異なるので注意してください。
| ジョブトラッカー | ネームノード | |
|---|---|---|
| 通常のHadoopでのポート番号 | 50030 | 50070 | 
| EMRでのポート番号 | 9100 | 9101 | 
さらに、AWS上ではEC2であれEMRであれ、基本的にはポートは閉じられています。実はEMRを利用する場合には「ElasticMapReduce-master」と「ElasticMapReduceslave」というセキュリティグループが自動的に作成され、マスターノード(マスターインスタンスグループ)にはElasticMapReduce-masterが、スレーブノード(コアインスタンスグループやタスクインスタンスグループ)にはElasticMapReduce-slaveがセキュリティグループとして自動的に設定されています。この閉じられた状態でどのようにブラウザから確認するのかについては「4.4 ブラウザから進捗を確認する」で説明します。ちなみにElasticMapReduce-masterとElasticMapReduce-slaveとの間ではすべての通信が自由に行えるようになっています。
さて、結果が指定したディレクトリ(今回だとs3n://sasata299/output/2012-07-19/)に出力されているはずなので確認しておきましょう。AWSコンソールでの実行時と同じようにこのような結果が出力されているはずです。
最後に、ジョブフローを終了させたいときには--terminateオプションで停止することができます。ジョブフローを停止することで内部で動いているEC2のインスタンスも停止するため、停止が完了すれば課金されない状態となります。
| オプション | 説明 | 例 | |
|---|---|---|---|
| --jobflow JOB_FLOW_ID | ジョブフローIDを指定する | ||
| --terminate | 指定したジョブフローを終了する | ||
| --set-termination-protextion BOOL | 指定したジョブフローの終了保護モードを有効または無効にする | TRUE | |
もし、あなたが「“ビッグデータプロジェクト”を任せる。何とかするように」と言われたら
Hadoopは「難しい・遅い・使えない」? 越えられない壁がある理由と打開策を整理する
いまさら聞けないHadoopとテキストマイニング入門
欧米の金融業界は今、どうHadoopを活用しているかCopyright © ITmedia, Inc. All Rights Reserved.