アンチパターンを踏んでいると、トランザクション量・データ量の増加に伴って劇的に性能悪化することがわかった - イオンの店舗一覧ページ改善プロジェクトから得た教訓

アンチパターンを踏んでいると、トランザクション量・データ量の増加に伴って劇的に性能悪化することがわかった - イオンの店舗一覧ページ改善プロジェクトから得た教訓

2025/5/13

Share

この記事に登場している人

石川 晴貴

Haruki Ishikawa

イオンスマートテクノロジー株式会社 Developer Enablementディビジョン TechLeadユニット TechLeadチーム エンジニア
ex-株式会社トラストバンク サーバーサイドエンジニア

2020年に株式会社チェンジに新卒入社。1年ほどITコンサルタントの経験を経た後、2021年8月から同ホールディングスの子会社である株式会社トラストバンクへ出向。3年間サーバーサイドエンジニアとしてふるさと納税ポータルサイト「ふるさとチョイス」の開発並びに、同システムの外部連携システムの開発・運用とその他新規システムの設計・開発業務に従事。2024年6月より現職。

# 室蘭工業大学 #トラストバンク # ITコンサルタント # サーバーサイド #PHP #Python

    高川 祐樹

    Yuki Takagawa

    株式会社ココロザシ 技術部
    愛知でシステム開発やアプリ開発に従事した後、転職して現在は地元の石川からリモートで開発業務を行っている。
    2024年にイオンスマートテクノロジー株式会社の店舗一覧ページ改善プロジェクトに業務委託として参画。

    この記事を読むとわかること

    ・「1リクエスト4000クエリ」問題を解消し、応答時間1/3・インフラ費用1/4の改善を実現
    ・New Relicを活用し、憶測ではなく定量的分析でボトルネックを特定
    ・Laravel設定漏れやN+1、DB設計の課題など複数のアンチパターンを可視化・解消
    ・効果×実装容易性で優先順位を設計し、段階的な改善で大幅なパフォーマンス向上へ

    1回のリクエストで4000回を超えるデータベースコール。通常時で1.2秒だった応答時間は、災害時のアクセス増に耐えきれず、対症療法としてインフラ費用は倍々に膨れ上がった。コードは当初、確かに"動いて"いた。だが、データ量とトラフィックの増加とともに、その設計は静かに破綻へと向かっていた——。

    そんな状況を救ったのは、たった1行の設定追加と、根本的なアンチパターンの排除だった。応答時間は1/3に激減し、インフラ費用は4分の1にまで削減された。イオンの店舗一覧ページ改善プロジェクトが明らかにしたのは、「アンチパターンを踏んでいると、トランザクション量の増加に伴って指数関数的に性能悪化する」という、ありふれていながらも見落とされがちな本質だった。

    本記事では、このプロジェクトを牽引したイオンスマートテクノロジー(以下、AST)高川と石川のインタビューをもとに、問題発見から解決までのプロセスを掘り下げていく。

    【目次】

    急激なリクエスト増とコスト上昇の板挟みから始まった開発

    パフォーマンスが悪化していたのは、イオングループの店舗一覧ページから店舗を検索する顧客向けのシステムだ。特に災害時やテレビ放映時の急激なリクエスト増に耐えられなくなっていたという。

    この問題に対応するため、ASTではデータベースのスペックを段階的に上げ続けていた。「インフラのスペックアップで、インフラ費用も倍々で上がってしまっていた」と石川は説明する。つまり、対症療法としてリソースを増強していたものの、根本的な問題解決には至っていなかったのだ。

    高川はこのときの状況を次のように分析する。

    性能問題は突然現れたわけではなく、データ量とトランザクション量の増加に伴って徐々に悪化していきました。当初のデータ量が少ない頃は問題なく動作していましたが、データが増えるにつれて応答時間が急激に悪化していったのです。(高川)

    「憶測」ではなく「定量的な実態把握」から始めたアプローチ

    「性能を向上させると同時にインフラ費用も削減する」という一見相反するミッションが課された店舗一覧ページ改善プロジェクト。同プロジェクトを任された高川が最初に直面したのは、問題の根本原因が明確になっていないという状況だった。

    プロジェクトにアサインされるまでは、実態の詳細がわかりませんでした。一番の問題点は、応答時間の悪化の原因が憶測で語られていることでした。『APIを使っているから遅い』『店舗一覧ページから直接SQLを叩いたら速くなるはず』といった根拠の乏しい仮説もありました。(高川)

    これは技術的負債を抱えたシステムでよく見られる現象だ。真のボトルネックを特定せず、憶測に基づいた対策を講じても効果は限定的になる。

    ここで高川が活用したのが、かつての職場でも使用経験のあったパフォーマンス監視ツールNew Relicだった。ASTではすでに導入済みだったため、まずはNew Relicを用いた実態把握から始めた。New RelicのAPM画面で、アプリケーションのTop 20 Transactionsを見ると、最も処理時間が長いトランザクションを特定することができる。

    そして、New Relicを使った詳細分析により、システム内に潜んでいた複数の性能低下要因が明らかになった。

    たとえば、リクエストごとに4000回以上のデータベースアクセスが発生しているケースがあり、これは典型的なN+1クエリ問題でした。他にも、Laravelのオプティマイズ設定不足や、プライマリDBとレプリカDBの使い分け問題など、複数のアンチパターンが存在していました。(高川)

    実際に発見された複数のアンチパターンとは

    実際に発見された主な問題点は以下のとおりだ。

    1. N+1クエリ問題

    まずは、データベースへの問い合わせが大量に発生していた問題。親レコードをループで処理しながら、それぞれに関連する子レコードを個別に取得する処理が原因で、1リクエストあたり4000回以上のクエリが発行されているケースもあった。

    見た瞬間に、これはN+1クエリ問題だとわかりました。N+1クエリ問題の恐ろしいところは、親の数に比例してクエリ数が増えることです。たとえば親レコードが10から100に増えただけで、発行されるクエリは90個ではなく900個増えることもある。当初は気にならなくても、データが増えるとあっという間にボトルネックになります。(高川)

    2. フレームワークの非最適な使用

    続いて、PHPフレームワークであるLaravelの本番環境用の最適化設定が適用されていなかった問題。最適化設定が適用されていなかったため、キャッシュが利用されず、リクエストごとに設定ファイルやルート情報を毎回読み込む処理が発生していた。

    本番環境では最適化しておくべきキャッシュ関連の設定が不足していました。これはトラフィックが増えれば増えるほど影響が大きくなる典型的な問題です。(高川)

    3. データベースアクセスの問題

    データベースアクセスの設計にも課題があった。店舗システムは、社内で利用するCMSと、顧客に向けたホームページ一覧からなるが、実は裏では同じデータベースを参照していたという。

    CMSは管理側、ホームページ一覧はお客さま側が見る画面で、それぞれ目的はまったく異なります。しかしながら、CMSと店舗一覧ページが同じデータベースを参照し、CMSからの更新作業中に発生する高負荷なクエリについても、店舗一覧ページと共有するレプリカDBへの問い合わせとなっていました。そのため、CMSで高負荷な更新処理を実行すると店舗一覧ページの表示にまで影響を及ぼしてしまう仕組みとなっていました。(石川)

    4. クラウド環境への非対応

    クラウド移行による典型的な問題点も生じていた。オンプレミス仕様のままAzureにリフトされたことで、接続失敗などクラウド特有のエラーへの再試行処理がなされておらず、負荷時にエラー率が上昇していた。

    クラウド移行時にベストプラクティスを採用していなかったことに起因するエラーが複数生じていました。たとえば、クラウド環境では、接続成功を前提にできないため、接続再試行のロジックを入れる必要があります。こういった対応がされていなかったため、動作が不安定になっていました。(高川)

    これらのアンチパターンに共通するのは、データ量やトランザクション量が少ない初期の段階では問題が顕在化しにくいという点だ。しかし、データが増え、アクセスが集中すると、急激に性能が悪化する。これがまさに「指数関数的な性能悪化」の正体といえる。

    優先順位は、「効果」と「実装の容易さ」で判断

    発見された問題に対処するため、高川はまず優先順位付けを行った。「一番先にやりたかったのは、ヘビーな問題だが、簡単に解決できるもの」と高川は語る。「効果の大きさ」と「実装の容易さ」という二軸で考え、最も効率的な改善から取り組んだ。

    具体的には、Laravelの最適化オプションが適用されていなかった点から着手した。デプロイ時にフレームワーク側の処理にスロースパンが発生していた原因について調査したところ、単純にキャッシュ系のベストプラクティスを実行していなかったことに気づいたという高川。実際に最適化コマンドを実行したところ、即座にパフォーマンスの改善が確認できたと言う。

    開発環境では、毎回必要なファイルを都度読み込む動作でも問題ありませんが、本番環境ではデプロイ時点でコードや設定が固定されるため、ファイルを事前にキャッシュしておく必要があります。Laravelでもベストプラクティスとしても推奨されていますが、それをやっていなかったことで、不要なファイル読み込みが都度発生していました。それが明らかになったことで『あぁ、これは optimizeオプションを付ければ一発で改善するじゃん』と気づきました。(高川)

    この対応だけでも店舗一覧ページが利用するバックエンドシステムの応答時間は大幅に改善した。

    当初1.2秒ほどかかっていたのが、対応後は400ミリ秒以下まで下がりました。3分の1以下になったんです。(石川)


    インフラ費用1/4、応答時間3倍以上の改善

    その後、N+1クエリの改善や、データベース向き先の制御など、より複雑な課題に順次対応していった結果、大きな成果を上げることができた。

    最も注目すべき点は、当初2段階上げたデータベースのスペックを、改善後には2段階下げられたことである。つまりインフラ費用は1/4になり、それでいて応答時間は3倍以上改善したのだ。

    「性能も上げながらインフラ費用も下げる」という一見矛盾する目標を達成できた理由について、石川と高川は「アンチパターンを踏むとちゃんと遅くなることがわかったため」と総括する。単にハードウェアリソースを増強するという対症療法では、根本的な解決にならないことが明確になった形だ。

    改善活動で見つけた失敗と学び

    もちろん、すべてが順調だったわけではない。高川は「データのバリエーションテストのパターンが足りなくて、ケース漏れをしたことがあります」と振り返る。「APIの特定のデータパターンによってインターフェースが変わってしまう現象があり、リリース後に不具合が起きてロールバックした」経験から、テストの重要性を再認識したという。

    石川は「仕様書がなく、コードリーディングで仕様を把握するしかなかった状況で、網羅的にテストを行うのは不可能です。その状態でテストがなかったことで、起こるべくして起こった」と補足。この経験から、ユニットテストの導入も進めているとのことだ。

    実態を捉えて、王道の改善を

    経験から得た知見として、「想像で語らずに、きちんと実態を把握しながら進めていくべき」と強調する石川。「まずは性能劣化の根拠を事実ベースで確認する。一番大きなボトルネックを把握して優先順位をつける。そうすれば時間をかけたのに効果が出なかったということにはならない」と、地道な分析の重要性を説く。

    特に優先順位付けについて、高川は「効果が大きく実装が容易なものから対応するという原則は、どんなプロジェクトでも役立ちます。そして効果を測定するためには、New Relicのようなモニタリングツールが不可欠」と語る。

    インフラ費用1/4、応答時間3倍という劇的な改善が証明するのは、リソース増強という対症療法ではなく、根本的な問題解決の価値である。実態を正確に把握し、効果の大きい施策から優先的に対応するという王道のアプローチが、性能向上とインフラ費用削減の両立を達成する鍵となった。

    現在、SREチーム主導でのAkamaiキャッシュ導入など、さらなる改善策も進行中である。今後もASTは、安定したUXと高効率なシステム運用を両立させる取り組みを続けていく。


    イオングループでは一緒に変革に挑んでくれる方を募集中です。

    どんなことをしているのか気になる方は、お気軽にご連絡ください。カジュアル面談も実施しておりますので、まずはざっくばらんにお話しましょう!

    ※掲載している所属・役職・肩書きおよび各種情報は、記事公開時点のものです。

    Share

    JOIN US

    AEONで働きたい人は、採用サイトもチェック

    カジュアル
    面談

    に申し込む