MySQLの master-slave 構成への接続設定。
公式ドキュメントだけだと分かりにくいかなー?って人がいるかもしれないということでメモ。
わかりにくかったらお気軽に質問してね。
参考にした公式ドキュメント - Working with Models - Setting multiple databases
設定
概要
編集するファイルは下記3つ。
/app
/config
config.php
service.php
/models
Base.php // 名前は好きにしてOK
では順番に見ていきましょう。
app/config/config.php
まずは設定ファイル
今回は
Master : 1
Slave : 3
の構成で書いてみました。
#マルチMaster構成なんてやったことないけどね。
<?php
(中略)
// masterの設定だよ
$settings = array_merge(
$settings,
array(
'mysql_master' => array(
'adapter' => 'Mysql',
'host' => '[hostname(master)]:[port]', // ex localhost:3306
'username' => 'user',
'password' => 'pass',
'dbname' => 'database',
),
)
);
// slave x3の設定だよ
$slave1 = '[hostname(slave1)]:[port]'; // ex localhost:3316
$slave2 = '[hostname(slave2)]:[port]'; // ex localhost:3326
$slave3 = '[hostname(slave3)]:[port]'; // ex localhost:3336
$mysqlSlaves = array(
'mysql_slave1' => array(
'adapter' => 'Mysql',
'host' => $slave1,
'username' => 'user',
'password' => 'pass',
'dbname' => 'database',
),
'mysql_slave2' => array(
'adapter' => 'Mysql',
'host' => $slave2,
'username' => 'user',
'password' => 'pass',
'dbname' => 'database',
),
'mysql_slave3' => array(
'adapter' => 'Mysql',
'host' => $slave3,
'username' => 'user',
'password' => 'pass',
'dbname' => 'database',
),
);
// ちょっと回りくどい書き方しているのはここでslaveの台数をカウントしたいから。
$settings = array_merge(
$settings,
$mysqlSlaves,
array('mysql_slave_count' => count($mysqlSlaves))
);
(以下略)
これでconfigはOK
app/config/service.php
次にservice.phpでPhalconのDI Containerにサービス登録しちゃいましょう。
Service : dbMasterにMySQL Masterへのコネクション
Service : dbSlaveにMySQL Slaveのいずれか1台へのコネクション
を登録します。
<?php
(中略)
// MySQL master
$di->set('dbMaster', function () use ($config) {
return new DbAdapter(array(
'host' => $config->mysql_master->host,
'username' => $config->mysql_master->username,
'password' => $config->mysql_master->password,
'dbname' => $config->mysql_master->dbname
));
});
// MySQL slave
// slaveの中から1台ランダムに選択。randの上限指定にさっきのslave台数を使ってます。
$di->set('dbSlave', function () use ($config) {
$slaveName = 'mysql_slave' . (String)rand(1, $config->mysql_slave_count);
return new DbAdapter(array(
'host' => $config[$slaveName]['host'],
'username' => $config[$slaveName]['username'],
'password' => $config[$slaveName]['password'],
'dbname' => $config[$slaveName]['dbname']
));
});
(以下略)
app/models/Base.php
そして最後にMaster - Slaveを使う側。Modelです。
公式ドキュメント - Working with Models - Setting multiple databases
のこの辺
「But Phalcon offers you more flexibility, you can define the connection that must be used to ‘read’ and for ‘write’. This is specially useful to balance the load to your databases implementing a master-slave architecture:」
に書かれているように、
Model->initialize()メソッドあたりで読み書きに使用するServiceを指定してあげるといいと思います。
ここで言うServiceとはapp/config/service.phpでDIに登録したmaster or slaveのコネクションです。
書き込み時は
$this->setWriteConnectionService('dbMaster');
に指定したServiceのコネクションを使う。
読み込み時は
$this->setReadConnectionService('dbSlave');
に指定したServiceのコネクションを使う、
といった感じに指定できます。
コードはこんな感じ。
<?php
class Base extends Phalcon\Mvc\Model
{
public function initialize()
{
$this->setWriteConnectionService('dbMaster');
$this->setReadConnectionService('dbSlave');
}
}
MySQLに接続したいModelには、上のBase.phpを継承させてます。
こんな感じ。
<?php
class Robots extends Base
{
(略)
}
これで下記のようにコネクションを使い分けてくれるようになりました。
<?php
$robots = new Robots();
$robots->find(); // dbSlaveへ接続
(略)
$robots->save(); // dbMasterへ接続