AWS‎ > ‎

Amazon Elastic MapReduce のセットアップ

遅まきながら。

総じて

使用感は通常の S3 ブートの EC2 インスタンスへアクセスするのと大差なく、専用ツールやライブラリを使うものの、実装的にはキーペアを用いた SSH による通信で Hadoop の管理層に指示を出しているようです。当然、インスタンスが消えたらディスク上のデータも消えます。

右記の図を見ると、キーペアを使っていないように見えます。てっきり “Master” と SSH で通信しているのだと思ったのですが、elasticity|Elasticity もキーペアなんか使っていないし…まあいいか、どっちでも ∥ Architectural Overview of Amazon EMR - Amazon Elastic MapReduce

…よく考えると、SSH なんか使ったら、SSH クライアントが無いとジョブの実行ができないじゃないか。

hbstudy#21 で AWS の中の人曰く、「安いスイッチで組んだ自家製 Hadoop クラスタなんて、20~30 台でサチる。ポート 400 個の高性能スイッチを買って、優秀なインフラエンジニアを雇えるならばよいけれど、そうでないならば EMR をどうぞ」だそうです。あくまでも「中の人曰く」ではあります。

Apache Hadoop との差異

ローカル Hadoop との違いをつらつらと。

EC2 をベースとしているが故の違い

  • 複数ステップを束ねる job flow の考え方がある
  • 基本的に、インスタンスの起動と同時に job flow が走り、終わると全インスタンスは終了する(開発用に、KeepJobFlowAliveWhenNoSteps 指定でもって、インスタンスを起動させたままにもできる)
  • よって、job flow への最初の入力と最終出力には HDFS を使うわけには行かず、S3 を用いる。結果 data locality は効かないので、job flow はデカい方が良かろう

S3 故の実装の違い

  • S3 の multipart upload を用いるためだと思うが、”s3” ファイルシステムの意味合いが OSS 版と異なる。右記曰く「The configuration of Hadoop running on Amazon EMR differs from the default configuration provided by Apache Hadoop. On Amazon EMR, s3n:// and s3:// both map to the Amazon S3 native file system, while in the default configuration provided by Apache Hadoop s3:// is mapped to the Amazon S3 block storage system.」 ∥ File System Configuration - Amazon Elastic MapReduce

導入

入門文書は下記から。

Get Started with Amazon EMR - Amazon Elastic MapReduce

おおよそこの、”Get Started” に従います。

Sign Up and Install the Command Line Interface - Amazon Elastic MapReduce
ここ大事「You can create job flows consisting of multiple steps using the Amazon EMR command line interface (CLI). The Amazon EMR console supports creating only single-step job flows.」

上記で入手したツールを導入します。

$ mkdir ~/emr/
$ cd ~/emr/
$ unzip ~/elastic-mapreduce-ruby.zip
$ export PATH=$PATH:~/emr
余談。以前から何となく疑問だったのですが、AWS のサービス API ってどうせ SSL 経由なのだから、クライアント認証をしたければ、Access Keys や X.509 Certificates といった非対称鍵暗号ではなく、共通鍵暗号で充分なんじゃないんですかね? そもそも、REST API 用の鍵とSOAP API 用の鍵と SSH 用の鍵と CloudFront 用の鍵が別々というのも初心者泣かせですし。

それと、Access Keys って、短かすぎませんか? $EC2_URL を見ると SSL 通信しているから良さそうなものではありますが、ブルートフォースで解けそうです ∥ About AWS Security Credentials

古かったので、「Amazon Webサービス」から、一式削除して作り直し。

ec2_user_id='XXXX-XXXX-XXXX'
ec2_url=https://ap-northeast-1.ec2.amazonaws.com
ec2_access_key='YYYYYYYYYYYYYYYYYYYY'
ec2_secret_key='YyYyYyYyYyYyYyYyYyYyYyYyYyYyYyYyYyYyYyYy'
ec2_cert=~/cert-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ.pem # 今回使わず
ec2_private_key=~/pk-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ.pem # 同上

ec2_rsa_id='my-key' # EC2 のキーペアです(CloudFront のキーではなく)
ec2_rsa_private_key=~/my-key.pem # 同上、秘密鍵ファイルです

s3_log_url='s3n://emr.ayutaya.com/'
ec2_region='ap-northeast-1'

メモ。RSA キーペアの中身を OpenSSL で確認する際のオプションは、以下。

$ openssl rsa -in rsa-********************.pem -text 
$ openssl rsa -pubin -in rsa-********************.pem -text 

秘密鍵の Permission をちゃんとしておきます。

$ chmod og-rwx pk-* *.pem

設定を書き出します。

cat <<EOF > ~/emr/credentials.json
{
    "access-id":     "$ec2_access_key",
    "private-key":   "$ec2_secret_key",
    "key-pair":      "$ec2_rsa_id",
    "key-pair-file": "$ec2_rsa_private_key",
    "log-uri":       "$s3_log_url",
    "region":        "$ec2_region"
}
EOF

テスト

Alive 指定でのインスタンスの起動をします。job flow が割り当てられます。

$ elastic-mapreduce --create --alive
Created job flow j-3I7Y1BU1089WS

しばらくすると “Waiting” になるので、web console なり、下記 CLI コマンドなりで状態を確認できます。

