こんにちは、ロジカル・アーツの井川です。
今日は、AWS EMR について紹介していきたいと思います。
AWS EMRとは?
EMRドキュメント によると、EMRは以下のように説明されています。 要するに、機械学習等で用いられる分散フレームワークのApache Spark や Apache Map Reduce等が使える、AWSのマネージドサービスになります。
Amazon EMR は、AWS でビッグデータフレームワーク (Apache Hadoop や Apache Spark など) の実行を簡素化して、大量のデータを処理および分析するマネージド型>クラスタープラットフォームです。これらのフレームワークと関連するオープンソースプロジェクト (Apache Hive や Apache Pig など) を使用することで、分析用のデ>ータやビジネスインテリジェンスワークロードを処理できます。さらに、Amazon EMR を使用して大量のデータを変換し、Amazon Simple Storage Service (Amazon S3) >や Amazon DynamoDB などの他の AWS データストアおよびデータベースとの間で移動することもできます。
- AWS EMRとは?
- 実際に触ってみる
- ステップ 1: 環境を整える
- ステップ 2: EMR環境構築のための準備
- ステップ 3: EMRリソースを構築する
- ステップ 4: 動作確認
- まとめ
- 参考サイト
EMR 6.0.0の紹介
EMRはApache Spark等の分散フレームワークを使うことができるのですが、チームで Pythonや R ライブラリの依存関係を管理するのが難しいことがあります。 そのような課題を解決してくれるのが、EMR 6.0.0です。EMR 6.0.0はDockerを用いてライブラリの依存関係を管理することができるため、環境の違いを気にする必要がありません。 以下では、EMR 6.0.0 を用いたハンズオンを行います。
実際に触ってみる
今回は AWSの公式ブログを参考にハンズオンを進めていきたいと思います。
EMR 6.0.0 の Docker を使用して、Spark の依存関係の管理を簡素化する を参考に進めていきたいと思います。
使用するフレームワークはApache Spark、使用言語は Pythonです。
作業環境
私が行う環境は以下の通りです。
項目 | 説明 |
---|---|
PC OS | Windows 10 Professional |
ブラウザ | Chrome |
作業環境(sshでログイン) | Amazon Linux 2 |
リージョン | Tokyo (ap-northeast-1) |
コマンドラインツール | aws-cli, シェルスクリプト(bash) |
分散フレームワーク | Apache Spark |
使用言語 | Python |
留意事項
私の環境では、下記を前提として進めていきます。
- AWS アカウントがある
ステップ 1: 環境を整える
今回はEC2を使って構築するため、EC2をまず最初に準備します。
- Amazon Linux 2
- インスタンスタイプは t2.micro
- "自動割り当てパブリックIP" を有効にする
- IAMロールに AmazonElasticMapReduceFullAccess を割り当てる。
- sshログインを有効にする
ステップ 1.1: EC2にログインする
ssh -i EC2に接続するための秘密鍵ファイルへのパス ec2-user@パブリックIPアドレス
ステップ 1.2: Dockerをインストールする
以下の手順にしたがって、EC2 に Dockerをインストールします。
# Dockerインストール $ sudo yum update -y $ sudo amazon-linux-extras install docker $ sudo service docker start $ sudo usermod -a -G docker ec2-user # ログアウト $ exit # 再ログイン $ ssh -i EC2に接続するための秘密鍵ファイルへのパス ec2-user@パブリックIPアドレス # Dockerがインストールされていることを確認する $ docker info
ステップ 2: EMR環境構築のための準備
ステップ 2.1: 作業ディレクトリを作成
以下のようなディレクトリ、ファイルを作成します。
EMR/ ├── deploy.sh ├── emr-configuration.json ├── pyspark │ └── Dockerfile
ステップ 2.2: pyspark/Dockerfileを作成
サイトに掲載されているDockerfileをそのまま活用します。
FROM amazoncorretto:8 RUN yum -y update RUN yum -y install yum-utils RUN yum -y groupinstall development RUN yum list python3* RUN yum -y install python3 python3-dev python3-pip python3-virtualenv RUN python -V RUN python3 -V ENV PYSPARK_DRIVER_PYTHON python3 ENV PYSPARK_PYTHON python3 RUN pip3 install --upgrade pip RUN pip3 install numpy RUN python3 -c "import numpy as np"
ステップ 2.3: deploy.shを作成
Dockerイメージ及びEMRクラスターの構築作成用シェルスクリプト
#!/bin/bash readonly region="ap-northeast-1" readonly account="AWS Account ID" readonly repository="pyspark" readonly image="pyspark:latest" readonly EC2KeyPair="EC2 に接続するためのキーペア" readonly public_subnet_id="Public Subnet ID" echo "region : ${region}" echo "account : ${account}" echo "repository : ${repository}" echo "image : ${image}" echo "EC2KeyPair : ${EC2KeyPair}" echo "public_subnet_id : ${public_subnet_id}" ################## # Docker setting # ################## # build docker build -t ${image} pyspark/ docker tag ${image} ${account}.dkr.ecr.${region}.amazonaws.com/${repository}:latest # push aws ecr describe-repositories --repository-names ${repository} --region ${region} > /dev/null 2>&1 if [ $? -ne 0 ] ; then aws ecr create-repository --repository-name ${repository} --region ${region} > /dev/null fi $(aws ecr get-login --region ${region} --no-include-email) docker image push ${account}.dkr.ecr.${region}.amazonaws.com/${repository}:latest ###################### # create EMR cluster # ###################### sed -e "s/%Region%/${region}/g" \ -e "s/%Account%/${account}/g" \ -e "s/%Repositry%/${repository}/g" \ emr-configuration.json > after.json aws emr create-cluster \ --name 'EMR 6.0.0 with Docker' \ --release-label emr-6.0.0 \ --applications Name=Livy Name=Spark \ --ec2-attributes "KeyName=${EC2KeyPair},SubnetId=${public_subnet_id}" \ --instance-type m5.xlarge \ --instance-count 3 \ --use-default-roles \ --configurations file://./after.json # success echo -e "\033[34msuccessfully deployed!!\033[0m"
ステップ 2.4: emr-configuration.jsonを作成
EMRクラスターの設定ファイル
[ { "Classification":"container-executor", "Properties":{ }, "Configurations":[ { "Classification":"docker", "Properties":{ "docker.privileged-containers.registries":"local,centos,%Account%.dkr.ecr.%Region%.amazonaws.com", "docker.trusted.registries":"local,centos,%Account%.dkr.ecr.%Region%.amazonaws.com" } } ] }, { "Classification":"livy-conf", "Properties":{ "livy.spark.master":"yarn", "livy.spark.deploy-mode":"cluster", "livy.server.session.timeout":"16h" } }, { "Classification":"hive-site", "Properties":{ "hive.execution.mode":"container" } }, { "Classification":"spark-defaults", "Properties":{ "spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE":"docker", "spark.yarn.am.waitTime":"300s", "spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE":"docker", "spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG":"hdfs:///user/hadoop/config.json", "spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE":"%Account%.dkr.ecr.%Region%.amazonaws.com/%Repositry%:latest", "spark.executor.instances":"2", "spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG":"hdfs:///user/hadoop/config.json", "spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE":"%Account%.dkr.ecr.%Region%.amazonaws.com/%Repositry%:latest" } } ]
ステップ 3: EMRリソースを構築する
ステップ 3.1: IAM Roleを作成する
以下のようにして、必要なIAM Roleを作成します。
~ $ aws emr create-default-roles ~ $ aws iam attach-role-policy --role-name EMR_EC2_DefaultRole --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
作成されたIAM Roleの内容は以下のようになっています。
EMR_EC2_DefaultRole
クラスターインスタンスに対して Hadoop エコシステム上で実行されるアプリケーションプロセスは、このロールを使用して AWS の他のサービスを呼び出します。EMRFS を使用して Amazon S3 のデータにアクセスする場合は、リクエスト元のユーザーやグループ、または Amazon S3 のデータの場所に応じて引き受けるロールを指定できます。
ポリシーARN
arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceforEC2Role
信頼されたエンティティ(EC2に権限を付与)
{ "Version": "2008-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
EMR_DefaultRole
リソースをプロビジョニングしてサービスレベルのアクションを実行する際にユーザーに代わって AWS の他のサービスを呼び出すことを Amazon EMR に許可します。このロールは、すべてのクラスターに必須です。
{ "Version": "2008-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "elasticmapreduce.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
EMR_AutoScaling_DefaultRole
以下ポリシーによって、動的なスケーリング環境用の追加のアクションを許可します。Amazon EMR で Auto Scaling を使用するクラスターでのみ必須です。
ポリシーARN
arn:aws:iam::aws:policy/service-role/AmazonElasticMapReduceforAutoScalingRole
信頼されたエンティティ(EMRとApplication AutoScalingに権限を付与)
{ "Version": "2008-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": [ "elasticmapreduce.amazonaws.com", "application-autoscaling.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }
ステップ 3.2: deploy.sh を実行する
deploy.shを実行し、EMRクラスターを構築します。
~ $ cd ~/EMR EMR $ source deploy.sh
ステップ 3.3: AWS EMRへログイン
クラスターが起動し、待機状態になったら、クラスターホストがAmazon ECRに対して自身を認証し、Dockerイメージをダウンロードできることを確認します。 クラスターのコアノードの 1 つに SSH を接続します。
# このコマンドは、config.json ファイルを /root/.docker フォルダ内に作成します。 ~ $ ssh -i deploy.shで指定したEMRログイン用の秘密鍵ファイルパス ec2-user@パブリックIPアドレス ~ $ sudo usermod -a -G docker ec2-user ~ $ exit ~ $ ssh -i deploy.shで指定したEMRログイン用の秘密鍵ファイルパス ec2-user@パブリックIPアドレス ~ $ $(aws ecr get-login --region ap-northeast-1 --no-include-email) # 次のコマンドを使用して、作成した config.json ファイルを HDFS がある場所の /user/hadoop/ に配置します。 ~ $ sudo hdfs dfs -put ~/.docker/config.json /user/hadoop/
ステップ 3.4: ノートブックを作成する
AWS EMRコンソールにて、以下のようにしてノートブックを作成します。
ステップ 4: 動作確認
PySparkが実行できるかどうかを確認してみましょう。
ノートブックが準備完了ステータスになったら、JupyterLabで開く ボタンをクリックすると、新しいブラウザータブで開くことができます。ご自分の EMR Notebook の名前が付いた既定のノートブックが、デフォルトで作成されます。そのノートブックをクリックすると、カーネルを選択するように求められます。PySpark をクリックします。
ノートブックの最初のセルに以下を書き込みます。
%%configure -f {"conf": { "spark.pyspark.virtualenv.enabled": "false" }}
ノートブックの2つめのセルに以下を書き込みます。
from pyspark.sql import SparkSession spark = SparkSession.builder.appName("docker-numpy").getOrCreate() sc = spark.sparkContext import numpy as np a = np.arange(15).reshape(3, 5) print(a) print(np.__version__)
実行結果が以下のようになれば成功です。このPySparkコードは、YARN、Docker、作成した pysparkイメージを使用して、EMR6.0.0 クラスターで実行したものです。 そして、EMR Notebooksは、Apache Livyを利用してEMRクラスターに接続します。
まとめ
長くなりましたが、いかがでしたでしょうか。私も AWS EMR を検証の段階でしたので、まとめるのに苦慮しました。説明に不備や誤りがありましたらご指摘ください。また、不明点があれば、元サイト もおすすめです。とても丁寧にまとめられていて理解が浅い私でも進めやすかったです。
所感として、機械学習等で使うデータを用意するための前段階処理として、使われることの多いApache SparkやMap Reduceが、手軽に使えるようにマネージドされたサービスという印象です。
参考サイト
https://d1.awsstatic.com/webinars/jp/pdf/services/20191023_AWS-Blackbelt_EMR.pdf
https://docs.aws.amazon.com/ja_jp/emr/latest/ManagementGuide/emr-what-is-emr.html
https://www.atmarkit.co.jp/ait/articles/1608/24/news014.html