Yii implements master-slave read/write separation for multiple databases. yii database master-slave read/write _ PHP Tutorial

Source: Internet
Author: User
Yii implements multi-database master-slave read/write splitting. yii database master-slave read/write. Yii implements multi-database master-slave read/write splitting. yii database master-slave read/write this article describes how Yii implements multi-database master-slave read/write splitting. Share it with you for your reference. Yii implements master-slave read/write separation for multiple databases.

This document describes how to implement master-slave read/write splitting for multiple databases in Yii. Share it with you for your reference. The specific analysis is as follows:

Yii Framework database multi-database, master-slave, read/write splitting implementation, function description:

1. Master/Slave Database read/write splitting: Write slave database (multiple): Read

2. when the master database cannot be connected, you can set whether the slave database is writable.

3. when the slave database cannot be connected, you can set whether the master database is readable.

4. if the slave database fails to be connected, you can set it to no longer connect within N seconds.

The code is as follows:

The code is as follows:

<? Php
/**
* The primary database can be read from the database (multiple ).
* Master/Slave Database read/write splitting the master server cannot connect to the slave server. you can switch the write function.
* The slave server cannot connect to the master server. you can switch between the slave server and the master server.
* By lmt
**/
Class DbConnectionMan extends CDbConnection {
Public $ timeout = 10; // connection timeout
Public $ markDeadSeconds = 600; // if the slave database fails to be connected within 600 seconds
// Use cache as the global cache mark
Public $ cacheID = 'cache ';

/**
* @ Var array $ slaves. Slave database connection (Read) config array.
* The configuration complies with CDbConnection.
* @ Example
* 'Components' => array (
* 'DB' => array (
* 'Connectionstring' => 'MySQL :// ',
* 'Slafs' => array (
* Array ('connectionstring' => 'MySQL :// '),
* Array ('connectionstring' => 'MySQL :// '),
*)
*)
*)
**/
Public $ slaves = array ();
/**
*
* If the status of the slave database is false, only the master database is used.
* @ Var bool $ enableSlave
**/
Public $ enableSlave = true;

/**
* @ Var slavesWrite in case of an emergency, the master database cannot connect to the slave server (read/write ).
*/
Public $ slavesWrite = false;

/**
* @ Var masterRead: in an emergency, the master database cannot be connected to the slave server (read/write ).
*/
Public $ masterRead = false;

/**
* @ Var _ slave
*/
Private $ _ slave;

/**
* @ Var _ disableWrite slave server (read-only ).
*/
Private $ _ disableWrite = true;

/**
*
* Override the createCommand method. 1. enable the Slave Database. 2. there is a slave database. 3. not in a transaction. 4. read data from the slave database.
* @ Param string $ SQL
* @ Return CDbCommand
**/
Public function createCommand ($ SQL = null ){
If ($ this-> enableSlave &&! Emptyempty ($ this-> slaves) & is_string ($ SQL )&&! $ This-> getCurrentTransaction () & self: isReadOperation ($ SQL) & ($ slave = $ this-> getSlave ())
){
Return $ slave-> createCommand ($ SQL );
} Else {
If (! $ This-> masterRead ){
If ($ this-> _ disableWrite &&! Self: isReadOperation ($ SQL )){

Throw new CDbException ("Master db server is not available now! Disallow write operation on slave server! ");
}
}
Return parent: createCommand ($ SQL );
}
}

/**
* Obtain the slave server connection resource
* @ Return CDbConnection
**/
Public function getSlave (){
If (! Isset ($ this-> _ slave )){
Shuffle ($ this-> slaves );
Foreach ($ this-> slaves as $ slaveConfig ){
If ($ this-> _ isDeadServer ($ slaveConfig ['ononstring']) {
Continue;
}
If (! Isset ($ slaveConfig ['class'])
$ SlaveConfig ['class'] = 'cdbconnection ';

$ SlaveConfig ['autoconnect '] = false;
Try {
If ($ slave = Yii: createComponent ($ slaveConfig )){
Yii: app ()-> setComponent ('dbslave ', $ slave );
$ Slave-> setAttribute (PDO: ATTR_TIMEOUT, $ this-> timeout );
$ Slave-> setAttribute (PDO: MYSQL_ATTR_USE_BUFFERED_QUERY, true );
$ Slave-> setActive (true );
$ This-> _ slave = $ slave;
Break;
}
} Catch (Exception $ e ){
$ This-> _ markDeadServer ($ slaveConfig ['connectionstring']);
Yii: log ("Slave database connection failed! NtConnection string: {$ slaveConfig ['connectionstring']} ", 'warning ');

Continue;
}
}

If (! Isset ($ this-> _ slave )){
$ This-> _ slave = null;
$ This-> enableSlave = false;
}
}
Return $ this-> _ slave;
}

Public function setActive ($ value ){
If ($ value! = $ This-> getActive ()){
If ($ value ){
Try {
If ($ this-> _ isDeadServer ($ this-> connectionString )){
Throw new CDbException ('master db server is already dead! ');
}
// PDO: ATTR_TIMEOUT must set before pdo instance create
$ This-> setAttribute (PDO: ATTR_TIMEOUT, $ this-> timeout );
$ This-> open ();
} Catch (Exception $ e ){
$ This-> _ markDeadServer ($ this-> connectionString );
$ Slave = $ this-> getSlave ();
Yii: log ($ e-> getMessage (), CLogger: LEVEL_ERROR, 'exception. cdbexception ');
If ($ slave ){
$ This-> connectionString = $ slave-> connectionString;
$ This-> username = $ slave-> username;
$ This-> password = $ slave-> password;
If ($ this-> slavesWrite ){
$ This-> _ disableWrite = false;
}
$ This-> open ();
} Else {// Slave also unavailable
If ($ this-> masterRead ){
$ This-> connectionString = $ this-> connectionString;
$ This-> username = $ this-> username;
$ This-> password = $ this-> password;
$ This-> open ();
} Else {
Throw new CDbException (Yii: t ('yii', 'cdbconnection failed to open the DB connection. '), (int) $ e-> getCode (), $ e-> errorInfo );
}
}
}
} Else {
$ This-> close ();
}
}
}

/**
* Check the SQL statements for read operations
*
* Keyword: SELECT, DECRIBE, SHOW...
* Write operations: UPDATE, INSERT, DELETE...
**/
Public static function isReadOperation ($ SQL ){
$ SQL = substr (ltrim ($ SQL), 0, 10 );
$ SQL = str_ireplace (array ('select', 'show', 'describe', 'pragm'), '^ O ^', $ SQL); // ^ O ^, magic smile
Return strpos ($ SQL, '^ O ^') = 0;
}

/**
* Check whether the slave server is marked as failed.
*/
Private function _ isDeadServer ($ c ){
$ Cache = Yii: app ()-> {$ this-> cacheID };
If ($ cache & $ cache-> get ('adserver: '. $ c) = 1 ){
Return true;
}
Return false;
}

/**
* Mark failed slaves.
*/
Private function _ markDeadServer ($ c ){
$ Cache = Yii: app ()-> {$ this-> cacheID };
If ($ cache ){
$ Cache-> set ('adserver: '. $ c, 1, $ this-> markDeadSeconds );
}
}
}


Main. php configuration: in the components array, the code is as follows:

The code is as follows:

'DB' => array (
'Class' => 'application. extensions. DbConnectionMan ', // extension path
'Connectionstring' => 'MySQL: host = 192.168.1.128; dbname = db_xcpt ', // write data to the primary database
'Default' => true,
'Username' => 'root ',
'Password' => 'root ',
'Charset' => 'utf8 ',
'Tableprefix' => 'xcpt _ ', // table prefix
'Enableslave '=> true, // enable the slave database
'Urgencywrite' => true, // in case of emergency, the master database cannot connect to enable the slave database write function.
'Masterread' => true, // The Master Database read function cannot be enabled from the database in an emergency.
'Slafs' => array (// slave database
Array (// slave1
'Connectionstring' => 'MySQL: host = localhost; dbname = db_xcpt ',
'Default' => true,
'Username' => 'root ',
'Password' => 'root ',
'Charset' => 'utf8 ',
'Tableprefix' => 'xcpt _ ', // table prefix
),
Array (// slave2
'Connectionstring' => 'MySQL: host = localhost; dbname = db_xcpt ',
'Default' => true,
'Username' => 'root ',
'Password' => 'root ',
'Charset' => 'utf8 ',
'Tableprefix' => 'xcpt _ ', // table prefix
),

),
),

I hope this article will help you design php programs based on the Yii Framework.

In this example, Yii implements multi-database master-slave read/write splitting. Share it with you for your reference. With...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.