$30 off During Our Annual Pro Sale. View Details »

Architecture Evolution in Repro

Architecture Evolution in Repro

railsdm2019

Tomohiro Hashidate

March 23, 2019
Tweet

More Decks by Tomohiro Hashidate

Other Decks in Technology

Transcript

  1. Architecture Evolution in Repro
    @joker1007 (Repro inc. CTO)

    View Slide

  2. ⾃⼰紹介
    @joker1007
    Repro inc. CTO
    Asakusa.rb
    RubyKaigi 2019 Speaker
    最近は主にデータエンジニアっぽい仕事

    View Slide

  3. Repro
    というサービス
    スマホアプリ・Web
    サービス向けのアナリティクス
    ユーザ属性や利⽤履歴を元にしたセグメンテーション
    セグメンテーション対象に対するダイレクトマーケティング
    セグメンテーション対象に対する広告出稿
    こういった機能をサービスとして提供している。

    View Slide

  4. Retention Analytics

    View Slide

  5. Funnel Analytics

    View Slide

  6. User Segmentation

    View Slide

  7. サービスのスケール
    総デバイス数 数億超
    ⼀度のプッシュ配信数が最⼤で1000
    万〜2000
    万デバイス
    ⽉間で送信しているプッシュメッセージの数が約40
    億超
    つまり、数千万のユーザの数⽇分の履歴やプロフィール情報を任意に組み合わせて、
    必要とするユーザーの集合を短時間で抽出しなければならない。
    それがRepro
    のユーザーセグメンテーション。

    View Slide

  8. 過去に戻って2016
    年半ば
    数万ユーザの集計とセグメンテーションの時代

    View Slide

  9. RDB
    の限界
    MySQL
    でリクエスト時に集計して結果をRedis
    にキャッシュ。
    ⾃分が⼊った当時で既に初回表⽰に10
    秒以上かかるページがあった。

    View Slide

  10. 中間集計テーブルとバッチ化
    とりあえず突貫でMySQL
    上に中間集計テーブルを作る。
    ⼀部の集計をバッチ化するが、データ構造上アプリ毎にループで実⾏していた。

    View Slide

  11. ナイーブなバッチの問題点
    顧客が増えれば線形で実⾏時間が伸び即破綻する。
    顧客が増えてもスケールでき、かつ顧客毎に集計更新に差が⽣じない様にする必要が
    ある。
    安易にバッチ化するとこうなりがち。

    View Slide

  12. fluentd & embulk & Bigquery
    Bigquery
    の採⽤
    データ転送のためにfluentd
    とembulk
    を利⽤
    それぞれのプラグインに何回かPR
    出してたらコミット権を獲得

    View Slide

  13. Bigquery
    の採⽤理由
    スキーマ設計を頑張りたくない
    分散キーとかソートキーとか
    異常なコストパフォーマンス
    まともなSQL
    に対応

    View Slide

  14. fluentd
    運⽤時の注意点
    データ転送量が多い時の注意点
    ブロッキングで詰まらない様にflush
    スレッド数を調整する
    ⼗分なファイルストレージを⽤意する
    特にBigquery
    はAPI
    が良く死ぬ
    require_ack_response
    とsecondary output
    は基本的に必須
    でないとデータロストする
    secondary
    でエラーファイルをS3
    に書き出すのは割と⼤丈夫

    によるエラーハンドルを設定
    どのレイヤーでどこまでデータが貯まって、
    どこまでの到達が保証できるのかを認識しておく事が重要。

    View Slide

  15. Bigquery
    採⽤後の構造

    View Slide

  16. Bigquery
    で解決できたこと
    集計処理がめっちゃスケールする様になった
    当時から現在まででデータ量が数⼗倍ぐらいになったが、集計時間は⼤きく
    変化していない
    全ての顧客に同時に集計結果を出せる様になった
    ただ、SQL
    構築するのに、かなりの時間を費した。
    特にFunnel Analytics
    は超⾟かった。
    (
    ハードな集計SQL
    に興味がある⼈は後で直接質問を)

    View Slide

  17. Bigquery
    では⾟いこと
    ユーザーが任意のタイミングで任意の条件でセグメンテーションし、短時間で結
    果を返すのが厳しい
    即時クエリの同時実⾏上限が存在する
    クラウドとリージョンを跨ぐデータ転送
    Bigquery
    はクエリ課⾦
    利⽤されればされる程、Repro
    側が損することになる
    当時は顧客毎にクエリ対象を分けられなかった
    現在はclustering key
    で多少カバーできそう
    しばらくは持つが、顧客の数が増えてくると破綻する。
    (
    また同じ問題……
    。)

    View Slide

  18. Rukawa
    の開発
    Bigquery
    採⽤に伴いバッチの数が激増
    依存関係や並列実⾏可能かどうかを上⼿く調整する必要が出てきた
    ワークフローエンジンrukawa
    を開発
    以前の発表資料
    Ruby
    製のシンプルなワークフローエンジンRukawa
    の紹介
    ワークフローエンジンRukawa
    と実装のサボり⽅

    View Slide

  19. ユーザーセグメンテーションの裏側
    各条件をツリーとして表現し、Operator
    ノードで繋ぐ
    各ツリーのノードはSQL
    として解決可能になっている
    ツリーを再帰処理しながらOperator
    がJOIN
    やIN
    句を使ってクエリを結合する
    最終的に出⼒されたクエリをクエリエンジンに投げる
    これらはRails
    のモデルとして表現されており、ERB
    を利⽤してSQL
    を構築している。
    つまり、モデルの中にERB
    のテンプレートがある

    View Slide

  20. SELECT DISTINCT
    user_id
    FROM filtered_custom_event_histories
    WHERE
    <%= event_property_where_clause(and_properties, and_not_properties) %>
    こんな感じに解決可能なものを組み合わせる。

    View Slide

  21. セグメンテーションツリーのイメージ
    SQL
    に解決しながらJOIN
    で折り畳んで、集合を組み合わせていく。

    View Slide

  22. この辺りで⼤半の実⾏基盤をコンテナ化
    過去に喋ったり書いたりした記事があるのでそちらを参照。
    production
    環境でRails
    アプリをdocker
    コンテナとしてECS
    で運⽤するために考え
    たこと
    開発しやすいRails on Docker
    環境の作り⽅
    サクっとAmazon ECS
    のクラスタを構築するためのterraform
    の設定
    Docker
    コンテナ上でのassets precompile
    の扱い 2017
    Rails
    アプリをECS
    で本番運⽤するためのStep by Step
    Docker
    時代の分散RSpec
    環境の作り⽅
    記事には書いてないがEmbulk on Fargate
    とかも
    (
    これも詳細は質問や懇親会で)

    View Slide

  23. Presto on EMR
    を採⽤
    クエリ数が増えてもコストが線形に増えない様に
    実際負荷が上がればコストは上がるけど
    AWS
    で完結する様にして、クエリレイテンシを下げ、アドホッククエリに対応す

    MySQL
    やAurora
    、その他のデータストアに接続できるので、それらを組み合わせ
    ることができる

    View Slide

  24. Presto
    とは
    Facebook
    が開発した分散SQL
    クエリエンジン。
    Presto
    ⾃体はデータストアを持っていない。
    コーディネータがSQL
    を解釈し、様々なデータストアに対するコネクタがデータスト
    アに合わせたリクエストに変換し並列でクエリを⾏う。
    最も良く使うのはhive connector
    で、Apache Hive
    のメタデータを利⽤してHDFS
    やS3
    に並列でアクセスし⾼速にSQL
    を利⽤したSELECT
    が可能。
    複数のデータストアのテーブルをJOIN
    することもできる。

    View Slide

  25. Hive
    とEmbulk
    によるデータ変換
    Bigquery
    で集計したデータをEmbulk
    でS3
    に転送
    fluentd
    でS3
    に蓄積したデータと合わせてHive
    でParquet
    に変換
    Presto
    でクエリして柔軟な条件によるセグメンテーションを実現

    View Slide

  26. Apache Parquet
    とは
    カラムナー(
    列指向)
    フォーマットの⼀つ。
    Google
    がBigquery
    ⽤に開発したDremel
    というフォーマットの論⽂を元にしてい
    る。
    似たフォーマットとしてORC
    がある。

    View Slide

  27. カラムナ フォ マットのイメ ジ

    View Slide

  28. なぜ列指向なのか
    ⼤量のデータを抽出したり集計したりする時は、⾏ではなく列単位でデータを持
    っていた⽅が効率的に扱える。
    圧縮効率とか、特定カラムを全取得する場合等に有効

    View Slide

  29. Presto
    採⽤後の構造

    View Slide

  30. Presto
    でも解決できなかったこと
    Parquet
    変換にバッチが必要
    抽出条件に引っかかる様になるまでに時間がかかる
    更新が発⽣するデータの扱いが⾯倒
    基本追記オンリーなので重複排除等が必要
    MySQL
    では読み書きのスケーラビリティが厳しい
    Presto
    で⼤量にデータ取得するとクソ遅い

    View Slide

  31. Cassandra
    を採⽤する
    DynamoDB
    の論⽂を参考にしているNoSQL
    で完全な⾮中央集権構造が特徴。
    Presto
    で元々サポートしている
    書き込みスケールしやすい
    ⼤量に読み込むのは得意ではない
    台数がある程度あればMySQL
    よりはマシ
    実験してみてしばらく持つだろうと判断

    View Slide

  32. Cassandra
    採⽤後の構造

    View Slide

  33. Presto & Cassandra & S3
    リアルタイムで更新したいデータをワーカーで直接Cassandra
    に書き込む
    集計が必要なデータはBigquery
    で集計, S3
    に転送しParquet
    に変換する
    Presto
    でCassandra
    のデータとParquet on S3
    のデータを組み合わせる
    ほとんどの規模の顧客のデータは1
    分以内で返答可能
    数百万を越える規模のユーザ数でも数分以内に。

    View Slide

  34. Cassandra
    でも解決できなかったこと
    余りにもデータ量が多いと読み込みクエリ負荷に耐えられない
    そのため⼀部のデータはリアルタイムに反映したいが対応できていない
    読み込み時のCPU
    負荷が⾼い
    コストとスケールのバランスを⾒極める必要がある

    View Slide

  35. 未来のユーザーセグメンテーション
    Apache Kafka
    を導⼊
    データ取得効率を上げるためのクエリ最適化
    Cassandra -> Apache Kudu?
    Apache Kudu
    ⾼速なデータの挿⼊・更新と列指向の参照を組み合わせた分散DB
    最近、Presto
    も公式サポートした。熱い。

    View Slide

  36. 妄想上の構造

    View Slide

  37. その他の課題
    マイクロサービス化
    サービスディスカバリ
    スキーマ管理
    秘匿情報管理V2
    ⾊々とやらねばならないことが。

    View Slide

  38. こういう仕事がしてみたいという⽅
    絶賛募集中です!!
    https://www.wantedly.com/projects/102039
    https://www.wantedly.com/projects/44097

    View Slide