$ elastic-mapreduce --describe --jobflow j-3I7Y1BU1089WS
{
  "JobFlows": [
    {
      "LogUri": "s3n:\/\/emr.ayutaya.com\/",
      "Name": "Development Job Flow (requires manual termination)",
      "BootstrapActions": [],
      "SupportedProducts": [],
      "ExecutionStatusDetail": {
        "EndDateTime": null,
        "CreationDateTime": 1336390423.0,
        "LastStateChangeReason": "Waiting for steps to run",
        "State": "WAITING",
        "StartDateTime": 1336390642.0,
        "ReadyDateTime": 1336390642.0
      },
      "Steps": [],
      "AmiVersion": "latest",
      "JobFlowId": "j-3I7Y1BU1089WS",
      "Instances": {
        "Ec2KeyName": "my-key",
        "Ec2SubnetId": null,
        "InstanceCount": 1,
        "NormalizedInstanceHours": 1,
        "Placement": {
          "AvailabilityZone": "ap-northeast-1b"
        },
        "KeepJobFlowAliveWhenNoSteps": true,
        "SlaveInstanceType": null,
        "MasterInstanceType": "m1.small",
        "MasterPublicDnsName": "ec2-175-41-214-14.ap-northeast-1.compute.amazonaws.com",
        "MasterInstanceId": "i-1b8aec1b",
        "InstanceGroups": [
          {
            "EndDateTime": null,
            "Name": "Master Instance Group",
            "InstanceRole": "MASTER",
            "BidPrice": null,
            "CreationDateTime": 1336390423.0,
            "LaunchGroup": null,
            "LastStateChangeReason": "",
            "InstanceGroupId": "ig-2OOJ4RKCWIC4T",
            "State": "RUNNING",
            "Market": "ON_DEMAND",
            "InstanceType": "m1.small",
            "StartDateTime": 1336390565.0,
            "InstanceRunningCount": 1,
            "ReadyDateTime": 1336390641.0,
            "InstanceRequestCount": 1
          }
        ],
        "TerminationProtected": false,
        "HadoopVersion": "0.20.205"
      }
    }
  ]
}

追加。

$ elastic-mapreduce --jobflow j-3I7Y1BU1089WS --stream
Added jobflow steps

すると、状態が “Running” に。Console では、下 pane の “Steps” で確認できます。

{
  "JobFlows": [
    {
      "LogUri": "s3n:\/\/emr.ayutaya.com\/",
      "Name": "Development Job Flow (requires manual termination)",
      "BootstrapActions": [],
      "SupportedProducts": [],
      "ExecutionStatusDetail": {
        "EndDateTime": null,
        "CreationDateTime": 1336390423.0,
        "LastStateChangeReason": "Running step",
        "State": "RUNNING",
        "StartDateTime": 1336390642.0,
        "ReadyDateTime": 1336390642.0
        ...

とりあえず、忘れず terminate 。

ローカルで Hadoop が動いていれば、連携も可能。参考 ∥ HadoopのファイルシステムとしてS3を利用する

$ hadoop fs -ls s3n://YYYYYYYYYYYYYYYYYYYY:YyYyYyYyYyYyYyYyYyYyYyYyYyYyYyYyYyYyYyYy@emr.ayutaya.com/
Found 9 items
-rwxrwxrwx   1        310 2012-XX-XX 19:15 /2012-XX-XX-10-15-45-5F4E9EB35537EA06
-rwxrwxrwx   1        368 2012-XX-XX 19:16 /2012-XX-XX-10-16-00-6677FC4636CBF80F
-rwxrwxrwx   1        768 2012-XX-XX 20:16 /2012-XX-XX-11-16-05-A8C439D64B8E1B9C
-rwxrwxrwx   1       7268 2012-XX-XX 21:15 /2012-XX-XX-12-15-47-2A1FB880B18ABCD4
-rwxrwxrwx   1      25052 2012-XX-XX 21:16 /2012-XX-XX-12-16-00-A4C875158568562D
-rwxrwxrwx   1       1879 2012-XX-XX 21:16 /2012-XX-XX-12-16-18-6B6A3E18ABE5528A
-rwxrwxrwx   1        611 2012-XX-XX 21:17 /2012-XX-XX-12-17-42-E86865C855841B84
-rwxrwxrwx   1        304 2012-XX-XX 21:18 /2012-XX-XX-12-18-30-707F79051409C0C8
drwxrwxrwx   -          0 1970-01-01 09:00 /j-3I7Y1BU1089WS

“Get Started” にあるサンプルを実行してみます。文書中では(EMR で言うところの) “s3” を利用していますが、混乱するので、明示的に “s3n” を利用すべきですよね。

elastic-mapreduce --create --stream \
  --mapper  s3n://elasticmapreduce/samples/wordcount/wordSplitter.py \
  --input   s3n://elasticmapreduce/samples/wordcount/input \
  --output  $s3_log_url/log \
  --reducer aggregate

Alive モード

Alive のモードで job flow を起動すれば、ジョブが終了してもクラスタが消えないので、開発者は、SSH でログインして直接に hive (1) コマンドを実行できるようになります。右記参照 ∥ Create a Job Flow Using Hive - Amazon Elastic MapReducehttp://docs.amazonwebservices.com/ElasticMapReduce/latest/GettingStartedGuide/CreateJobFlowHive.html

リンク

内部

外部

Comments