thinkphp Distributed database Connection code detailed introduction

Source: Internet
Author: User
Tags dsn explode getmessage

Thinkphp as a domestic popular framework, I believe that the use of people must be a minority. In this article, we will analyze the important part of thinkphp--the connection of distributed database.

Of course, we're not here to use the model to make a database-altering search. We are to the bottom of the connection code to do an analysis, can help you better understand the thinkphp to the database operation. Convenient for us to use later.

One, a single database connection

When used, the connection configuration of a single database is very simple. We only need to configure the information in the configuration file.

' Db_type ' => ' MySQL ',
' Db_host ' => ' 192.168.5.102 ',
' Db_name ' => ' databasename ',
' Db_user ' => ' USER ',
' Db_pwd ' => ' password ',
' Db_port ' => ' 3306 ',
' Db_prefix ' => ' onmpw_ ',

After the setup is complete, you can use it. A single database connection is by default.

Second, the Distributed database connection

The connection of a single database is simple, we focus on the connection of the distributed database.

' Db_type ' => ' MySQL ',
' Db_host ' => ' 192.168.5.191,192.168.5.88,192.168.5.103 ',
' Db_name ' => ' test,test,test ',
' Db_user ' => ' Masteruser,slaveuser,slaveuser ',
' Db_pwd ' => ' Masterpass,slavepass,slavepass ',
' Db_port ' => ' 3306 ',
' Db_prefix ' => ',
' Db_deploy_type ' => 1,//Database Deployment mode: 0 Centralized (single server), 1 distributed (Master-slave server)
' Db_rw_separate ' => true,///database read/write separate master-slave valid
' Db_master_num ' => 1,//read/write separated rear server number
' Db_slave_no ' => ',//specify from server serial number

You can connect to a distributed database by using the above configuration.

Let's look at a few options below

' Db_host '

Distributed database, several servers are required to fill out several server addresses, separated by commas between each address. If it is a master-slave distribution, the previous address is the address of the primary database.

For the following username and password and listening port, of course, there are a few to write a few. If each database has the same username and password, you can write only one.

The code for parsing these options is as follows

