ある程度の規模のアプリケーションでは、Amazon AuroraやMySQLのレプリケーション機能を利用して、マスター/スレーブ構成でのデータベースを構築することがよくあります。
アプリケーションからの参照系クエリ(SELECT)はスレーブサーバーに向けて実行、一方更新系のSQL(INSERT/UPDATE/DELETE)はマスターサーバーに向けて実行し、マスターサーバーからスレーブサーバーに変更内容を同期する、という構成にすることで、データ参照時の性能向上や負荷分散、可用性・冗長性の向上が期待できます。
これを実現するには、アプリケーション側で発行されるSQLに応じて、マスター向け/スレーブ向けの2つのデータベースコネクションを使い分ける必要があります。
Laravelでマスター/スレーブ構成のDBに接続するための設定
Laravelには、標準でマスター向け/スレーブ向けのコネクションの使い分けを実現するための設定方法が用意されています。
やり方は、config/database.php
に、read
、write
それぞれの接続先を設定するだけです。
<?php return [ 'connections' =--> [ 'mysql' => [ 'driver' => 'mysql', 'read' => [ 'host' => env('DB_SLAVE_HOST', '127.0.0.1'), 'port' => env('DB_SLAVE_PORT', '3306'), ], 'write' => [ 'host' => env('DB_MASTER_HOST', '127.0.0.1'), 'port' => env('DB_MASTER_PORT', '3306'), ], 'sticky' => true, 'database' => env('DB_DATABASE', 'database'), 'username' => env('DB_USERNAME', 'appuser'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => 'InnoDB ROW_FORMAT=DYNAMIC', ],
これだけで、自動的にクエリに応じた接続が使われることになります。
- SELECTクエリ発行時はread(スレーブ)
- それ以外はwrite(マスター)
アプリケーション側でどちらの接続を使用するかを明示的に指定する必要はありません。
補足1: .envの設定方法
なおこの例では、実際の接続先の値を.env
から取得しています。次のキーであらかじめ.env
に設定を定義しておきましょう。
- DB_SLAVE_HOST
- DB_SLAVE_PORT
- DB_MASTER_HOST
- DB_MASTER_PORT
補足2: stickyオプション
sticky
オプションをtrue
にしておくと、マスターへの更新系SQLを実行した同一のHTTPリクエストでは、それ以降の参照系クエリ(SELECT)をスレーブではなくマスターに対して行うようになります。
マスターへの更新内容がスレーブに同期される前にスレーブのデータを参照しようとして発生してしまう不整合を、防止するための仕組みです。
コメント