Slide 1

Slide 1 text

CRuby プロダクトにおける embulk の活用法 @joker1007

Slide 2

Slide 2 text

self.inspect @joker1007 Repro inc. CTO ( 要は色々やる人) Ruby/Rails uentd/embulk ← 今日はこの辺 Docker/ECS Bigquery/EMR/Hive/Presto

Slide 3

Slide 3 text

Repro のサービス モバイルアプリケーションの行動トラッキング 分析結果の提供と、それと連動したマーケティン グの提供 大体Ruby ・Rails でほぼAWS 上で稼動している Docker やterraform 等も活用している 会社規模の割にデータ量が多い。 そのためデータエンジニアリングも必要。

Slide 4

Slide 4 text

開発・メンテしてるもの embulk embulk- lter-ruby_proc embulk-output-in uxdb embulk-parser(formatter)-avro embulk-output-s3_per_record その他 uent-plugin-bigquery rukawa ( 自作のワークフローエンジン)

Slide 5

Slide 5 text

embulk の主な用途 Bigquery で集計した結果の整形、取得 ( 日次バッ チ) データの洗い替え ( データメンテナンス)

Slide 6

Slide 6 text

embulk の採用理由 CRuby より高速に処理できる かつRuby でプラグインを書くことでアドホックな 加工ができる プラグイン管理にRubyist にとって馴染みのある Bundler が使える Gem le.lock によるバージョンロックが楽 プラグインインストールの方法がプロダクトと 揃う JRuby やプラグイン機構がRubyist フレンドリーな点 が良い。

Slide 7

Slide 7 text

バッチ処理に組込むために必要なもの 自動実行のためのスケジューラ -> Rundeck 実行日付を元に設定をパラメーター化 -> yaml_master 処理同士の依存関係や並列数を定義できるワーク フローエンジン -> rukawa digdag があればいい。 が、現在、digdag は使っていないw digdag リリースの前に設計・構築したので。

Slide 8

Slide 8 text

rukawa については以下を参照 http://joker1007.github.io/slides/introduce_rukawa/slid es/index.html

Slide 9

Slide 9 text

embulk 利用例詳細 1. 更新が発生するデータをembulk でBq に転送 2. uentd で蓄積しているログと結合しBq で集計 3. 集計後のデータとそれに紐付くユーザーID をAVRO でexport 4. GCS からS3 にembulk でデータを転送する 5. S3 に転送したAVRO ファイルをembulk でRDB に import 6. S3 に転送したAVRO ファイルをembulk でレコード 単位にばらして別バケットに保存

Slide 10

Slide 10 text

Bq へのデータ転送 日次バッチで必要なデータを都度丸ごと上書き 更新のある小規模のデータで羃等性を担保するた め embulk-output-bigquery を普通に利用している

Slide 11

Slide 11 text

Bq でのデータ集計 いくつかのSQL ジョブをワークフローエンジンで定 義して実行 処理が終わった側からexport してはembulk でデー タを転送する

Slide 12

Slide 12 text

GCS からS3 へのデータ転送 embulk-input-gcs とembulk-output-s3 を使用 ファイルフォーマットにAVRO を利用するため以下 のプラグインを開発 embulk-parser-avro embulk-formatter-avro

Slide 13

Slide 13 text

embulk-parser-avro in: type: file path_prefix: "items" parser: type: avro avsc : "./item.avsc" columns: - {name: "id", type: "long"} - {name: "name", type: "string"} - {name: "flag", type: "boolean"} - {name: "price", type: "long"} - {name: "item_type", type: "string"} - {name: "tags", type: "json"} - {name: "options", type: "json"} out: type: stdout

Slide 14

Slide 14 text

AVRO スキーマ サンプル { "type" : "record", "name" : "Item", "namespace" : "example.avro", "fields" : [ {"name": "id", "type": "int"}, {"name": "name", "type": "string"}, {"name": "flag", "type": "boolean"}, {"name": "spec", "type": { "type": "record", "name": "item_spec", "fields" : [ {"name" : "key", "type" : "string"}, {"name" : "value", "type" : ["string", "null"]} ]} } ] }

Slide 15

Slide 15 text

AVRO を使う理由 Bq からexport した時のデータ型の問題 JSON だとINT が文字列になる INT の配列も文字列になる スキーマを後から変えられる スキーマ側からデフォルト値を差し込める Hadoop エコシステムで処理しやすい cf. http://avro.apache.org/docs/current/spec.html

Slide 16

Slide 16 text

レコードをばらしてS3 に書き込む サービス上の要請による embulk-output-s3_per_record を利用 Page をadd する時に都度S3 に書き込む 効率がめっちゃ悪いので遅いが仕方なく

Slide 17

Slide 17 text

embulk-output-s3_per_record con g out: type: s3_per_record bucket: your-bucket-name key: "sample/${id}.txt" mode: multi_column serializer: json data_columns: [id, payload] output {"id": 5, "payload": "foo"}

Slide 18

Slide 18 text

設定ファイルの生成とembulk の実行 yaml_master というgem を作り設定ファイルを生成 ERB を利用してRuby からプロパティを突っ込ん でyaml を出力する Liquid より表現力が高い CRuby のプロダクトが持つ情報を元に直接生成 しやすい CRuby からの呼び出しはpopen3 を利用してプロセ スを起動する Rukawa で呼び出しのためのヘルパーを書いてい る

Slide 19

Slide 19 text

Embulk を効果的に使うには システムに組込むには、いくつか周辺のヘルパー を用意する必要がある 自分達が使うフォーマットに合わせてプラグイン を作れる様にしておく パフォーマンス要求がきつくないデータ加工には embulk- lter-ruby_proc をオススメする

Slide 20

Slide 20 text

プラグイン開発で意識していること できるだけ機能を限定する カラムの操作など lter でやれることは単体の lter に任せる データのparse, encode はJava の方が良い ネストしたデータ構造を扱うのは面倒だが マルチスレッドで動作することを意識する 特にRuby プラグイン 実行フェイズ毎にシリアライズを挟む場合がある ことを知っておく