实现原理
Laravel5 读写分离主要有两个过程:
第一步,根据 database.php 配置,创建写库和读库的链接 connection
第二步,调用 select 时先判断使用读库还是写库,而 insert/update/delete 统一使用写库
主要文件:Illuminate/Database/Connectors/ConnectionFactory.php
1:判断 database.php 是否配置了读写分离数据库
/**
* Establish a PDO connection based on the configuration.
*
* @param array $config
* @param string $name
* @return \Illuminate\Database\Connection
*/
public function make(array $config, $name = null)
{
$config = $this->parseConfig($config, $name);
// 如果配置了读写分离,则同时创建读库和写库的链接
if (isset($config['read'])) {
return $this->createReadWriteConnection($config);
}
// 如果没有配置,默认创建单个数据库链接
return $this->createSingleConnection($config);
}
2:看看如何创建读库和写库的链接
/**
* Create a single database connection instance.
*
* @param array $config
* @return \Illuminate\Database\Connection
*/
protected function createReadWriteConnection(array $config)
{
// 获取写库的配置信息,并创建链接
$connection = $this->createSingleConnection($this->getWriteConfig($config));
// 创建读库的链接
return $connection->setReadPdo($this->createReadPdo($config));
}
3:多个读库如何选择
/**
* Get the read configuration for a read / write connection.
*
* @param array $config
* @return array
*/
protected function getReadConfig(array $config)
{
$readConfig = $this->getReadWriteConfig($config, 'read');
// 如果数组即多个读库,那么通过随机函数array_rand()挑一个,默认取第一个
if (isset($readConfig['host']) && is_array($readConfig['host'])) {
$readConfig['host'] = count($readConfig['host']) > 1
? $readConfig['host'][array_rand($readConfig['host'])]
: $readConfig['host'][0];
}
return $this->mergeReadWriteConfig($config, $readConfig);
}
4:写库也是随机选择的
/**
* Get a read / write level configuration.
*
* @param array $config
* @param string $type
* @return array
*/
protected function getReadWriteConfig(array $config, $type)
{
// 如果多个,那么通过随机函数array_rand()挑一个
if (isset($config[$type][0])) {
return $config[$type][array_rand($config[$type])];
}
return $config[$type];
}
总结:
1:可以设置多个读库和多个写库,或者不同组合,比如一个写库两个读库
2:每次只创建一个读库链接和一个写库链接,从多个库中随机选择一个;