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
推し活の ハイトラフィックに立ち向かう Railsとアーキテクチャ - Kaigi on Ra...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Hayato OKUMOTO
October 26, 2024
Programming
8
8.3k
推し活の ハイトラフィックに立ち向かう Railsとアーキテクチャ - Kaigi on Rails 2024
Hayato OKUMOTO
October 26, 2024
Tweet
Share
More Decks by Hayato OKUMOTO
See All by Hayato OKUMOTO
2分台で1500examples完走!爆速CIを支える環境構築術 - Kaigi on Rails 2025
falcon8823
3
5.5k
Railsアプリケーションと パフォーマンスチューニング ー 秒間5万リクエストの モバイルオーダーシステムを支える事例 ー Rubyセミナー 大阪
falcon8823
7
2.3k
推し活を支えるAngularアプリ 量産体制
falcon8823
0
94
Angular x Auth0 複数サービス展開での認証基盤を考える
falcon8823
0
720
Angular Schematicsを利用した アプリ量産体制
falcon8823
0
250
iOSとIonicとHEIF画像
falcon8823
0
380
Ionicアプリのビルド自動化
falcon8823
0
41
Firebase Authentication - Ionic Meetup #12 Tokyo
falcon8823
0
320
IonicアプリをAuth0で認証する - Ionic Meetup #16 in Online
falcon8823
0
460
Other Decks in Programming
See All in Programming
How to stabilize UI tests using XCTest
akkeylab
0
110
株式会社 Sun terras カンパニーデック
sunterras
0
2.1k
AWS×クラウドネイティブソフトウェア設計 / AWS x Cloud-Native Software Design
nrslib
15
3k
猫の手も借りたい!ので AIエージェント猫を作って社内に放した話 Claude Code × Container Lambda の Slack Bot "DevNeko"
naramomi7
0
260
コードレビューをしない選択 #でぃーぷらすトウキョウ
kajitack
3
890
AIコーディングの理想と現実 2026 | AI Coding: Expectations vs. Reality 2026
tomohisa
0
1.2k
メタプログラミングで実現する「コードを仕様にする」仕組み/nikkei-tech-talk43
nikkei_engineer_recruiting
0
170
米国のサイバーセキュリティタイムラインと見る Goの暗号パッケージの進化
tomtwinkle
2
550
AI主導でFastAPIのWebサービスを作るときに 人間が構造化すべき境界線
okajun35
0
700
go directiveを最新にしすぎないで欲しい話──あるいは、Go 1.26からgo mod initで作られるgo directiveの値が変わる話 / Go 1.26 リリースパーティ
arthur1
2
540
Go1.26 go fixをプロダクトに適用して困ったこと
kurakura0916
0
360
Claude Codeセッション現状確認 2026福岡 / fukuoka-aicoding-00-beacon
monochromegane
4
410
Featured
See All Featured
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.7k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
120
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
300
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
250
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
74
Why Our Code Smells
bkeepers
PRO
340
58k
We Are The Robots
honzajavorek
0
190
The Invisible Side of Design
smashingmag
302
51k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
190
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
390
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
1
150
Transcript
2024年10月26日 推 し 活 の ハ イ ト ラ フ
ィ ッ ク に 立 ち 向 か う R a i l s と ア ー キ テ ク チ ャ 株式会社TwoGate 取締役CTO 奥本 隼
奥本 隼 (Hayato OKUMOTO) @falcon_8823 株式会社TwoGate 取締役CTO チーム組成から11年 / 創業8年
長野高専出身 Rails歴10年以上 自己紹介
Ruby Sponsor
TwoGateの主要なソリューション ライブイベント向け OEM型モバイルオーダーアプリ オンラインくじ ファンクラブアプリ チケットサイト 共通会員ID基盤 Shopify EC構築支援 多数のサービス展開
ライブエンタメ領域に対して、 コンパウンド戦略でサービスを複数展開 しています。
Caravan - イベント物販に特化したアプリ
特徴 サーバサイドはマルチテナント アプリはOEM型 1アーティスト=1アプリ 短納期での提供 内製向けローコード化 負荷対策に強い
事例 TwoGate inc. のApp Storeで一部配信されています。 累計220万DL / 100万ユーザ登録 エンタメ業界、事例を公開しにくい… TwoGateのブースでこっそりお教えします。
累計50アプリほど提供
きっと会場内にも ユーザがいるはず
技術スタック サーバサイド フロントエンド インフラ
Fastly インフラアーキテクチャ 実はシンプル+モノリシックなRailsアプリ ALB nginx nginx Rails App Aurora PostgreSQL
ElastiCache Redis (Cache) ElastiCache Redis (Queue) Sidekiq API Request Amazon ECS
ピークトラフィック CDN 50,000 RPS ALB / Rails 8,000 RPS 決済エンドポイント
400 RPS 先日660 RPSに記録更新
トラフィックに 耐えきれず 障害の経験も
Rails × ハイトラフィック 本発表のテーマ
推し活 × ハイトラフィック
ハイトラフィックに挑む設計 スロークエリをおこさないように実装 CDNでのキャッシュを活用する 後から導入ではなく最初から / CDNでキャッシュするエ ンドポイントは名前空間を切る アプリケーションキャッシュ(Redis)の活用 CDNでのキャッシュがどうしても難しいとき
この規模で起きる問題 DBレイヤーでのボトルネックから始まる インデックスの不足 / クエリが悪い / テーブル設計が悪い 実行計画が変わって急に遅くなることも 各種外部APIのレートリミットに引っかかる ピーク性能を出すパラメータチューニングが必要
ALBのスケーリングが間に合わずにエラーが発生する
どのように対処しているか Performance Insight / APMによる分析 アプリケーションログの分析 特定条件だけ遅いケース:ある商品だけ在庫が非常に多い 実行計画の解析 ChatGPTに投げ込むと便利 負荷試験
ChatGPTで実行計画を解析
先着販売 予告した日時に販売が開始する 在庫限りでの販売 受け取り時間枠選択→商品選択→カート→決済の流れ 本発表で扱うプロダクトの機能 ユーザが一同にアクセスし、在庫の奪い合いが始まる。
ライブエンタメでの販売の難しさ 在庫を綺麗に売り切りたい 在庫数を大幅に超過してはいけない 決済エラー等によって在庫が浮いたままではいけない ピークトラフィックでサーバダウンできない レスポンスタイムの悪化はユーザの不満になる
本発表で扱うテーマ 本発表では、次の2つのテーマについて取り扱います。 高スループットかつ正確な在庫確保のアーキテクチャ 外部決済APIのレートリミットとの向き合い
在庫確保 × パフォーマンス Part.1
在庫確保の簡易な実装 商品ID 在庫数 販売数 P1 100 20 P2 150 10
P3 50 30 在庫テーブル 商品P1を10購入 UPDATE 在庫テーブル SET 販売数 = 販売数 - 10 WHERE 商品ID = P1;
在庫確保の簡易な実装 商品ID 在庫数 販売数 P1 100 10 P2 150 10
P3 50 30 在庫テーブル 商品P1を10購入 UPDATE 在庫テーブル SET 販売数 = 販売数 - 10 WHERE 商品ID = P1; SQLでトランザクションを 学ぶ題材でよく出てくる実装
在庫確保の簡易な実装 商品ID 在庫数 販売数 P1 100 20 P2 150 10
P3 50 30 在庫テーブル 商品P1を10購入 UPDATE 在庫テーブル SET 販売数 = 販売数 - 10 WHERE 商品ID = P1; 同時に購入者がいると… 商品P2を20購入 UPDATE 在庫テーブル SET 販売数 = 販売数 - 20 WHERE 商品ID = P2;
在庫確保の簡易な実装 商品ID 在庫数 販売数 P1 100 -10 P2 150 10
P3 50 30 在庫テーブル 同時に購入者がいると… 在庫数を確認したタイミングと 更新するまでの間に更新が走れ ば、在庫数を超過する。 解決策 行ロックを導入する
在庫確保の安全な実装 商品ID 在庫数 販売数 P1 100 20 P2 150 10
P3 50 30 在庫テーブル 商品P1を10購入 BEGIN; SELECT * FROM 在庫テーブル WHERE 商品ID = P1 FOR UPDATE; -- ここで在庫数 > 販売数を確認 UPDATE 在庫テーブル SET 販売数 = 販売数 - 10 WHERE 商品ID = P1; COMMIT;
行ロックを掛けることで正確な数量の販売ができるように しかし、 数百RPSでの在庫確保のワークロードでは… 同じ行を更新するユーザが多数いる ロックの奪い合いでロック待ち, デッドロックが頻発する 在庫確保の安全な実装
ロック競合を回避するには =同じデータを同時に書き換えないような構造に変更する 次の疑問 どうやって行を奪い合わないようにすればよい?? 同じ行を同時に書き換えるから競合する
在庫テーブルの設計を変える 在庫ID 商品ID ユーザID Z1 P1 Z2 P1 Z3 P1
Z4 P1 在庫テーブル 1行1在庫のテーブルに変える 順番に排出できれば、競合を回避 できるはず。 どのように実装する??
FOR UPDATE SKIP LOCKED これを対処する実装は非常に シンプル 行ロックされている行をスキ ップした結果を応答してくれ る PostgreSQL
9.5~ MySQL 8.0~ BEGIN; SELECT * FROM 在庫テーブル WHERE 商品ID = P1 LIMIT 4 FOR UPDATE SKIP LOCKED; -- ここで行数 = 購入数を確認 UPDATE 在庫テーブル SET ユーザID = Ua WHERE 商品ID = P1; COMMIT;
在庫テーブルの設計を変える 在庫ID 商品ID ユーザID Z1 P1 Z2 P1 Z3 P1
Z4 P1 在庫テーブル ユーザUaがP1を2行取得&ロック 1. ロックが無い2行取得 SELECT * FROM 在庫テーブル WHERE 商品ID = P1 LIMIT 2 FOR UPDATE SKIP LOCKED;
在庫テーブルの設計を変える 在庫ID 商品ID ユーザID Z1 P1 Z2 P1 Z3 P1
Z4 P1 在庫テーブル 2. ユーザUbがP1を3行取得 SELECT * FROM 在庫テーブル WHERE 商品ID = P1 LIMIT 3 FOR UPDATE SKIP LOCKED; Uaがロックしている行をスキップ Z3,Z4の2行だけを返す 足りないので在庫不足で扱う
高スループットでの在庫確保が可能に 行ロックされていない行を必ず返答する保証がある 競合することがなくなり、実測で数百TPSでの処理が可 能に 【余談】Solid QueueはDBをバックエンドにしているが、 同様にFOR UPDATE SKIP LOCKEDを使って実現してい
る
在庫処理まとめ 1在庫1行のデータ構造で管理する 欠点としてテーブルが肥大化するが、販売が終わったら 消すことで解消 FOR UPDATE SKIP LOCKEDで競合を回避する 数百TPSの注文処理を捌ける 先日は200万在庫のテーブルで運用し問題無く捌いた
決済 × パフォーマンス Part.2
前提 クレジットカード決済には外部のペイメントプロバイダを利用 非通過、非保持化のため 決済関連のAPIレートリミットは20-30 rps程度 stripeでもデフォルトは100 rps 決済会社との交渉や料率の交渉が必要 そもそも400 rps近くまでの緩和は厳しい
与信確保 (オーソリ) 決済と在庫確保の流れ 決済できずに宙に浮く在庫を無くすため、この流れで実装。 在庫確保 売上確定 与信開放 (キャンセル) 在庫OK 在庫NG
売り切れた在庫が復活すると、タイミングと件数 によってはクレームが発生するため。
本当にあった怖い話 与信確保→在庫確保→売上確定 売上確定時にレートリミットエラー→ロールバック 奇跡的に与信確保できた人でも、 売上確定時にレートリミットエラー 結局、ほとんど誰も買えない事態に。
じゃあどうする? そもそも、決済プロバイダのレートを上げることができない 非同期にして後から決済を通知する? 待機してもらう?
諦めて待機してもらう いずれにせよ、 解決しない問題なので 諦めました
正しく諦める 決済システムの限界よりもリクエストを受け付けな いようにする これ以上捌けないのに処理を発行しない レートリミットを導入
レートリミットの実装 CDN/WAFで対応する? 正確性や条件制御が単純なため不採用 お高いプランにするとできたりする 正確なレートリミットのためにRedisで自作
決済×パフォーマンスまとめ コロンブスの卵的な対応だが… 限界に対して正しく向き合うことは大事 負荷試験で外部APIをモックするときはレートリミ ット時の挙動も考慮すること
最後に… Railsでハイトラフィックを捌いている事例をお伝 えしました TwoGateはライブエンタメ業界に全方位プロダク トを展開していきます
ASK THE SPEAKER 以下の場所で質疑をお受け付けします! TwoGate企業ブース FREE AFTER PARTY by TWOGATE
& KOMOJU 本日19時開催 『推し活のハイトラフィックに立 ち向かうRailsとアーキテクチャ』 【登壇者】取締役CTO 奥本 『Type on Rails: Railsアプリ ケーションの安全性と開発体験を 型で革新する』 【登壇者】エンジニア 村田 Speakers
None