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.3k
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
490
5分で分かった気になるDebezium
joker1007
1
29
Rustで作るtree-sitterパーサーのRubyバインディング
joker1007
5
780
tree-sitter-rbsで作って学ぶRBSとパーサージェネレーター
joker1007
3
190
Kafka Streamsで作る10万rpsを支えるイベント駆動マイクロサービス
joker1007
7
3.2k
neovimで作る最新Ruby開発環境2023
joker1007
2
3.8k
ReproのImport/Exportを支えるサーバーレスアーキテクチャ
joker1007
1
1.2k
Ruby on Rails on Lambda
joker1007
13
12k
Sidekiq to Kafka ストリームベースのmicro services
joker1007
4
8.7k
Other Decks in Technology
See All in Technology
独自ツール開発でスタジオ撮影をDX!「VLS(Virtual LED Studio)」 / dx-studio-vls
cyberagentdevelopers
PRO
1
180
分布で見る効果検証入門 / ai-distributional-effect
cyberagentdevelopers
PRO
4
700
グローバル展開を見据えたサービスにおける機械翻訳プラクティス / dp-ai-translating
cyberagentdevelopers
PRO
1
150
20241031_AWS_生成AIハッカソン_GenMuck
tsumita
0
110
[AWS JAPAN 生成AIハッカソン] Dialog の紹介
yoshimi0227
0
150
IaC運用を楽にするためにCDK Pipelinesを導入したけど、思い通りにいかなかった話
smt7174
1
110
Amazon FSx for NetApp ONTAPを利用するにあたっての要件整理と設計のポイント
non97
1
160
プロダクトエンジニアが活躍する環境を作りたくて 事業責任者になった話 ~プロダクトエンジニアの行き着く先~
gimupop
1
480
30万人が利用するチャットをFirebase Realtime DatabaseからActionCableへ移行する方法
ryosk7
5
340
新R25、乃木坂46 Mobileなどのファンビジネスを支えるマルチテナンシーなプラットフォームの全体像 / cam-multi-cloud
cyberagentdevelopers
PRO
1
130
プロダクト成長に対応するプラットフォーム戦略:Authleteによる共通認証基盤の移行事例 / Building an authentication platform using Authlete and AWS
kakehashi
1
150
いまならこう作りたい AWSコンテナ[本格]入門ハンズオン 〜2024年版 ハンズオンの構想〜
horsewin
9
2.1k
Featured
See All Featured
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5k
Music & Morning Musume
bryan
46
6.1k
Making the Leap to Tech Lead
cromwellryan
132
8.9k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.8k
A designer walks into a library…
pauljervisheath
202
24k
Adopting Sorbet at Scale
ufuk
73
9k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
3
370
Become a Pro
speakerdeck
PRO
24
5k
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
Bash Introduction
62gerente
608
210k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
92
16k
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