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.4k
Architecture Evolution in Repro
railsdm2019
Tomohiro Hashidate
March 23, 2019
Tweet
Share
More Decks by Tomohiro Hashidate
See All by Tomohiro Hashidate
本番のトラフィック量でHudiを検証して見えてきた課題
joker1007
2
700
5分で分かった気になるDebezium
joker1007
1
45
Rustで作るtree-sitterパーサーのRubyバインディング
joker1007
5
890
tree-sitter-rbsで作って学ぶRBSとパーサージェネレーター
joker1007
3
220
Kafka Streamsで作る10万rpsを支えるイベント駆動マイクロサービス
joker1007
7
3.2k
neovimで作る最新Ruby開発環境2023
joker1007
2
4k
ReproのImport/Exportを支えるサーバーレスアーキテクチャ
joker1007
1
1.2k
Ruby on Rails on Lambda
joker1007
13
12k
Sidekiq to Kafka ストリームベースのmicro services
joker1007
4
8.8k
Other Decks in Technology
See All in Technology
Amazon VPC Lattice 最新アップデート紹介 - PrivateLink も似たようなアップデートあったけど違いとは
bigmuramura
0
190
社外コミュニティで学び社内に活かす共に学ぶプロジェクトの実践/backlogworld2024
nishiuma
0
260
OpenAIの蒸留機能(Model Distillation)を使用して運用中のLLMのコストを削減する取り組み
pharma_x_tech
4
560
PHP ユーザのための OpenTelemetry 入門 / phpcon2024-opentelemetry
shin1x1
1
220
MLOps の現場から
asei
6
640
UI State設計とテスト方針
rmakiyama
2
590
podman_update_2024-12
orimanabu
1
270
生成AIをより賢く エンジニアのための RAG入門 - Oracle AI Jam Session #20
kutsushitaneko
4
230
Oracle Cloudの生成AIサービスって実際どこまで使えるの? エンジニア目線で試してみた
minorun365
PRO
4
280
生成AIのガバナンスの全体像と現実解
fnifni
1
190
サーバレスアプリ開発者向けアップデートをキャッチアップしてきた #AWSreInvent #regrowth_fuk
drumnistnakano
0
190
PHPからGoへのマイグレーション for DMMアフィリエイト
yabakokobayashi
1
170
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Into the Great Unknown - MozCon
thekraken
33
1.5k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
0
98
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
95
17k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
48
2.2k
Building Your Own Lightsaber
phodgson
103
6.1k
[RailsConf 2023] Rails as a piece of cake
palkan
53
5k
Bash Introduction
62gerente
608
210k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.1k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
5
450
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