この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
CX事業本部の高橋雄大です。
2019年8月28日にGlue ETLライブラリのバイナリがリリースされました。このリリースにより、ローカルの開発環境でGlueのETLスクリプトを実行出来るようになりました。
AWS Glue、Glue ジョブ用 Glue ETL ライブラリのバイナリをリリース
目次
開発環境
項目 | バージョン | 備考 |
---|---|---|
macOS | Mojave 10.14.6 | |
AWS CLI | 1.16.233 | |
Apach Maven | 3.6.2 | Mavenをダウンロード |
Java Development Kit 8 (JDK) | 1.8 | JDKをダウンロード |
Apache Spark | 2.2.1 | Sparkをダウンロード |
Python | 2.7.1 | |
LocalStack | 0.10.2 | LocalStack |
環境変数を設定します。MavenとSparkのパスは個人の環境に合わせて変更してください。
echo 'export PATH=$HOME/.apache-maven-3.6.2/bin:$PATH' >> ~/.bash_profile
echo 'export SPARK_HOME=$HOME/.spark-2.2.1-bin-hadoop2.7' >> ~/.bash_profile
echo 'export JAVA_HOME=`/usr/libexec/java_home -v 1.8`' >> ~/.bash_profile
Pythonでローカル開発
AWS Glue Pythonライブラリを取得
GitHubからAWS Glue Pythonライブラリをダウンロードします。以降の作業はAWS Glue Pythonライブラリのルートディレクトリで行います。
https://github.com/awslabs/aws-glue-libs
PySparkをインストール
pipコマンドでpysparkパッケージをインストールします。
$ pip install pyspark
Apache Sparkの環境設定
Sparkの設定ファイルを作成します。DynamoDBとS3のエンドポイントをLocalStackに向けます。
conf/spark-defaults.conf
spark.hadoop.dynamodb.endpoint http://localhost:4569
spark.hadoop.fs.s3a.endpoint http://localhost:4572
spark.hadoop.fs.s3a.path.style.access true
spark.hadoop.fs.s3a.signing-algorithm S3SignerType
PythonでETLスクリプトを作成
DynamoDBから全ての項目を取得して、S3バケットに格納するスクリプトを作成してみます。
src/sample.py
import sys
from awsglue.transforms import ApplyMapping
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job
from awsglue.dynamicframe import DynamicFrame
DYNAMODB_INPUT_TABLE_NAME = 'aws-glue-local-test-table'
S3_OUTPUT_BUCKET_NAME = 'aws-glue-local-test-bucket'
args = getResolvedOptions(sys.argv, [
'JOB_NAME'
])
JOB_NAME = args['JOB_NAME']
sc = SparkContext()
glueContext = GlueContext(sc)
job = Job(glueContext)
job.init(JOB_NAME, args)
datasource = glueContext.create_dynamic_frame.from_options(
connection_type='dynamodb',
connection_options={
'dynamodb.input.tableName': DYNAMODB_INPUT_TABLE_NAME
}
)
applymapping = ApplyMapping.apply(
frame=datasource,
mappings=[
('Id', 'string', 'Id', 'string'),
('Column1', 'string', 'Column1', 'string'),
('Column2', 'string', 'Column2', 'string'),
('Column3', 'string', 'Column3', 'string')
]
)
glueContext.write_dynamic_frame.from_options(
frame=datasource,
connection_type='s3',
connection_options={
'path': 's3://' + S3_OUTPUT_BUCKET_NAME
},
format='csv'
)
job.commit()
ETLスクリプトの実行
LocalStackの準備
docker-compose
でLocalStackを立ち上げます。
docker-compose.yml
version: "3.3"
services:
localstack:
container_name: localstack
image: localstack/localstack
ports:
- "8080:8080"
- "4569:4569"
- "4572:4572"
environment:
- DOCKER_HOST=unix:///var/run/docker.sock
- DEFAULT_REGION=ap-northeast-1
- SERVICES=dynamodb,s3
$ docker-compose up -d
DynamoDBテーブルの準備
DynamoDBのテーブルを作成します。
$ aws dynamodb create-table \
--table-name aws-glue-local-test-table \
--attribute-definitions \
AttributeName=Id,AttributeType=S \
--key-schema AttributeName=Id,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 \
--endpoint-url http://localhost:4569
テスト用のデータを登録します。
$ aws dynamodb put-item \
--table-name aws-glue-local-test-table \
--item \
'{"Id": {"S": "test"}, "Column1": {"S": "test1"}, "Column2": {"S": "test2"}, "Column3": {"S": "test3"}}' \
--endpoint-url http://localhost:4569
S3バケットの準備
S3のバケットを作成します。
$ aws s3api create-bucket \
--bucket aws-glue-local-test-bucket \
--endpoint-url http://localhost:4572
実行コマンド
AWS Glue Pythonパッケージのルートディレクトリで以下のコマンドを実行できます。
コマンド | 説明 |
---|---|
./bin/gluepyspark | ライブラリと統合するシェルにPythonスクリプトを入力して実行します。 |
./bin/gluesparksubmit | Pythonスクリプトを指定して実行します。 |
./bin/gluepytest | Pythonの単体テストを実行します。pytestモジュールが必要です。 |
動作確認
認証情報が設定されていないとエラーになるので、環境変数をセットしておきます。
$ export AWS_ACCESS_KEY_ID='dummy'
$ export AWS_SECRET_ACCESS_KEY='dummy'
$ export AWS_REGION='ap-northeast-1'
Pythonスクリプトを指定して実行します。--JOB_NAME
は必須なのでdummy
をセットしておきます。初回の実行時はGlue ETLライブラリのバイナリをダウンロードしてくるので、多少時間がかかります。
$ ./bin/gluesparksubmit ./src/sample.py --JOB_NAME='dummy'
S3バケットにCSVファイルが作成されていることを確認します。
$ aws s3api list-objects \
--bucket aws-glue-local-test-bucket \
--endpoint-url http://localhost:4572
S3からローカルにダウンロードして内容を確認します。
$ aws s3 cp s3://aws-glue-local-test-bucket ~/Downloads/aws-glue-local-test-bucket \
--recursive \
--endpoint-url http://localhost:4572
最後に
AWS Glueの開発において、今まで時間がかかっていたデバッグ作業が改善できました。pytestで単体テストを実装することもできるので、AWS環境へデプロイ前に簡単な動作確認ができそうです。Glue Python ETLライブラリは発展途上で、まだ不足している機能がたくさんあります。今後のアップデートに期待しています。
参考
Developing and Testing ETL Scripts Locally Using the AWS Glue ETL Library