メルカリのデータ分析基盤の紹介〜BigQuery周辺の話〜

Mercari Advent Calendar 2017 の9日目はメルカリ SRE(Site Reliability Engineering) チームの @syu_cream がお送りします。

メルカリでは様々なデータを BigQuery に格納して、データ利用を可能にしています。
BigQuery に格納しているデータの具体例としては、 Web サーバや API サーバのアクセスログやアプリケーションのログ、 以前当ブログで紹介した Pascal のイベントログ などが挙げられます。

メルカリのデータ分析基盤に関する情報はこれまでに以下のようなブログやスライドで紹介しております。

今回はこれらの延長線で、特に BigQuery にログデータを格納する辺りの構成の紹介や、最近行った改善について紹介いたします。
なにかの参考になれば幸いです。

従来の構成

今回紹介する箇所は メルカリのデータ分析基盤 / mercari data analysis infrastructure で紹介した図において以下の破線の部分になります。

f:id:syu_cream:20171206105611p:plain:w800

この部分は従来、以下のように一時間毎に fluentd から転送されたログファイルを洗い出し、一旦 gsutil cp コマンドによって GCS(Google Cloud Storage) にアップロードした上で bq load コマンドを用いて BigQuery にロードするという処理を行っていました。
これを簡単に図示すると以下のようになります。

f:id:syu_cream:20171206113821p:plain

この構成は数年間安定して稼働してはいたのですが、メルカリのサービス成長に伴い最近は以下のような課題が挙がってきました。

  • アップロード失敗時のリトライが難しい
    • シェルスクリプトで行っているコマンドを手動で再現する必要があった
  • アップロードの実行時間の計測をしていなかった
    • アップロード完了までどの程度の時間を要しているか不明な状態だった
  • GCS/BigQuery にアップロードするログのサイズが増大し、アップロードのロジックが複雑になってきた
    • BigQuery には 読み込みジョブに対する制限 が存在する
    • 実際にログのアップロードシステムにおいて圧縮済みJSONファイルの 4GB 上限に引っかかるケースが発生した
    • この制限を回避するため、アップロード直前にファイルを split するという重い処理を行っていた

これからの構成

これらの課題を払拭するため、今回は Treasure Data 製ワークフローエンジンである digdag を用いることにしました。
他のワークフローエンジンと比較して digdag を選択した理由としては、以下が挙げられます。

  • 課題を解決するに足る機能が存在する
  • 構成がシンプルで DB やワーカーなどの複数コンポーネントを管理せずに済む
  • AWS, GCP のサービスに関したオペレータのサポートがされている
  • YAML ライクなシンタックスの設定ファイルで扱いやすい

digdag を用いて置き換えた BigQuery のアップロード処理は以下のようになります。
ちょうど従来シェルスクリプトで実装していた部分を、 digdag のワークフローとして再実装した格好になります。

f:id:syu_cream:20171206113907p:plain

アップロードシステムにおいて digdag server を起動し、 schedule: オプションに従いアップロードを定時実行するようにしています。
下図のように実行ステータスや所要時間も可視化され、今後ログファイルが増加した際のスケジューリングも行いやすくなるものと思われます。

f:id:syu_cream:20171205194715p:plain:w800

更にアップロード失敗時の再実行も digdag の WebUI 上でワンクリックで行うことができるようになりました(下図の RETRY ALL ボタンを押すことで、セッションのすべての処理を再実行できます)。
これで実行されるべきであったコマンドを手動で再現するという手間を掛ける必要がなくなりました。

f:id:syu_cream:20171205194742p:plain:w800

また digdag とは直接関係はないのですが、今回合わせて BigQuery のファイルサイズ制限をアップロード時に解決するのではなく、 fluentd の設定ファイルの buffer_chunk_limit の値を見直し、転送されてきた適当なファイルサイズに分割されるように修正しました。
これでアップロード時に巨大なファイルの split を行うという重い処理を行わずに済みます。

おわりに

今回ご紹介したお話は、今月 12 日にメルカリ主催で行われる SRE-SET Automation Night でも紹介させていただこうと思っております。データ処理やワークフローの整理で悩む同士の方がいらっしゃいましたら、ぜひ一緒にお話しませんか?
(既に参加可能枠を超過するほどのご参加応募をいただいております!ありがとうございます!)

connpass.com

明日 10 日目の執筆担当は @deme0607 です。引き続きお楽しみください 🙂