本文目录导读:

- 使用 Laravel (框架层面)
- 使用 ThinkPHP 6.0+ (框架层面)
- 使用 PHP 原生 + PDO (自研封装)
- 使用数据库中间件 (最推荐)
- 主从延迟与权重的关系(重要)
- 推荐配置层级
- 注意事项
在 PHP 中配置读写分离权重,通常需要结合数据库中间件、ORM 框架或自研封装来实现,下面列出几种常见的配置方式,从框架层面到中间件层面。
使用 Laravel (框架层面)
Laravel 原生支持读写分离,但不支持权重,要实现权重负载,需要结合第三方包或自定义逻辑。
① 原生配置(无权重,随机/轮询)
// config/database.php
'mysql' => [
'read' => [
'host' => [
'192.168.1.1',
'192.168.1.2',
'192.168.1.3',
],
],
'write' => [
'host' => [
'192.168.1.100',
],
],
'sticky' => true,
'driver' => 'mysql',
'database' => 'schema',
'username' => 'root',
'password' => '',
'charset' => 'utf8mb4',
],
② 使用第三方包(支持权重)
推荐包:laravel-doctrine 或自定义连接器。
// 自定义服务提供者中绑定连接器
use Illuminate\Database\Connection;
use Illuminate\Database\Connectors\MySqlConnector;
$this->app->bind('db.connector.mysql', function ($app, $config) {
// 重写 createConnection 方法,在内部实现权重随机算法
});
使用 ThinkPHP 6.0+ (框架层面)
ThinkPHP 6 支持读写分离,并且支持权重配置。
核心配置:
// config/database.php
return [
'connections' => [
'mysql' => [
'type' => 'mysql',
'host' => '192.168.1.100', // 主库(写)
'username' => 'root',
'password' => '',
'database' => 'demo',
// 读写分离配置
'rw_separate' => true,
'read' => [
'host' => [
// 格式:'权重' => '主机'
'weight' => [
'192.168.1.1' => 3, // 权重3
'192.168.1.2' => 2, // 权重2
'192.168.1.3' => 1, // 权重1
],
],
'username' => 'root',
'password' => '',
],
],
],
];
备注:ThinkPHP 内置了 parseWeight 方法,会按照权重比例随机选取从库。
使用 PHP 原生 + PDO (自研封装)
自己写一个数据库连接管理器,实现权重随机。
class DatabaseManager
{
private $readHosts = [
['host' => '192.168.1.1', 'weight' => 3],
['host' => '192.168.1.2', 'weight' => 2],
['host' => '192.168.1.3', 'weight' => 1],
];
private $writeHost = ['host' => '192.168.1.100'];
/**
* 根据权重随机选择从库
*/
private function selectReadHost()
{
$totalWeight = array_sum(array_column($this->readHosts, 'weight'));
$rand = mt_rand(1, $totalWeight);
foreach ($this->readHosts as $host) {
$rand -= $host['weight'];
if ($rand <= 0) {
return $host['host'];
}
}
return $this->readHosts[0]['host'];
}
/**
* 获取 PDO 连接
*/
public function getConnection($isWrite = false)
{
$host = $isWrite ? $this->writeHost['host'] : $this->selectReadHost();
$dsn = "mysql:host={$host};dbname=your_db;charset=utf8mb4";
return new PDO($dsn, 'username', 'password');
}
/**
* 判断 SQL 是读还是写
*/
public function query($sql)
{
$trimmed = trim($sql);
$isWrite = !preg_match('/^(SELECT|SHOW|DESCRIBE|EXPLAIN)/i', $trimmed);
$conn = $this->getConnection($isWrite);
return $conn->query($sql);
}
}
使用数据库中间件 (最推荐)
在实际生产环境中,不推荐在业务代码中配置权重,因为会耦合数据库拓扑,推荐使用中间件:
| 中间件 | 权重配置示例 |
|---|---|
| MySQL Proxy | read_weight = 3:2:1 |
| MyCat | <dataHost balance="1" writeType="0" dbType="mysql"><readHost host="..." weight="3"/></dataHost> |
| ProxySQL | INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight) VALUES (2, 'slave1', 3306, 3); |
| MaxScale | servers = ( slave1, slave2, slave3 ) + weights = 3,2,1 |
| Vitess | 通过 VSchema 配置 weight |
ProxySQL 配置示例:
-- 添加主机并设置权重 INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight) VALUES (2, '192.168.1.1', 3306, 300), (2, '192.168.1.2', 3306, 200), (2, '192.168.1.3', 3306, 100); LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;
PHP 代码只需要连接 ProxySQL 一个入口,完全不需要关心权重逻辑。
主从延迟与权重的关系(重要)
权重配置需要结合主从延迟考虑:
- 延迟高的从库应降低权重(
weight设置小)。 - 建议采用动态权重,例如根据
SHOW SLAVE STATUS的Seconds_Behind_Master实时调整。 - 若业务数据一致性要求高,建议
sticky(会话保持)开启,确保写后立即读到新数据。
推荐配置层级
- 小型项目(单机 PHP):使用 ThinkPHP 8 内置权重配置(最简单)。
- 中型项目(多实例):使用 ProxySQL 中间件统一管理权重。
- 大型分布式架构:使用云数据库(如阿里云 PolarDB、腾讯云 TDSQL),它们自带读写分离和权重策略,PHP 只需连接一个入口。
注意事项
- 权重比例是随机概率,并不是严格轮询。
- 如果从库宕机,需要健康检查剔除节点,否则会导致部分请求失败。
- 建议在业务代码层面加上降级策略:当从库全部不可用时,自动切换主库兜底。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播