DBレプリケーションで負荷分散

MySQLレプリケーションでmaster/slaveサーバをたててCakePHP1.2で振分をしてみます

参考URL: http://bakery.cakephp.org/articles/view/master-slave-support-also-with-multiple-slave-support

db設定

まず database.php を編集します
SELECT系はslaveサーバに接続するので $default で。レコード更新用に masterサーバを $master として追加設定しました

app/config/database.php

class DATABASE_CONFIG {
	var $default = array( // as MySQL slave server
		'driver' => 'mysql',
		'persistent' => false,
		'host' => 'slave.host',
		'port' => '',
		'login' => 'username',
		'password' => 'password',
		'database' => 'database',
		'schema' => '',
		'prefix' => '',
		'encoding' => 'utf8'
	);
	var $master = array(
		'driver' => 'mysql',
		'persistent' => false,
		'host' => 'master.host',
		'port' => '',
		'login' => 'username',
		'password' => 'password',
		'database' => 'database',
		'schema' => '',
		'prefix' => '',
		'encoding' => 'utf8'
	);
}

更新系のメソッドをmasterサーバに向ける

app_model.php でマスターに接続するようオーバーライドします
参考にした記事では save, updataAll だけでしたが delete, deleteAll も追加しました

  • delete, remove は del のエイリアスなので他のを使うなら注意
  • 使うなら saveAll, saveField も
  • 関係ないけど delete系 に cascade あるのはじめて知った

app/app_model.php

class AppModel extends Model {

	function save($data = null, $validate = true, $fieldList = array()) {
		// Remember the old config (default)
		$oldDb = $this->useDbConfig;
		// Set the new config
		$this->setDataSource('master');
		// Call the original Model::save() method
		$return = parent::save($data, $validate, $fieldList);
		// Reset the config/datasource (default)
		$this->setDataSource($oldDb);

		return $return;
	}

	function updateAll($fields, $conditions = true) {
		$oldDb = $this->useDbConfig;
		$this->setDataSource('master');
		$return = parent::updateAll($fields, $conditions);
		$this->setDataSource($oldDb);
		return $return;
	} 

	function delete($id = null, $cascade = true) {
		$oldDb = $this->useDbConfig;
		$this->setDataSource('master');
		$return = parent::delete($id, $cascade);
		$this->setDataSource($oldDb);
		return $return;
	} 

	function deleteAll($conditions, $cascade = true, $callbacks = false) {
		$oldDb = $this->useDbConfig;
		$this->setDataSource('master');
		$return = parent::deleteAll($conditions, $cascade, $callbacks);
		$this->setDataSource($oldDb);
		return $return;
	} 

}


これだけっぽい

注意点

更新かけてすぐに SELECT するときは レプリケーションのタイムラグがあるのでマスターサーバにつないどかないとダメでした><

分散なんとか勉強会 で

2009/05/30 に福岡である 分散なんとか勉強会 でこういう感じの話をしたりしますのでよかったら参加したらいい