はじめに

DX開発事業部の深川です。

システムのスケーラビリティと可用性向上のため、Amazon Aurora MySQL のリード・レプリカを活用したリード・ライト分離(Read-Write Splitting)は非常に一般的なアーキテクチャです。しかし、この構成を Laravel で導入する際、「データを更新した直後に画面を再描画しても変更が反映されない」というデータ不整合の現象に遭遇することがあります。

この記事では、LaravelでAuroraのリード・ライト分離を設定した環境で発生したこの問題を、config/database.phpの設定一つで解消した事例とその仕組みについて解説します。

🛠️ 発生した問題と環境

発生した現象

設定環境 DB構成 動作
DB_CONNECTION=mysql-ssl シングルインスタンス 問題なし
DB_CONNECTION=mysql-ssl-two-hosts Aurora(ライター/リーダー) 更新直後に再描画すると、古いデータが表示される

mysql-ssl-two-hosts環境では、データを書き込み(writeした後、すぐにそのデータを使って読み込み(readを行った際、変更が反映されていませんでした。

AWS Auroraとデータ不整合の原因

この問題は、Auroraのクラスターエンドポイント(ライター)リーダーエンドポイント(リード・レプリカ)を使用する構成と、その間のレプリケーション遅延に起因します。

  1. 書き込み(Write): ライターインスタンス(マスターDB)に対して実行されます。
  2. 読み込み(Read): リーダーインスタンス(スレーブDB、リード・レプリカ)に対して実行されます。

更新直後の読み込みがリーダーインスタンスに対して行われた場合、ライターインスタンスでの変更がまだリーダーにレプリケーション(同期)されていないわずかな時間帯に、リーダーは古いデータを持っているため、不整合なデータが表示されてしまうのです。

💡 解決策:'sticky' => true の設定

この「更新直後のリードを強制的にライターに固定する」という問題を解決したのが、Laravelのデータベース接続設定にある'sticky'オプションtrueに変更することでした。

変更した設定(config/database.php

'mysql-ssl-two-hosts' => [
    // ... その他の設定 ...
    'sticky' => true, // 👈 これを追加!
    // ... その他の設定 ...
],

'sticky'オプションとは?

Laravelのstickyオプションは、リード・ライト分離構成において、「直前のリクエストで書き込み(Write)が実行されていた場合、その後の読み込み(Read)を一時的に書き込み用の接続(ライターインスタンス)に固定する」という機能を提供します。

  • 'sticky' => false (デフォルト): 書き込み後も、即座に読み込み用の接続(リーダーインスタンス)を使用しようとします。
  • 'sticky' => true: 書き込みが行われたリクエスト内では、データの一貫性を保つため、その後の読み込みもライターインスタンスに接続し直します。

これにより、ユーザーがデータを更新した直後のリダイレクトや再描画といった一連の処理の中で、必ず最新のデータを参照できるようになり、Auroraのレプリケーション遅延による不整合をアプリケーション側で吸収できます。

📝 まとめ

Amazon Auroraは高パフォーマンスなデータベースソリューションですが、そのリード・レプリカ(リーダーインスタンス)を活用したリード・ライト分離には、レプリケーション遅延によるデータ不整合のリスクが伴います。

Laravelでは、この問題を'sticky' => trueというシンプルな設定で、開発者がAuroraのレプリケーション遅延を意識することなく、データの一貫性を確保することができます。

Aurora環境でリード・ライト分離を構築する際は、このstickyオプションの設定を忘れないようにしましょう。

この記事が、LaravelとAmazon Auroraの構成における問題解決の助けになれば幸いです!