サービス全体の流入が大きくなってきた時、DBの性能が気になって来ることがあります。mysqlとかであれば、リードレプリカからSelectをすることで負荷を分散することができます。
CakePHPでSELECTの時だけ指定したDBに接続してSELECTする方法を書きます。
■database.phpファイルの記述
リードレプリカ用の設定を記述します。以下のように、通常の接続先とリードレプリカ用の接続先をdatabase.phpに記述します。
// デフォルトの接続先 public $default = array( 'datasource' => 'Database/Mysql', 'persistent' => false, 'host' => 'localhost', 'login' => 'loginuser', 'password' => '', 'database' => 'database_name', 'prefix' => '', //'encoding' => 'utf8', ); // リードレプリカ用の接続先 public $default_read = array( 'datasource' => 'Database/Mysql', 'persistent' => false, 'host' => 'localhost_readreplica', 'login' => 'loginuser_read', 'password' => '', 'database' => 'database_name_readreplica', 'prefix' => '', //'encoding' => 'utf8', );
■AppModelのbeforeFindとafterFindメソッドをオーバーライド
AppModel.phpに以下を記述します。そうすると、自動的にselectだけはレプリカから取得されるようになります。 あとは、このAppModelを継承してモデルを作成すれば、完成です。
/** * SELSECTをする前に実行される関数です。 * セレクト直前にリードレプリカ側を見るように接続を変更しています。 */ public function beforeFind($queryData) { $this->useDbConfig = 'default_read'; foreach ($this->belongsTo as $btModelName => $btModelData) { $this->{$btModelName}->useDbConfig = 'default_read'; } return $queryData; } /** * SELECTが完了するときに実行する関数です。 * リードレプリカから、通常の接続に戻すように変更しています。 */ public function afterFind($results, $primary = false) { $this->useDbConfig = 'default'; foreach ($this->belongsTo as $btModelName => $btModelData) { $this->{$btModelName}->useDbConfig = 'default'; } return $results; }
現状は負荷が低くて同じDBに接続するようにしていても、将来のことを考えて一旦実装しておくのもいいと思います。数少ないDBの負荷分散方法です。