2015年5月13日水曜日

データ転送のOSS「Embulk」を使って、MysqlからデータをCsvに落としてみる

こんにちは、井下です。

ゴールデンウィーク中はほぼ毎日出かけてましたが、おかげで財布が寒いことになってしまいました。もうクールビズ期間になるくらい、気温は上がっているというのに…。


さて、今回はOSSについて取り上げてみようと思います。
メジャーなOSSだけでも、サーバ監視のZabbix、メールサーバのPostfix、クラウド環境を構築できるOpenStack、A-AUTO 50サイトでも利用しているCMSのWordPressなど今や膨大な数になっています。

新しいOSSも次々とリリースされているので、1年もすればメジャーなOSSの数が倍くらいになっているかもしれません。また、消えていくものもたくさんあるので、OSSの選択は重要ですね。

そこで、今回は新しいOSSに着目し、2015/1/27にリリースされたデータ転送のOSS、Embulk(エンバルク)についての紹介と、実際に利用してみます。


Embulkとは

Embulkとは、先に書いたようにデータ転送のOSSですが、特徴としてデータのインプット・アウトプットや、データの加工をプラグインとして拡張することができます。
既に一般的なDBからのインプット・アウトプットのプラグインや、Amazon S3からのインプット・アウトプとのプラグインが利用できるようになっています。

プラグイン一覧:http://www.embulk.org/plugins/


ご存知の方も多いと思いますが、同様の特徴を持つfluentdというOSSがあります。
Embulkはfluentdのバッチ版として位置づけられ、サーバに常駐してリアルタイムでログを送信するfluentdに対し、Embulkは定期実行や一度だけの実行に利用するものとされています。

例えばDBからcsvファイルとしてデータを落としたいものの、日次で取得できれば十分な場合などに使えそうですね。


とりあえず試してみたい方は下記のテスト実行手順を参考にしてみてください。サンプルデータの作成コマンドが用意されているので、試してみる敷居は低くなっています。
https://github.com/embulk/embulk#trying-the-example


ここからは、実際にDB(より具体的に言うとMysql)から、csvファイルとしてデータを落としてみます。
ちなみに今回はEmbulkの仕組みや、設定に関して詳しい説明はしません。(分かりやすい解説サイトもたくさんありますので…)
Embulkを使ってみて、こんなことができるだなという感じを掴んでもらればいいなと思っています。


実際にやってみる

特徴として挙げたように、Embulkはプラグインによってインプットやアウトプットの幅を広げることができます。
まず、WordPressのDBとして利用されているMySQLからデータを抜き出せるように、"embulk-input-mysql"をインストールします。

[embulk]# embulk gem install embulk-input-mysql
2015-05-11 02:32:29.417 -0400: Embulk v0.6.2
Fetching: embulk-input-mysql-0.4.0.gem (100%)
Successfully installed embulk-input-mysql-0.4.0
1 gem installed

これでEmbulkを使ってMysqlのデータを取り出すことができるようになりました。

次にymlファイルを編集します。
ymlファイルとは、Embulk実行時にインプットにするいわば設計図にあたるファイルで、これによってインプットの種類や内容、同様にアウトプットの種類や内容、データの加工方法について記載します。



embulk-input-mysqlを利用する場合、次のように書き起こします。
in:
  type: mysql
  host: localhost
  user: myuser
  password: ""
  database: my_database
  table: my_table
  select: "col1, col2, col3"
  where: "col4 != 'a'"

※embulk-input-mysqlのドキュメントから引用しました


見れば何となく意味が見えてきますね。
接続に必要な情報と、落としたいデータの範囲を指定するだけです。


次はデータを抜き出した後の出力についての書き方ですが、csvファイルへの出力は特別なプラグインは必要ありません。

デフォルトで選択できる出力方法参考サイト:https://gist.github.com/hiroyuki-sato/ec502a7e37ae488e4256

上記のサイトを参考にして、次のように出力の情報を作成してみました。
out:
  type: file
  path_prefix: ./output/mysql_to_csv
  file_ext: csv
  formatter:
    type: csv
    header_line
    charset: UTF-8
    newline: CRLF


最終的なymlファイルは、次のようになりました。
in:
  type: mysql
  host: localhost
  user: XXXXX
  password: XXXXX
  database: embulk
  table: table1
  select: "*"