$_config[' username '] = explode (', ', $this->config[' username '));
$_config[' password '] = explode (', ', $this->config[' password '));
$_config[' hostname '] = explode (', ', $this->config[' hostname '));
$_config[' hostport '] = explode (', ', $this->config[' Hostport '));
$_config[' database ' = explode (', ', $this->config[' database ');
$_config[' DSN ' = Explode (', ', $this->config[' DSN '));
$_config[' charset '] = explode (', ', $this->config[' CharSet '));

' Db_deploy_type ' =>1

1 means distributed, and 0 represents a centralized (that is, a single server).

The implementation of this option is in the class Think\db\dirver

protected function Initconnect ($master =true) {
if (!empty ($this->config[' deploy '))
Using Distributed databases
$this->_linkid = $this->multiconnect ($master);
Else
Default Single Database
if (! $this->_linkid) $this->_linkid = $this->connect ();
}

$this->config[' Deploy '] represents the ' db_deploy_type ' configuration option, which has been parsed prior to use, and the configuration items are in the $this->config array. As for how to parse the configuration file, here we do not introduce, interested can refer to the Think\db class.

$this->multiconnect () function is used for distributed connections, and if the ' db_deploy_type ' option is set to 1, the function executes. Otherwise, the $this->connect () function is executed directly.

' Db_rw_separate ' =>true

True indicates read-write detach; false means no separation.

It should be noted here that the separation of read and write is based on the master-slave database system. When this option is set to True, the primary database is written and read from the database.

if ($this->config[' rw_separate ']) {
Master-Slave type using read-write separation
if ($master)
Primary server Write
$r = $m;
else{
if (Is_numeric ($this->config[' slave_no ')) {//Specify server Read
$r = $this->config[' slave_no '];
}else{
Read operation connection from server
$r = Floor (Mt_rand ($this->config[' Master_num '],count ($_config[' hostname ')-1)); Each randomly connected database
}
}
}else{
Read-write operations do not differentiate between servers
$r = Floor (Mt_rand (0,count ($_config[' hostname ')-1)); Each randomly connected database
}

$this->config[' Rw_separate '] is true, read-write separation is used, and read-write is not separated when false. Why must the separation of read and write be master-slave? Because the server can not write only read, if you write data from the server, the data can not be synchronized. This can result in inconsistent data. So, if our system is master-slave, we must use read-write separation. This means that the Db_rw_separate option must be configured to TRUE.

' Db_master_num ' =>1

The number following this option indicates the number of primary servers after read-write separation. Therefore, this option is also used for master-slave database systems.

The following code selects the primary server.

$m = Floor (Mt_rand (0, $this->config[' Master_num ']-1));

The core code to read from the server when reading from the master-slave database

$r = Floor (Mt_rand ($this->config[' Master_num '],count ($_config[' hostname ')-1)); Each randomly connected database

where $this->config[' Master_num ' represents the number of primary servers.

' Db_slave_no ' => '

Specifies the ordinal number from the server to use for reading data. If not set, the number of books from the server is calculated based on the number of primary servers, which is then randomly selected for reading.

if (Is_numeric ($this->config[' slave_no ')) {//Specify server Read
$r = $this->config[' slave_no '];
}else{
Read operation connection from server
$r = Floor (Mt_rand ($this->config[' Master_num '],count ($_config[' hostname ')-1)); Each randomly connected database
}

The above is a simple description of the implementation code for each option's function.

Now let's look at the part of the connection.

if ($m!= $r) {
$db _master = Array (
' Username ' => isset ($_config[' username '] [$m])? $_config[' username '] [$m]:$_config[' username '][0],
' Password ' => isset ($_config[' password '] [$m])? $_config[' Password '] [$m]:$_config[' password '][0],
' Hostname ' => isset ($_config[' hostname '] [$m])? $_config[' hostname '] [$m]:$_config[' hostname '][0],
' Hostport ' => isset ($_config[' hostport '] [$m])? $_config[' Hostport '] [$m]:$_config[' Hostport '][0],
' Database ' => isset ($_config[' database ' [$m])? $_config[' database ' [$m]:$_config[' database '][0],
' DSN ' => isset ($_config[' DSN ' [$m])? $_config[' DSN ' [$m]:$_config[' DSN '][0],
' CharSet ' => isset ($_config[' charset '] [$m])? $_config[' CharSet '] [$m]:$_config[' CharSet '][0],
);
}
$db _config = Array (
' Username ' => isset ($_config[' username '] [$r])? $_config[' username '] [$r]:$_config[' username '][0],
' Password ' => isset ($_config[' password '] [$r])? $_config[' Password '] [$r]:$_config[' password '][0],
' Hostname ' => isset ($_config[' hostname '] [$r])? $_config[' hostname '] [$r]:$_config[' hostname '][0],
' Hostport ' => isset ($_config[' hostport '] [$r])? $_config[' Hostport '] [$r]:$_config[' Hostport '][0],
' Database ' => isset ($_config[' database ' [$r])? $_config[' database ' [$r]:$_config[' database '][0],
' DSN ' => isset ($_config[' DSN ' [$r])? $_config[' DSN ' [$r]:$_config[' DSN '][0],
' CharSet ' => isset ($_config[' charset '] [$r])? $_config[' CharSet '] [$r]:$_config[' CharSet '][0],
);
return $this->connect ($db _config, $r, $r = = $m? false: $db _master);

Seeing this, I think you should be able to see what it does with the "and $m" in the code that describes each configuration option.

Now let's see $r = = $m? False: $db _master, if the database reads and writes is not separated, the read and write is a server to pass to the Connect function the value is false. Or, if it is a master-slave write, the value passed to connect is also false. From the above code we see that if "and $m are not equal, the $db_master will be set." In fact, is equivalent to a standby, if the selected server fails to connect, will go to connect $db_master.

The third parameter of the Connect () function actually indicates whether an alternate connection is selected when the $db_config server fails. False indicates no reconnection, and other values indicate reconnection.

Its core code is as follows

try{
if (Empty ($config [' DSN '])) {
$config [' dsn '] = $this->parsedsn ($config);
}
if (Version_compare (php_version, ' 5.3.6 ', ' <= ')) {
Disabling impersonation preprocessing statements
$this->options[pdo::attr_emulate_prepares] = false;
}
$this->linkid[$linkNum] = new PDO ($config [' DSN '], $config [' username '], $config [' Password '], $this->options);
}catch (\pdoexception $e) {
if ($autoConnection) {//$autoConnection is not false, but is the default primary server
Trace ($e->getmessage (), ', ' ERR ');
return $this->connect ($autoConnection, $linkNum); An exception was found, and a recursive function was used to reconnect
}elseif ($config [' Debug ']) {
E ($e->getmessage ());
}
}

This way, for the master-slave, $r and $m will certainly not be the same. So if you are reading the data, the choice of the one from the server failure, that the primary server is standby, and finally to the main server read. Can ensure the timeliness of data reading.

However, the general feeling is not perfect now. If there are more than one from the server, in the reading of the selection from the server and the main server have failed, the data will not be read failed. It should be more secure if you can read the other from the server again. Of course, the current thinkphp function has been quite perfect enough for us to use. But still hope thinkphp more and more perfect later.

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.