サービス全体の流入が大きくなってきた時、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の負荷分散方法です。

