dockerでデータのバッチ処理をしてみる

dockerについて

dockerについては、ここでは詳しく解説しません。

あまりご存知ない方は、以下の記事を参照してください。

【docker】基本的なコマンドと使い方

対象者

  • dockerとはなにか知っている方
  • dockerの操作がある程度できる方

さっそくやってみる

以下の手順でやっていきます。

  1. サンプル用データを用意する
  2. データ処理用のpythonファイルを作成する
  3. Dockerfile、docker-compose.yml、requirements.txtを作成する
  4. image、コンテナを作成する
  5. docker runしてみる

1. サンプル用データを用意する

以下のサンプルデータを使っていきます。

AWSのS3に上記データを保存して処理したものを、同じくS3の別のフォルダに吐き出すようにしていきます。

S3の構成としては、以下のようにしました。inputフォルダに上記データを入れ、outputフォルダには処理したデータが入るようにします。

またローカルのフォルダ構成は、以下のようにしました

各ファイルをそれぞれ作っていきます。

データ処理用のpythonファイルを用意する

今回は、ファイルのheaderの名前を日本語から英語に変更するpythonファイルを作成し、コンテナ上で処理させます。

optフォルダの中に「column_re.py」を作成し、下記の内容を記載していきます。

# -*- coding: utf-8 -*-
import pandas as pd
import boto3
import io
import json
import sys

# 引数指定
header_transform_rule = sys.argv[1]
src_bucket_name = sys.argv[2]
src_key_name = sys.argv[3]
dest_bucket_name = sys.argv[4]
dest_key_name = sys.argv[5]

# header_transform_rule.jsonを読み込み
header_transform_rule=open(f'{header_transform_rule}', 'r')
header_transform_rule=json.load(header_transform_rule)

# src読み込み
s3 = boto3.client('s3')
src_object_body = s3.get_object(Bucket=src_bucket_name, Key=src_key_name)['Body'].read().decode('utf-8')

# header変換処理
buffer_in = io.StringIO(src_object_body)
df_in = pd.read_csv(buffer_in)
df_out = df_in.rename(columns=header_transform_rule)
buffer_out = io.StringIO()
df_out.to_csv(buffer_out, index=False)

# dest書き出し
body_out = buffer_out.getvalue()
dest_object_body = s3.put_object(Bucket=dest_bucket_name, Key=dest_key_name, Body=body_out)
print ("successed")

同じくoptフォルダの中に「header_transform_rule.json」ファイルを作成し、下記の内容を記載していきます。

{
	"日付": "date",
	"チャネル": "channel",
	"媒体": "medium",
	"訪問数": "session",
	"ページビュー": "pageview",
	"離脱数": "bounce",
	"滞在時間": "session_duration",
	"直帰数": "exits",
	"ユーザー数": "users",
	"新規ユーザー数": "new_users",
	"コンバージョン数": "conversions"
}

Dockerfile、docker-compose.yml、requirements.txtを作成する

続いて、設定ファイルを作成していきます。

python3のimageを元にコンテナを作成していきます。

https://hub.docker.com/_/python

Dockerfile

FROM python:3
USER root

RUN apt-get update && apt-get install -y --no-install-recommends \
	curl \
	unzip

RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip
RUN ./aws/install

RUN pip install --upgrade pip
RUN pip install --upgrade setuptools

COPY ./requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

ENTRYPOINT ["python", "column_re.py"]

S3にアクセスするので、CLIV2をコンテナ内にインストールしておきます。また必要なパッケージはrequirements.txtに記載してインストールするようにします。pythonファイルをrunしたときに実行できるようにしたいので、ENTRYPOINTでpythonファイルを指定します。

docker-compose.yml

version: '3'
services:
  python3:
    build: .
    container_name: 'python3'
    working_dir: '/root/opt'
    tty: true
    volumes:
      - ./opt:/root/opt
      - $HOME/.aws:/root/.aws

実行時に色々引数指定してbuildするのが面倒なので、composeで処理する方が私は好きです。

実行ファイル(optフォルダ)は、マウントで置いていきます。また、aws認証用ファイルを置くことを忘れずに。awscliをローカルにインストールしていれば、.awsフォルダをそのままマウントすればいけます。

requirements.txt

pandas
boto3

必要なパッケージを記載します。今回は、pandasとboto3の2つぐらいで十分です。

image、コンテナを作成する

以上で準備が完了したので、image、コンテナを作成していきます。

testフォルダ配下(ルート配下)で、buildしてimageとコンテナを作ります。

docker compose up -d --build

image作られているか、コンテナが起動したか確認します。

docker images
docker ps -a

docker runしてみる

実際に動作確認していきます。

docker runで、s3のinputフォルダ配下のcsvデータが処理されて、outputフォルダに格納されるか確認します。

docker-compose run python3 ./header_transform_rule.json <src対象のバケット名> <src対象のファイルパス> <dest対象のバケット名> <dest対象のファイルパス>

「successed」

とでてきたら、処理成功です。

s3のoutputフォルダに格納されているか、s3 selectで中身も確認します。

問題なく実行されていることが確認できました。

まとめ

dockerいいですね!非常に便利です。

コンテナをうまく活用すれば、環境構築で悩むことがほとんどなくなります。

環境構築は人に左右されることもあり、非常に時間かかるし、面倒だったのでこれからはdockerをフル活用していこうと思います。

今回のソースは以下に格納しております。参考までに。

https://github.com/takuma11248250/test_ecs

次は、ECSについて書きます。

ABOUTこの記事をかいた人

株式会社メンバーズ データアドベンチャー所属 データエンジニアとしてデータ基盤の構築から運用を行っております。 得意なことは、データ活用推進です。 日々の学びをアウトプットしていきます。