search
HomeBackend DevelopmentPHP TutorialHow to connect to distributed database in Thinkphp

How to connect to distributed database in Thinkphp

Dec 23, 2017 pm 02:00 PM
thinkphpdistributeddatabase

Thinkphp is a mainstream framework in China, and I believe there must be many people using it. Today we will take a look at how to connect to a distributed database in Thinkphp.

Of course, we are not here to explain how to use the model to add, delete, modify, and query the database. We are doing an analysis of its underlying connection code, which can help you better understand thinkphp's operation of the database. To facilitate our future use.

1. Single database connection

When used, the connection configuration of a single database is very simple. We only need to configure some 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_',

It can be used after the setting is completed. The default is a single database connection.

2. Distributed database connection

The connection to a single database is very simple. Let’s focus on analyzing the connection to 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, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'DB_RW_SEPARATE'        =>  true,       // 数据库读写是否分离 主从式有效
'DB_MASTER_NUM'         =>  1, // 读写分离后 主服务器数量
'DB_SLAVE_NO'           =>  '', // 指定从服务器序号

Follow the above configuration to connect to the distributed database.

Let’s look at the following options

'DB_HOST'

Distributed database, if there are several servers, you need to fill in several server addresses, and use separated by commas. If it is a master-slave distribution, the previous address must be the address of the master database.

For the following user names, passwords, listening ports, etc., of course, write down as many as you have. If the username and password of each database are the same, you can only write 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, 0 means 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']))
       // 采用分布式数据库
       $this->_linkID = $this->multiConnect($master);
    else
       // 默认单数据库
       if ( !$this->_linkID ) $this->_linkID = $this->connect();
}

$this->config['deploy'] represents the 'DB_DEPLOY_TYPE' configuration option, the above configuration They have been parsed before use, and the configuration items are in the $this->config array. As for how to parse the configuration file, we will not introduce it here. Those who are interested can refer to the Think\Db class.

$this->The multiConnect() function is used for distributed connections. If the 'DB_DEPLOY_TYPE' option is set to 1, this function will be executed. Otherwise, execute the $this->connect() function directly.

‘DB_RW_SEPARATE’=>true

true means reading and writing are separated; false means reading and writing are not separated.

It should be noted here that the separation of reading and writing is based on the master-slave database system. When this option is set to true, the master database writes and the slave database reads.

if($this->config['rw_separate']){
      // 主从式采用读写分离
      if($master)
          // 主服务器写入
          $r  =   $m;
      else{
          if(is_numeric($this->config['slave_no'])) {// 指定服务器读
              $r = $this->config['slave_no'];
          }else{
               // 读操作连接从服务器
              $r = floor(mt_rand($this->config['master_num'],count($_config['hostname'])-1));   // 每次随机连接的数据库
          }
            }
}else{
      // 读写操作不区分服务器
      $r = floor(mt_rand(0,count($_config['hostname'])-1));   // 每次随机连接的数据库
}

$this->config[‘rw_separate’] When it is true, reading and writing are separated. When it is false, reading and writing are not separated. Why does the separation of reading and writing have to be master-slave? Because the slave server cannot write and can only read, if data is written to the slave server, the data cannot be synchronized. This will cause data inconsistency. Therefore, if our system is master-slave, we must use read-write separation. In other words, the DB_RW_SEPARATE option must be configured as true.

'DB_MASTER_NUM'=>1

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

The following code selects the main server.

$m  =  floor(mt_rand(0,$this->config['master_num']-1));

When reading from a master-slave database, select the core code to read from the slave server

$r = floor(mt_rand($this->config['master_num'],count($_config['hostname'])-1));   // 每次随机连接的数据库

where $this->config[‘master_num’] represents the number of master servers.

'DB_SLAVE_NO'=> ''

Specify the serial number of the slave server for reading data. If not set, the number of slave servers will be calculated based on the number of master servers, and then one will be randomly selected for reading.

if(is_numeric($this->config['slave_no'])) {// 指定服务器读
   $r = $this->config['slave_no'];
}else{
   // 读操作连接从服务器
   $r = floor(mt_rand($this->config['master_num'],count($_config['hostname'])-1));   // 每次随机连接的数据库
}

The above is a simple explanation of the implementation code of the role of each option.

Let’s take a look at the connection part

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 everyone should understand the role of $r and $m when introducing the code for each configuration option above. .

Now let's look at $r == $m ? false : $db_master. If the database reading and writing are not separated, and the reading and writing is a server, the value passed to the connect function is false. Or if the master-slave write is separated, the value passed to connect is also false. From the above code we see that if $r and $m are not equal, $db_master will be set. In fact, it is equivalent to a backup. If the selected $r server fails and cannot be connected, it will connect to $db_master.

