Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Architecture Evolution in Repro
Search
Tomohiro Hashidate
March 23, 2019
Technology
5
4.9k
Architecture Evolution in Repro
railsdm2019
Tomohiro Hashidate
March 23, 2019
Tweet
Share
More Decks by Tomohiro Hashidate
See All by Tomohiro Hashidate
ReproでのicebergのStreaming Writeの検証と実運用にむけた取り組み
joker1007
0
550
マイクロサービスへの5年間 ぶっちゃけ何をしてどうなったか
joker1007
23
9.1k
Quarkusで作るInteractive Stream Application
joker1007
0
210
今改めてServiceクラスについて考える 〜あるRails開発者の10年〜
joker1007
25
19k
rubygem開発で鍛える設計力
joker1007
4
1.2k
実践Kafka Streams 〜イベント駆動型アーキテクチャを添えて〜
joker1007
3
1.3k
本番のトラフィック量でHudiを検証して見えてきた課題
joker1007
2
1.2k
5分で分かった気になるDebezium
joker1007
1
200
Rustで作るtree-sitterパーサーのRubyバインディング
joker1007
5
1.6k
Other Decks in Technology
See All in Technology
予期せぬコストの急増を障害のように扱う――「コスト版ポストモーテム」の導入とその後の改善
muziyoshiz
1
1.9k
超初心者からでも大丈夫!オープンソース半導体の楽しみ方〜今こそ!オレオレチップをつくろう〜
keropiyo
0
110
We Built for Predictability; The Workloads Didn’t Care
stahnma
0
140
モダンUIでフルサーバーレスなAIエージェントをAmplifyとCDKでサクッとデプロイしよう
minorun365
4
200
配列に見る bash と zsh の違い
kazzpapa3
1
150
Context Engineeringの取り組み
nutslove
0
340
20260204_Midosuji_Tech
takuyay0ne
1
150
量子クラウドサービスの裏側 〜Deep Dive into OQTOPUS〜
oqtopus
0
110
ファインディの横断SREがTakumi byGMOと取り組む、セキュリティと開発スピードの両立
rvirus0817
1
1.4k
プロダクト成長を支える開発基盤とスケールに伴う課題
yuu26
4
1.3k
30万人の同時アクセスに耐えたい!新サービスの盤石なリリースを支える負荷試験 / SRE Kaigi 2026
genda
4
1.3k
AzureでのIaC - Bicep? Terraform? それ早く言ってよ会議
torumakabe
1
540
Featured
See All Featured
Faster Mobile Websites
deanohume
310
31k
Mobile First: as difficult as doing things right
swwweet
225
10k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
180
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
7.9k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
140
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
130
Un-Boring Meetings
codingconduct
0
200
GraphQLの誤解/rethinking-graphql
sonatard
74
11k
The browser strikes back
jonoalderson
0
370
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
74
How to train your dragon (web standard)
notwaldorf
97
6.5k
Transcript
Architecture Evolution in Repro @joker1007 (Repro inc. CTO)
⾃⼰紹介 @joker1007 Repro inc. CTO Asakusa.rb RubyKaigi 2019 Speaker 最近は主にデータエンジニアっぽい仕事
Repro というサービス スマホアプリ・Web サービス向けのアナリティクス ユーザ属性や利⽤履歴を元にしたセグメンテーション セグメンテーション対象に対するダイレクトマーケティング セグメンテーション対象に対する広告出稿 こういった機能をサービスとして提供している。
Retention Analytics
Funnel Analytics
User Segmentation
サービスのスケール 総デバイス数 数億超 ⼀度のプッシュ配信数が最⼤で1000 万〜2000 万デバイス ⽉間で送信しているプッシュメッセージの数が約40 億超 つまり、数千万のユーザの数⽇分の履歴やプロフィール情報を任意に組み合わせて、 必要とするユーザーの集合を短時間で抽出しなければならない。
それがRepro のユーザーセグメンテーション。
過去に戻って2016 年半ば 数万ユーザの集計とセグメンテーションの時代
RDB の限界 MySQL でリクエスト時に集計して結果をRedis にキャッシュ。 ⾃分が⼊った当時で既に初回表⽰に10 秒以上かかるページがあった。
中間集計テーブルとバッチ化 とりあえず突貫でMySQL 上に中間集計テーブルを作る。 ⼀部の集計をバッチ化するが、データ構造上アプリ毎にループで実⾏していた。
ナイーブなバッチの問題点 顧客が増えれば線形で実⾏時間が伸び即破綻する。 顧客が増えてもスケールでき、かつ顧客毎に集計更新に差が⽣じない様にする必要が ある。 安易にバッチ化するとこうなりがち。
fluentd & embulk & Bigquery Bigquery の採⽤ データ転送のためにfluentd とembulk を利⽤
それぞれのプラグインに何回かPR 出してたらコミット権を獲得
Bigquery の採⽤理由 スキーマ設計を頑張りたくない 分散キーとかソートキーとか 異常なコストパフォーマンス まともなSQL に対応
fluentd 運⽤時の注意点 データ転送量が多い時の注意点 ブロッキングで詰まらない様にflush スレッド数を調整する ⼗分なファイルストレージを⽤意する 特にBigquery はAPI が良く死ぬ require_ack_response
とsecondary output は基本的に必須 でないとデータロストする secondary でエラーファイルをS3 に書き出すのは割と⼤丈夫 <label @ERROR> によるエラーハンドルを設定 どのレイヤーでどこまでデータが貯まって、 どこまでの到達が保証できるのかを認識しておく事が重要。
Bigquery 採⽤後の構造
Bigquery で解決できたこと 集計処理がめっちゃスケールする様になった 当時から現在まででデータ量が数⼗倍ぐらいになったが、集計時間は⼤きく 変化していない 全ての顧客に同時に集計結果を出せる様になった ただ、SQL 構築するのに、かなりの時間を費した。 特にFunnel Analytics
は超⾟かった。 ( ハードな集計SQL に興味がある⼈は後で直接質問を)
Bigquery では⾟いこと ユーザーが任意のタイミングで任意の条件でセグメンテーションし、短時間で結 果を返すのが厳しい 即時クエリの同時実⾏上限が存在する クラウドとリージョンを跨ぐデータ転送 Bigquery はクエリ課⾦ 利⽤されればされる程、Repro 側が損することになる
当時は顧客毎にクエリ対象を分けられなかった 現在はclustering key で多少カバーできそう しばらくは持つが、顧客の数が増えてくると破綻する。 ( また同じ問題…… 。)
Rukawa の開発 Bigquery 採⽤に伴いバッチの数が激増 依存関係や並列実⾏可能かどうかを上⼿く調整する必要が出てきた ワークフローエンジンrukawa を開発 以前の発表資料 Ruby 製のシンプルなワークフローエンジンRukawa
の紹介 ワークフローエンジンRukawa と実装のサボり⽅
ユーザーセグメンテーションの裏側 各条件をツリーとして表現し、Operator ノードで繋ぐ 各ツリーのノードはSQL として解決可能になっている ツリーを再帰処理しながらOperator がJOIN やIN 句を使ってクエリを結合する 最終的に出⼒されたクエリをクエリエンジンに投げる
これらはRails のモデルとして表現されており、ERB を利⽤してSQL を構築している。 つまり、モデルの中にERB のテンプレートがある
SELECT DISTINCT user_id FROM filtered_custom_event_histories WHERE <%= event_property_where_clause(and_properties, and_not_properties) %>
こんな感じに解決可能なものを組み合わせる。
セグメンテーションツリーのイメージ SQL に解決しながらJOIN で折り畳んで、集合を組み合わせていく。
この辺りで⼤半の実⾏基盤をコンテナ化 過去に喋ったり書いたりした記事があるのでそちらを参照。 production 環境でRails アプリをdocker コンテナとしてECS で運⽤するために考え たこと 開発しやすいRails on
Docker 環境の作り⽅ サクっとAmazon ECS のクラスタを構築するためのterraform の設定 Docker コンテナ上でのassets precompile の扱い 2017 Rails アプリをECS で本番運⽤するためのStep by Step Docker 時代の分散RSpec 環境の作り⽅ 記事には書いてないがEmbulk on Fargate とかも ( これも詳細は質問や懇親会で)
Presto on EMR を採⽤ クエリ数が増えてもコストが線形に増えない様に 実際負荷が上がればコストは上がるけど AWS で完結する様にして、クエリレイテンシを下げ、アドホッククエリに対応す る MySQL
やAurora 、その他のデータストアに接続できるので、それらを組み合わせ ることができる
Presto とは Facebook が開発した分散SQL クエリエンジン。 Presto ⾃体はデータストアを持っていない。 コーディネータがSQL を解釈し、様々なデータストアに対するコネクタがデータスト アに合わせたリクエストに変換し並列でクエリを⾏う。
最も良く使うのはhive connector で、Apache Hive のメタデータを利⽤してHDFS やS3 に並列でアクセスし⾼速にSQL を利⽤したSELECT が可能。 複数のデータストアのテーブルをJOIN することもできる。
Hive とEmbulk によるデータ変換 Bigquery で集計したデータをEmbulk でS3 に転送 fluentd でS3 に蓄積したデータと合わせてHive
でParquet に変換 Presto でクエリして柔軟な条件によるセグメンテーションを実現
Apache Parquet とは カラムナー( 列指向) フォーマットの⼀つ。 Google がBigquery ⽤に開発したDremel というフォーマットの論⽂を元にしてい
る。 似たフォーマットとしてORC がある。
カラムナ フォ マットのイメ ジ
なぜ列指向なのか ⼤量のデータを抽出したり集計したりする時は、⾏ではなく列単位でデータを持 っていた⽅が効率的に扱える。 圧縮効率とか、特定カラムを全取得する場合等に有効
Presto 採⽤後の構造
Presto でも解決できなかったこと Parquet 変換にバッチが必要 抽出条件に引っかかる様になるまでに時間がかかる 更新が発⽣するデータの扱いが⾯倒 基本追記オンリーなので重複排除等が必要 MySQL では読み書きのスケーラビリティが厳しい Presto
で⼤量にデータ取得するとクソ遅い
Cassandra を採⽤する DynamoDB の論⽂を参考にしているNoSQL で完全な⾮中央集権構造が特徴。 Presto で元々サポートしている 書き込みスケールしやすい ⼤量に読み込むのは得意ではない 台数がある程度あればMySQL
よりはマシ 実験してみてしばらく持つだろうと判断
Cassandra 採⽤後の構造
Presto & Cassandra & S3 リアルタイムで更新したいデータをワーカーで直接Cassandra に書き込む 集計が必要なデータはBigquery で集計, S3
に転送しParquet に変換する Presto でCassandra のデータとParquet on S3 のデータを組み合わせる ほとんどの規模の顧客のデータは1 分以内で返答可能 数百万を越える規模のユーザ数でも数分以内に。
Cassandra でも解決できなかったこと 余りにもデータ量が多いと読み込みクエリ負荷に耐えられない そのため⼀部のデータはリアルタイムに反映したいが対応できていない 読み込み時のCPU 負荷が⾼い コストとスケールのバランスを⾒極める必要がある
未来のユーザーセグメンテーション Apache Kafka を導⼊ データ取得効率を上げるためのクエリ最適化 Cassandra -> Apache Kudu? Apache
Kudu ⾼速なデータの挿⼊・更新と列指向の参照を組み合わせた分散DB 最近、Presto も公式サポートした。熱い。
妄想上の構造
その他の課題 マイクロサービス化 サービスディスカバリ スキーマ管理 秘匿情報管理V2 ⾊々とやらねばならないことが。
こういう仕事がしてみたいという⽅ 絶賛募集中です!! https://www.wantedly.com/projects/102039 https://www.wantedly.com/projects/44097