menu
デジタルファームは、札幌・東京・大阪を拠点に、Web戦略の立案からシステム開発、ホームページ制作、SNS運用、運用改善まで一貫支援。Web活用によるビジネス課題解決をサポートします。

スケールアウトでは解決できなかった問題を SQLite で乗り越えた話

シェア
ツイート
シェア
ブックマーク
タイトルとURLをコピー
スケールアウトでは解決できなかった問題を SQLite で乗り越えた話

最終更新日:2026/08/08   公開日:2026/03/25

はじめに

あるウェブサイトには定期的に公開される特設ページがあり、公開のたびにアクセスが集中します。インフラとしてはオートスケーリングに対応しており、AP サーバーも DB も必要に応じてスケールできる構成でした。通常の運用ではそれで問題なく回っていたのですが、この特設ページの公開時には AP・DB の台数を増やしても最大ピークを解決できず 50x エラーが発生してしまいました。

本記事では、この問題をどのように分析して、どのように解決したかを紹介します。

起きていたこと

特設ページの公開時にアクセスが急増し、サービス全体で 50x エラーが発生するようになりました。オートスケーリングが効いているはずの環境で、AP・DB ともに台数を増やして対応を試みましたが、状況は完全には改善しませんでした。 ただし、ピーク時間がかなり短かったため、対応中にピーク時間が過ぎ、アクセス頻度が少し下がってくると徐々に安定していきました。

また、厄介だったのは、影響範囲がこの特設ページだけに留まらなかったことです。特設ページ内の機能が通常の機能と DB を共有しているため、そこでクエリが詰まるとサービス全体のリクエスト処理が遅延し、特設機能とは無関係な機能まで巻き添えで応答に問題が発生してしまっていました。

なぜスケールアウトで解決しなかったのか

根本原因は DB クエリの遅延でした。特設ページの検索機能が発行するクエリが重く、ピーク時にレスポンスが大幅に遅延していたことが原因です。

ここで問題になるのが、AP を増やしたときの挙動です。AP の台数が増えると、それだけ DB に対する同時接続数も増えます。しかし DB 側のクエリ処理が追いつかないため、AP はレスポンスを待ち続けることになります。待ちが溜まると AP のワーカーが埋まり、やがて新規リクエストを受け付けられなくなります。結果として、AP を増やせば増やすほど DB への負荷が高まり、状況がさらに悪化するという悪循環に陥っていました。

もちろん DB 側もスケールアウトして台数は増やしていましたが、話はそう単純ではありません。 残念ながら Aurora のリードレプリカを多少増やした程度(今回のケースでは通常の3倍を用意しました)ではピークの負荷に追いつきませんでした。

ピークに対応しようとした場合、計算上では更に多く(おそらく通常の10倍以上の)DBを用意する必要がありました。 期間の限られている特設ページとはいえ、これだけの追加リソースが必要となるので、インフラでの解決を考える前にアプリケーション側の改修を考えるべきだと考えました。

どう解決したか

まず、この特設機能を改めて整理したところ、以下のような性質があることが分かりました。

  • ランディングページ(LP)的性質のページである:ウェブサイトの共通設定などを参照しに DB アクセスする必要がない
  • 検索機能のみである:データの書き込みは発生しない
  • CDNが有効に働かない:利用者が色々なパターンで検索するため、CDN によるページキャッシュと相性が悪い
  • データは事前に確定している:公開前にデータを用意できる
  • データの量が十分小さい:検索対象のデータは数万件以下

これらの性質から、共通 DB にアクセスせずとも、必要なデータを各 AP サーバーにコピーして、それを参照することで特設機能が動作することが分かります。 

これらの条件を踏まえて、SQLite を採用するアプローチを取りました。

事前にデータを SQLite ファイルとして生成し、各 AP サーバーに配置します。
今回は、APをオートスケーリングで構築していますが、各スケーリングサーバーは定期的に最新データと同期するような設計となっています。 そのため、SQLite ファイルを更新した場合でも、スケーリングサーバーが増えた場合でも、特別な対応をせずとも各 AP サーバーに最新のデータが反映されます。

そして、特設機能ではリクエストがきたら、DB に問い合わせる代わりにローカルの SQLite ファイルを参照するようにします。

この方式のメリットは明確です。

  • DB への依存がなくなる:ネットワーク越しの通信もコネクションプールも不要になる
  • AP を増やすほどスケールする:各インスタンスが独立してデータを持つので、AP の増加がそのまま処理能力の向上に直結する
  • サービス本体に影響しない:共有 DB を経由しないため、特設機能の負荷がサービス全体に波及しなくなる
  • 改修が容易:共通DB(MySQL)のクエリ実行部分をそのまま SQLite への呼び出しに修正するだけなので、ソースコード全体の修正は少ない

SQLite を利用する方式がインフラコスト面まで含めて、あまりにもメリットが多かったため、こちらを採用しました。 

他のアイデアとしては、例えばキャッシュの追加、Redis などのインメモリキャッシュの追加、AWS Lambda を用いてランディングページを独立させるなどのアイデアがありました。
しかし、この特設ページは前述の通り CDN キャッシュとは相性が悪いため、同じような解決方法であるアプリケーションキャッシュ・DBのクエリキャッシュなどを活用しても効果的とは考えられませんでした。
Redis の追加はミドルウェアの追加となり、コスト増加と安定性の低下が考えられます。
ランディングページを独立させて、この部分を自動スケールする AWS Lambda で対応するパターンの実装も考えましたが、そこまでしなくても SQLite への変更の方が実装コストが十分に小さく、現実的でした。

結果

この改修により、特設ページ公開時のピークアクセスに対して問題なく耐えられるようになりました。レスポンスも非常に速い状態を保っており、50x エラーは解消し、サービス全体が道連れになる事象も発生しなくなりました。

おわりに

今回の事例で改めて実感したのは、スケールアウトすればなんでも解決できるわけではないということです。 スケーリング可能なインフラであっても、アプリケーションのボトルネックを解消しない限り根本的な解決にはなりません。

今回は対象の性質から、SQLite を使うことが有効な選択肢になりました。 すべてのケースに当てはまるわけではありませんが、「共有リソースへの依存を減らす」「処理を AP 側に寄せる」という発想は、同様の問題に直面したときのヒントになるかもしれません。