The third parameter of the connect() function actually indicates whether to choose an alternate connection when the $db_config server connection fails. False means no reconnection, other values ​​mean reconnection.

The core code is as follows

try{
   if(empty($config['dsn'])) {
      $config['dsn']  =   $this->parseDsn($config);
   }
   if(version_compare(PHP_VERSION,&#39;5.3.6&#39;,&#39;<=&#39;)){
       // 禁用模拟预处理语句
       $this->options[PDO::ATTR_EMULATE_PREPARES]  =   false;
   }
   $this->linkID[$linkNum] = new PDO( $config[&#39;dsn&#39;], $config[&#39;username&#39;], $config[&#39;password&#39;],$this->options);
}catch (\PDOException $e) {
   if($autoConnection){ //$autoConnection不为false,而是默认的主服务器
        trace($e->getMessage(),&#39;&#39;,&#39;ERR&#39;);
            return $this->connect($autoConnection,$linkNum);  //出现异常,使用递归函数重新连接
        }elseif($config[&#39;debug&#39;]){
            E($e->getMessage());
    }
}

In this way, for the master-slave type, $r and $m will definitely not be the same. Therefore, if the selected slave server fails when reading data, the master server will be the backup and will eventually go to the master server to read. It can ensure the timeliness of data reading.

However, I always feel that it is not perfect yet. If there are multiple slave servers, and both the slave server and the master server selected during reading fail, then the data reading will fail. At this time, it should be more secure if other slave servers can be read again. Of course, the current functions of thinkphp are quite complete and sufficient for our use. But I still hope that thinkphp will become more and more perfect in the future.

I hope the above introduction can be helpful to everyone when using thinkphp for development.

Related recommendations:

ThinkPHP5 framework basic knowledge, development specifications and directory structure

ThinkPHP file caching class code sharing

ThinkPHP Db and model performance evaluation


The above is the detailed content of How to connect to distributed database in Thinkphp. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Explain how load balancing affects session management and how to address it.Explain how load balancing affects session management and how to address it.Apr 29, 2025 am 12:42 AM

Load balancing affects session management, but can be resolved with session replication, session stickiness, and centralized session storage. 1. Session Replication Copy session data between servers. 2. Session stickiness directs user requests to the same server. 3. Centralized session storage uses independent servers such as Redis to store session data to ensure data sharing.

Explain the concept of session locking.Explain the concept of session locking.Apr 29, 2025 am 12:39 AM

Sessionlockingisatechniqueusedtoensureauser'ssessionremainsexclusivetooneuseratatime.Itiscrucialforpreventingdatacorruptionandsecuritybreachesinmulti-userapplications.Sessionlockingisimplementedusingserver-sidelockingmechanisms,suchasReentrantLockinJ

Are there any alternatives to PHP sessions?Are there any alternatives to PHP sessions?Apr 29, 2025 am 12:36 AM

Alternatives to PHP sessions include Cookies, Token-based Authentication, Database-based Sessions, and Redis/Memcached. 1.Cookies manage sessions by storing data on the client, which is simple but low in security. 2.Token-based Authentication uses tokens to verify users, which is highly secure but requires additional logic. 3.Database-basedSessions stores data in the database, which has good scalability but may affect performance. 4. Redis/Memcached uses distributed cache to improve performance and scalability, but requires additional matching

Define the term 'session hijacking' in the context of PHP.Define the term 'session hijacking' in the context of PHP.Apr 29, 2025 am 12:33 AM

Sessionhijacking refers to an attacker impersonating a user by obtaining the user's sessionID. Prevention methods include: 1) encrypting communication using HTTPS; 2) verifying the source of the sessionID; 3) using a secure sessionID generation algorithm; 4) regularly updating the sessionID.

What is the full form of PHP?What is the full form of PHP?Apr 28, 2025 pm 04:58 PM

The article discusses PHP, detailing its full form, main uses in web development, comparison with Python and Java, and its ease of learning for beginners.

How does PHP handle form data?How does PHP handle form data?Apr 28, 2025 pm 04:57 PM

PHP handles form data using $\_POST and $\_GET superglobals, with security ensured through validation, sanitization, and secure database interactions.

What is the difference between PHP and ASP.NET?What is the difference between PHP and ASP.NET?Apr 28, 2025 pm 04:56 PM

The article compares PHP and ASP.NET, focusing on their suitability for large-scale web applications, performance differences, and security features. Both are viable for large projects, but PHP is open-source and platform-independent, while ASP.NET,

Is PHP a case-sensitive language?Is PHP a case-sensitive language?Apr 28, 2025 pm 04:55 PM

PHP's case sensitivity varies: functions are insensitive, while variables and classes are sensitive. Best practices include consistent naming and using case-insensitive functions for comparisons.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor