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
570
5分で分かった気になるDebezium
joker1007
1
39
Rustで作るtree-sitterパーサーのRubyバインディング
joker1007
5
820
tree-sitter-rbsで作って学ぶRBSとパーサージェネレーター
joker1007
3
200
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.8k
Other Decks in Technology
See All in Technology
Engineer Career Talk
lycorp_recruit_jp
0
180
100 名超が参加した日経グループ横断の競技型 AWS 学習イベント「Nikkei Group AWS GameDay」の紹介/mediajaws202411
nikkei_engineer_recruiting
1
170
OCI Network Firewall 概要
oracle4engineer
PRO
0
4.1k
rootlessコンテナのすゝめ - 研究室サーバーでもできる安全なコンテナ管理
kitsuya0828
3
390
AWS Lambdaと歩んだ“サーバーレス”と今後 #lambda_10years
yoshidashingo
1
180
Evangelismo técnico: ¿qué, cómo y por qué?
trishagee
0
360
Can We Measure Developer Productivity?
ewolff
1
150
プロダクト活用度で見えた真実 ホリゾンタルSaaSでの顧客解像度の高め方
tadaken3
0
130
AWS Media Services 最新サービスアップデート 2024
eijikominami
0
200
Shopifyアプリ開発における Shopifyの機能活用
sonatard
4
250
20241120_JAWS_東京_ランチタイムLT#17_AWS認定全冠の先へ
tsumita
2
290
OCI 運用監視サービス 概要
oracle4engineer
PRO
0
4.8k
Featured
See All Featured
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
How To Stay Up To Date on Web Technology
chriscoyier
788
250k
Facilitating Awesome Meetings
lara
50
6.1k
Happy Clients
brianwarren
98
6.7k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Music & Morning Musume
bryan
46
6.2k
Bash Introduction
62gerente
608
210k
The Cult of Friendly URLs
andyhume
78
6k
Speed Design
sergeychernyshev
25
620
Automating Front-end Workflow
addyosmani
1366
200k
Fireside Chat
paigeccino
34
3k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.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