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
GraphQL×Railsアプリのデータベース負荷分散 - 月間3,000万人利用サービスを無停止で
Search
Koya Masuda
September 26, 2025
Programming
1
1.3k
GraphQL×Railsアプリのデータベース負荷分散 - 月間3,000万人利用サービスを無停止で
Koya Masuda
September 26, 2025
Tweet
Share
More Decks by Koya Masuda
See All by Koya Masuda
2度目の参加で気づいたKaigiEffectの“持ち帰り方”
koxya
0
300
Other Decks in Programming
See All in Programming
CSC509 Lecture 03
javiergs
PRO
0
340
Domain-centric? Why Hexagonal, Onion, and Clean Architecture Are Answers to the Wrong Question
olivergierke
2
880
他言語経験者が Golangci-lint を最初のコーディングメンターにした話 / How Golangci-lint Became My First Coding Mentor: A Story from a Polyglot Programmer
uma31
0
170
技術的負債の正体を知って向き合う / Facing Technical Debt
irof
0
170
What's new in Spring Modulith?
olivergierke
1
150
作って理解するGOCACHEPROG / Go Conference 2025(Workshop)
mazrean
0
100
Devvox Belgium - Agentic AI Patterns
kdubois
1
120
Claude CodeによるAI駆動開発の実践 〜そこから見えてきたこれからのプログラミング〜
iriikeita
0
250
Range on Rails ―「多重範囲型」という新たな選択肢が、複雑ロジックを劇的にシンプルにしたワケ
rizap_tech
0
6.6k
Six and a half ridiculous things to do with Quarkus
hollycummins
0
180
Claude Agent SDK を使ってみよう
hyshu
0
780
XP, Testing and ninja testing ZOZ5
m_seki
3
670
Featured
See All Featured
Building an army of robots
kneath
306
46k
Designing for humans not robots
tammielis
254
26k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
127
53k
Build your cross-platform service in a week with App Engine
jlugia
232
18k
Scaling GitHub
holman
463
140k
Designing Experiences People Love
moore
142
24k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
Gamification - CAS2011
davidbonilla
81
5.5k
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.6k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
It's Worth the Effort
3n
187
28k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Transcript
GraphQL×Railsアプリのデータベース負荷分散 - 月間3,000万人利用サービスを無停止で 2025.09.26 Kaigi on Rails 2025 @JP TOWER
Hall & Conference Koya Masuda 1
GraphQL×Railsアプリのデータベース負荷分散 - 月間3,000万人利用サービスを無停止で 2
GraphQL×Railsアプリのデータベース負荷分散 - 月間3,000万人利用サービスを無停止で → RDBにおけるRead/Write Splitting(r/w Splitting) 3
GraphQL×Railsアプリのデータベース負荷分散 - 月間3,000万人利用サービスを無停止で → Rails標準機能に乗っかれなくて困ることがある 4
GraphQL×Railsアプリのデータベース負荷分散 - 月間3,000万人利用サービスを 無停止で → ビジネス要求に答える 💪 5
GraphQL×Railsアプリのデータベース負荷分散 - 月間3,000万人利用サービス を無停止で → マイベスト 6
月間利用者数 3,000 ユーザーの “選択”を サポートするサービス 万人以 上 (2025年8月時点) 7
商品の検証の様子
インターネッツを観測できる 9 非常に強い大型台風10号が日本到来 → 気圧が急激に下がる → みんなのストームグラスがエグくイキリ 立つ → Xにあげてバズる → 検索してマイベストで比較検討する
インターネッツを観測できる 10 非常に強い大型台風10号が日本到来 → 気圧が急激に下がる → みんなのストームグラスがエグくイキリ 立つ → Xにあげてバズる → 検索してマイベストで比較検討する
持ち帰っていただきたいこと 11 • GraphQL × RailsのDB負荷分散はQueryとMutationの責務分離で実現できる • 技術選定は「組織」の観点を持つ • ホワイトリストで小さく試してリスク管理しよう
想定する聞き手 12 • GraphQL × Railsを使って開発している、しようとしている方 • DB負荷分散について学んでみたい方 • リスク管理しながら技術導入するプロセスが気になる方
1 DB負荷分散することになった背景 3 技術選定プロセス 2 Read / Write Splittingの技術 4
GraphQL × RailsでRead / Write Splittingしようとすると困ること 13 アウトライン 5 リスク管理しながら導入する
01 DB負荷分散導入することになった背景 14
テレビ特集 15 某テレビ番組 某コーナー
テレビ特集 • レポーターが話題の企業や人物を徹底取材 • 「今注目の mybestにTV初潜入!」という企画 • 平日朝 7:35から10分ほど特集される 16
マイベストのアーキテクチャ 17 • ECSはオートスケールに対応 • アプリケーションからAuroraへはwriterのクラスターにのみ接続
マイベストのアーキテクチャ 18 やれるとしたらECSタスクを事前 に増やすくらいかなぁ
いざ、放送! 19
サイトめちゃ重い • 1分間に40,000アクセス • 666rps相当 • 鳴り止まないアラート • ECSはオートスケールも… •
DBがボトルネック → サービスダウン 20
テレビ砲直撃 😭 • 1分間に40,000アクセス • 666rps相当 • 鳴り止まないアラート • ECSはオートスケールも…
• DBがボトルネック → サービスダウン 21
これまで月間 3,000万UUを どうやって捌いてきたのか? 🤔 22
普段のユーザー行動 23 https://my-best.com/1234 → 直接アクセスが多いので、コンテンツに CDNキャッシュを設定している スマホ壊れちゃった … 「スマホ おすすめ」
テレビ特集時のユーザー行動 24 マイベストというサービスが あるらしいぞ https://my-best.com/ → サービス名で流入し、キャッシュの効いていないページにアクセス 「マイベスト」
DBをスケールアウトできないと 取れる手段が限られる 25
02 Read / Write Splittingの手段 26
Read / Write Splittingとは? 27
DBサーバー 前提知識:レプリケーション • 複数のサーバーにデータベースを複製 する技術 • 同じデータを持つデータベースに同じ SQLを実行したら、同じ状態になるよね、 という考え方 •
複製されたデータベースをレプリカと呼 ぶ 28 アプリケーション サーバー CRUD データ同期 プライマリ レプリカ https://www.shoeisha.co.jp/book/detail/9784798186627
DBサーバー リードレプリカによる負荷分散 • 参照専用のレプリカをリードレプリカと呼 ぶ • リードレプリカを増やすことで参照SQLを 分散できる • Read(参照)とWrite(更新)のSQLを分
離して別のDBに処理させることを「Read / Write Splitting」という ※以降、プライマリ=writer、レプリカ=readerと表現します 29 アプリケーション サーバー Write データ同期 Read プライマリ リードレプリカ
Read / Write Splittingしてくれるのは誰? 30
①ミドルウェアに任せる ②アプリケーション側で接続するデータベースを分岐する 31 Read / Write Splitting の主なアプローチ
①ミドルウェアに任せる(※Rackではないです) 32 Read / Write Splitting の主なアプローチ アプリケーション サーバー ミドルウェア
ミドルウェアの設定を書く writer reader
②アプリケーション側で接続するデータベースを分岐する 33 Read / Write Splitting の主なアプローチ アプリケーション サーバー ここをアプリケーションで実装する
writer reader
Railsの複数DB • 複数DBのマイグレーション • r/wのロールの自動切り替え • 手動のデータベース接続切替 • モデル単位の切替 34
https://railsguides.jp/v8.0/active_record_multiple_databases.html config/database.yml レプリカには replica: trueを指定する
reader / writer ロールの自動切り替え 35 https://railsguides.jp/v8.0/active_record_multiple_databases.html HTTPメソッドによってreaderとwriterのロールを使い分け POST, DELETE PUT,
PATCH GET, HEAD reader writer
03 技術選定プロセス 36
技術選定、どんな観点で考えるか? 37
技術選定のポイント 38 • 技術に関すること ◦ 要件を満たせる技術なのか? ◦ 拡張性があるか? • 組織に関すること
◦ 普段の開発速度に影響するか? ◦ 扱えるメンバーがどれくらいいるか? https://book.impress.co.jp/books/1118101029
当時のマイベストの開発組織 39 • バックエンドエンジニア:10名 • SRE:2名 ◦ バックエンドから転向&バックエンド兼務 ◦ 業務委託(稼働薄め)
技術選定 40 アプリケーション ミドルウェア 技術 欲しい機能は自分たちで実装 多機能 組織 扱える人数が多い 扱える人数が少ない
技術選定 41 • 複数DBに対応している • 新しい依存関係が増えない • Rails(Ruby)に閉じた中でコントロールできるメリット アプリケーション ミドルウェア
技術 欲しい機能は自分たちで実装 多機能 組織 扱える人数が多い 扱える人数が少ない
技術選定 42 アプリケーション ミドルウェア 技術 欲しい機能は自分たちで実装 多機能 組織 扱える人数が多い 扱える人数が少ない
• 初期実装者の手を離れても、他の開発者がメンテナンスできるメリット
技術選定 43 アプリケーション ミドルウェア 技術 欲しい機能は自分たちで実装 多機能 組織 扱える人数が多い 扱える人数が少ない
• アプリケーションでRead / Write Splittingの制御を行うことに決定
04 GraphQL × Railsでr/w Splitting しようとすると困ること 44
前提知識: GraphQLの基礎① 45 参照がQuery、更新がMutation Operation SQL GraphQL Create INSERT Mutation
Read SELECT Query Update UPDATE Mutation Delete DELETE Mutation
前提知識: GraphQLの基礎② 46 POSTのリクエストボディにクエリを書く to curl
GraphQL × Railsのr/w Splittingで困ること 47
① GraphQLリクエストが HTTP POSTリクエストである 48 RailsはHTTPメソッドで接続DBを切り替えるため、標準機能は使えない POST, DELETE PUT, PATCH
GET, HEAD writer reader
② Queryで更新している(かも) • GETリクエストで更新しているようなもの • Query→参照、Mutation→更新だが、Queryで更新していないかは実装による ◦ Queryの中で`find_or_create_by!`みたいな実装を発見 😭 →
Mutationをwriterに、Queryをreaderに、と単純にはできない 49
① GraphQLがPOSTリクエストな件 50
CQRSパターン 51 参照がQuery、更新がCommand https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/modernization-data-persistence/cqrs-pattern.html
CQRSパターン 52 参照がQuery、更新がCommand https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/modernization-data-persistence/cqrs-pattern.html GraphQLに似ている • CommandがMutation • QueryはそのままQuery
CQRSパターン 53 参照がQuery、更新がCommand https://kaigionrails.org/2023/talks/krpk1900/ GraphQLに似ている • CommandがMutation • QueryはそのままQuery
CQRSパターン 54 Mutation → writer、Query → reader https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/modernization-data-persistence/cqrs-pattern.html
graphql-rubyのTracing 55 • 様々なGraphQLのイベントをフックでき る • 自由にmoduleを定義でき、schemaに mixinできる
Tracingを用いたRead / Write Splitting 56 複数Queryをまとめて実行するメソッド すべてQuery(Mutationを含まない) ならreaderに接続する
② Queryは本当にRead Only…? 57
ホワイトリスト式 Read / Write Splitting 58 Read OnlyなQuery名をホワイトリストに登録 Query &&
ホワイトリスト登録済みか
どうやって Read Onlyなことを確認する? 59
Active Support Instrumentation 60 https://railsguides.jp/active_support_instrumentation.html • Railsの内部イベントをフックできる仕組み • ActiveSupport::Notifications.subscribeでブロック内で測定できる
Active Support Instrumentation 61 https://railsguides.jp/active_support_instrumentation.html • Railsの内部イベントをフックできる仕組み • ActiveSupport::Notifications.subscribeでブロック内で測定できる
Active Support InstrumentationでQueryによるSQLを検査 62 更新SQLを正規表現で探して、見つかったら例外を吐く SQL発行時のイベント 開発環境やステージングに導入し開発時に気がつけるように!
課題と解決アプローチのまとめ 63 1. GraphQLリクエストがHTTP POSTリクエストである → CQRSパターンに沿って、Query → reader、Mutation →
writer 2. Queryで更新している(かも) → Read OnlyなQueryをホワイトリストで管理する
05 リスク管理しながら導入する 64
graphql-rubyのSchema 65 SchemaにはQueryやMutationの型情報やフィールド名を書いておく
マイベストの Schema 66 管理画面 Web アプリ
マイベストの Schema 67 影響箇所や利用時間帯が限られているので、ファーストステップに最適 管理画面 Web アプリ
小さく試す 68 • はじめに管理画面の影響範囲の狭いQueryでの動作確認を取った • その後、Webやアプリの主要Queryをホワイトリストに追加していった • 優先順位はテレメトリから総実行時間が長い順に進めた
メトリクスの変化をお祝い 69
70 プライマリ DBのCPU利用率をピーク時から 50%Down🎉 データベースがスケールアウトできない課題も解決 🎉
まとめ 71 • GraphQL × RailsのDB負荷分散はQueryとMutationの責務分離で実現できる • 技術選定は「組織」の観点を持つ • ホワイトリストで小さく試してリスク管理しよう
About me Koya Masuda • 2021年 新卒で未経験からエンジニア • 2024年~ マイベスト所属
• サッカーが好き @koxya @koxya 72
LT登壇者募集中!!! 73 https://connpass.com/event/370180/