楽屋

embulkでRedshiftにデータを取り込む

この記事について

embulkでRedshiftにデータを取り込む方法について解説します。

どうしてembulkを使うのか

まず、Redshiftにデータを取り込む際には、大きく分けて、embulkで取り込む方法と、RedshiftのCOPYコマンドで取り込む方法の2つが考えられます。embulkを使うメリットデメリットは下記のとおりです。
  • メリット
    • データのチェック機能があり、汚いデータをインポートするのに強い。
    • 元のcsvファイルなどから、特定の条件に該当するレコードのみをインポートするなど、条件抽出もできる。
  • デメリット
    • 処理がCOPYコマンドに比べて遅い(内部的にはデータのチェック=>COPYの実行を行っているので)。特に大きなデータを扱う際にその速度差が顕著に出る。
このように、汚いデータ(数値として取り込みたい列に文字列が入っているなど)を取り込む際や、元ファイルから特定の条件に該当するレコードのみインポートしなければいけないなどにembulkは強みを発揮します。 注意: 以下は、「embulkを使って、s3に置いたデータファイルをRedshiftにインポートする」ことを前提に書きます。本来embulkの良いところは同じymlファイルの記法を覚えるだけで多種多様なDBへのデータ転送が行える点にありますが、本記事ではそれらについで触れません。

embulkでデータを取り込むのに何が必要か

embulkの実行には、
  • embulkのインストール
  • 必要なembulkのプラグインのインストール
  • 設定ファイル※
が必要になります。 ※embulkの設定ファイルは.yml(yaml、ヤムル)というファイル形式で記述できます。具体的な方法は後述します。

ymlファイルの書き方

embulkの設定ファイル、yamlファイルの書き方について先に解説します。 先にymlファイルの実例を示した上で、各部の構造について書きます。

ymlファイルのサンプル

ymlファイルの構造

見て気づいたかもしれませんが、embulkのyamlは大きく分けて、in:, out:, filters:に分けられます(今回のサンプルコードの場合)。in:out:部分は必須で 、必要に応じてfilters:部分を記述します。 それぞれの部分の記述法について個別に解説します。

in:

in:部分では、embulkでインポートするファイルの情報を記載します。 今回の場合は、s3上にあるcsvファイルを指定しているので、type:オプションをs3に指定した上で、bucket:,path_prefix:,endpoint:, access_key_id:, secret_access_key:オプションを設定します。 embulkを実行する前に、embulk-input-s3 プラグインがインストールされていることを確認しましょう(インストール方法は後述)。 各オプションの設定方法は下記の通りです。 本来はそれ以下のオプションも当然指定しなければならないのですが、guessコマンドを使って手順を簡略化できます。
guessコマンドについて
guessコマンドは、取り込むファイル(の先頭の一部分)を取得し、yml ファイルのin:部分の適切な設定を書いてくれます。 例えば、ファイル形式や文字コード、区切り文字、ヘッダの有無、それぞれの列のデータ型なども自動で判定してくれます。 下の実行コマンドサンプルでは、before.ymlというファイルにguessコマンドを適用し、after.ymlというファイルに結果を出力しています。
オプション設定項目
bucket:対象のファイルが置いてあるs3のバケット
path_prefix:対象のファイルのs3内のパス
endpoint:対象のファイルが置いてあるs3のエンドポイント
access_key_id:対象のファイルが置いてあるAWSアクセスキー
secret_access_key:対象のファイルが置いてあるAWSシークレットアクセスキー
1
bundle exec embulk guess before.yml -o after.yml
guessコマンドを使ったあとのチェックポイント
本来は、guessコマンドによって追記された部分全てをチェックするべきですが、下記はチェックすべきです。
  • columns:のnameに必要なカラムが網羅されているか。
  • columns:のnameが取り込みたいデータ形式になっているか。このデータ形式に一致しないデータは取り込まれない。ただし、columnsはあくまでもJavaのデータ型であることに注意してください。 Javaのdoubleには入るけど、redshiftのDOUBLE PRECISION型に入らないようなデータというものが存在します。例えば、Javaのdouble型では文字列のNaNを格納できますが、RedshiftのDOUBLE PRECISION型にはNaNを格納できません(エラーが出てembulkの処理が終了する) columns: で使えるデータ型はこちらを参照してください。

out:

outは、出力するredshiftの情報と、embulkを処理する際に発生する一時ファイル(データをチェックし、redshiftに格納される前のデータ)の置き場所となるs3のバケットを指定できます。 まず、type:にRedshiftを指定した上で、接続先となるredshiftの情報を記述しましょう。
オプション設定項目
host:接続先のホスト名
user:接続するユーザ名
password:接続するユーザ名のパスワード
database:接続するDB
table:取り込んだデータを格納するテーブル名
mode:新規にテーブルを作成するならばinsertで大丈夫です
他のモードの詳細はこちら
オプション設定項目
column_options:このオプションで、取り込むデータのカラム名・データ型を指定できます。ここのデータ型は Redshiftのデータ型をそのまま指定できます。下記のオプションは、embulkを処理する際に発生する一時ファイルの置き場所となるs3のバケットを指定するオプションです。書き込み権限があるIAMユーザ名とバケット名の組み合わせを指定してください。
access_key_id:対象のバケットにアクセスできるAWSアクセスキー
secret_access_key:対象のバケットにアクセスできるAWSシークレットアクセスキー
iam_user_name:対象のバケットにアクセスできるIAMユーザ名
s3_bucket:一時ファイルを保存するバケット名
s3_key_prefix:一時ファイルを保存するs3内のパス

filters:

filtersオプションは毎回指定する必要があるものではありませんが、指定することで、取り込みたいファイルの中で、特定の条件に該当するレコードのみ抽出してインポートすることができます。
オプション設定項目
type:オプションにrowを指定した上で、下記のオプションを設定しましょう。また、embulkを実行する前に、embulk-filter-row プラグインがインストールされていることを確認しましょう(インストール方法は後述)
condition:ANDもしくはORを指定する。下記conditions:に記述した条件に対する論理結合になります
conditions:各カラムについて、operatorに演算子、argument:に値を入力することで抽出条件を指定できます。文字列の場合は、START_WITH, IS NOT NULLなどの演算子、数値型の場合は、>, <=などの演算子が利用できます。具体的な使用できる抽出条件とデータ型の一覧は公式ドキュメントを参照してください
  1. 準備 embulkをインストールし、3つのembulkプラグイン embulk-input-s3 , embulk-output-redshift, embulk-filter-row をインストールしましょう(手順はこちら)。 また、特定の条件で入力ファイルの一部のみ ※以下、bundler経由でembulkを使用することを前提に書いています。 ymlファイルを記述する。必要に応じてguessコマンドを使いましょう。

  2. エラーが出ないかチェックする。embulk previewコマンドを使うことで、取り込み対象のcsvファイルの一部にだけ処理を実行し、その結果を見ることができます。ここで、ほしい形でデータが取り込めそうか確認しましょう。

  3. embulkを実行しましょう。実際にembulkによるデータの取り込みを行う際には、下記のコマンドを実行しましょう。

  4. 参考記事