exec: {}
out:
  type: file
  path_prefix: ./output/mysql_to_csv
  file_ext: csv
  formatter:
    type: csv
    header_line
    charset: UTF-8
    newline: CRLF


これでEmbulkでMysqlからCsvファイルへとデータを転送する準備は整いました。実行する前に、転送元のデータを載せておきます。

mysql> SELECT *  FROM embulk.table1;
+------+-------------------+---------------------+
| id   | content           | timestamp           |
+------+-------------------+---------------------+
|    1 | embulk            | 2015-05-20 11:23:11 |
|    2 | mysql content     | 2015-05-21 09:52:57 |
|    3 | mysql to csv test | 2015-05-24 16:49:10 |
+------+-------------------+---------------------+
3 rows in set (0.00 sec)


それでは、Embulkで実行してみます。
あらかじめ期待する結果が得られるのを確認したいという人のために、実行したらどんな形式でデータが転送されるのか、数行分確認できる「preview」コマンドが用意されていますので、まずはpreviewコマンドで予想される結果を確認してみます。
※"mysql.yml"は上記で記載した"最終的なymlファイル"です

[lib]# embulk preview mysql.yml
2015-05-11 03:31:41.067 -0400: Embulk v0.6.2
2015-05-11 03:31:42.161 -0400 [INFO] (preview): Fetch size is 10000. 
Using server-side prepared statement.
2015-05-11 03:31:42.519 -0400 [INFO] (preview): Fetch size is 10000. 
Using server-side prepared statement.
2015-05-11 03:31:42.530 -0400 [INFO] (preview): SQL: SELECT * FROM `table1`
2015-05-11 03:31:42.533 -0400 [INFO] (preview): > 0.00 seconds
+---------+-------------------+-------------------------+
| id:long |    content:string |     timestamp:timestamp |
+---------+-------------------+-------------------------+
|       1 |            embulk | 2015-05-20 15:23:11 UTC |
|       2 |     mysql content | 2015-05-21 13:52:57 UTC |
|       3 | mysql to csv test | 2015-05-24 20:49:10 UTC |
+---------+-------------------+-------------------------+

どうやらデータは問題なく転送されそうです。


満を持してEmbulkによってデータ転送を実行してみます。

[lib]# embulk run mysql.yml
2015-05-11 03:33:58.533 -0400: Embulk v0.6.2
2015-05-11 03:34:01.068 -0400 [INFO] (transaction): Fetch size is 10000. 
Using server-side prepared statement.
2015-05-11 03:34:01.667 -0400 [INFO] (transaction): {done:  0 / 1, 
running: 0}
2015-05-11 03:34:01.828 -0400 [INFO] (task-0000): Writing local file 
'./output/mysql_to_csv.000.00.csv'
2015-05-11 03:34:01.852 -0400 [INFO] (task-0000): Fetch size is 10000. 
Using server-side prepared statement.
2015-05-11 03:34:01.908 -0400 [INFO] (task-0000): SQL: SELECT * 
FROM `table1`
2015-05-11 03:34:01.922 -0400 [INFO] (task-0000): > 0.01 seconds
2015-05-11 03:34:01.971 -0400 [INFO] (transaction): {done:  1 / 1, 
running: 0}
2015-05-11 03:34:01.981 -0400 [INFO] (main): Committed.
2015-05-11 03:34:01.981 -0400 [INFO] (main): Next config diff: 
{"in":{},"out":{}}
[lib]# cat output/mysql_to_csv.000.00.csv
id,content,timestamp
1,embulk,2015-05-20 15:23:11
2,mysql content,2015-05-21 13:52:57
3,mysql to csv test,2015-05-24 20:49:10

実行後、mysql.ymlで指定したプレフィックス、"output/mysql_to_csv"を持ったファイルが生成されました(mysql_to_csv.000.00.csv)

中身はMysqlに入っていたデータが、カンマ区切りで移行されています。


おわりに
Embulkを利用してのデータ転送は如何だったでしょうか。
実のところ、データの加工のプラグインや、ymlファイルの自動生成など、まだ紹介しきれていない数多くのEmbulkの強みや、使っていて"こういう機能も欲しいな"という点もあるのですが、今回はEmbulkがどういうものかを伝えられる内容にしてみました。

次回は他のサービスとEmbulkとを組み合わせて何かしてみようと思います。

0 件のコメント:

コメントを投稿