本文目录导读:

对于PHP项目配置数据库主从(读写分离),主要分为应用层配置和数据库层配置两部分,以下是一个逐步的完整解决方案,适用于大多数PHP框架(如Laravel、ThinkPHP)以及原生PHP。
数据库主从环境准备(MySQL)
主库配置(Master)
编辑 MySQL 配置文件 /etc/my.cnf(或 /etc/mysql/mysql.conf.d/mysqld.cnf):
[mysqld] server-id = 1 log_bin = /var/log/mysql/mysql-bin.log binlog-do-db = your_database_name # 可选:指定要同步的数据库 binlog-ignore-db = mysql # 忽略系统库
从库配置(Slave)
[mysqld] server-id = 2 relay-log = /var/log/mysql/mysql-relay-bin.log read_only = 1
主从同步设置
在主库创建同步用户:
CREATE USER 'repl'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES;
查看主库状态:
SHOW MASTER STATUS;
在从库执行同步:
CHANGE MASTER TO MASTER_HOST='主库IP', MASTER_USER='repl', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', -- 从SHOW MASTER STATUS获得 MASTER_LOG_POS=154; -- 从SHOW MASTER STATUS获得 START SLAVE; -- 检查状态(Slave_IO_Running和Slave_SQL_Running均为Yes) SHOW SLAVE STATUS\G
PHP应用层配置(读写分离)
原生PHP(使用PDO)
<?php
class DatabaseManager {
private $master;
private $slave;
public function __construct() {
// 主库连接
$this->master = new PDO(
'mysql:host=主库IP;dbname=your_db;charset=utf8mb4',
'username',
'password'
);
// 从库连接(多个从库可随机选择)
$slaveConfig = [
['host' => '从库1_IP', 'port' => 3306],
['host' => '从库2_IP', 'port' => 3306]
];
$selected = $slaveConfig[array_rand($slaveConfig)];
$this->slave = new PDO(
"mysql:host={$selected['host']};port={$selected['port']};dbname=your_db;charset=utf8mb4",
'username',
'password'
);
}
// 写操作使用主库
public function write($sql, $params = []) {
return $this->master->prepare($sql)->execute($params);
}
// 读操作使用从库
public function read($sql, $params = []) {
$stmt = $this->slave->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
Laravel框架(内置支持)
在 .env 文件中配置:
DB_CONNECTION=mysql DB_HOST=主库IP DB_PORT=3306 DB_DATABASE=your_db DB_USERNAME=root DB_PASSWORD=密码 # 从库配置(支持多个) DB_SLAVE1_HOST=从库1_IP DB_SLAVE1_PORT=3306 DB_SLAVE2_HOST=从库2_IP
在 config/database.php 中完善:
'mysql' => [
'driver' => 'mysql',
'read' => [
'host' => [
env('DB_SLAVE1_HOST', '127.0.0.1'),
env('DB_SLAVE2_HOST', '127.0.0.1'),
],
],
'write' => [
'host' => [
env('DB_HOST', '127.0.0.1'),
],
],
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
// 其他配置...
],
Laravel会自动将读操作分发到从库,写操作发往主库。
ThinkPHP框架
在 config/database.php 中:
'connections' => [
'mysql' => [
'type' => 'mysql',
'hostname' => '主库IP', // 主库
'database' => 'your_db',
'username' => 'root',
'password' => '密码',
'hostport' => '3306',
// 从库配置
'slave' => [
[
'hostname' => '从库1_IP',
'hostport' => '3306',
],
[
'hostname' => '从库2_IP',
'hostport' => '3306',
],
],
'rw_separate' => true, // 启用读写分离
],
],
使用数据库中间件(推荐生产环境)
- ProxySQL:透明代理,应用层只需连接ProxySQL,自动分发读写请求。
- MySQL Router:官方方案,支持故障转移。
安装ProxySQL后配置查询规则:
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup) VALUES (1, 1, '^SELECT', 1); -- SELECT到从库组 INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup) VALUES (2, 1, '.*', 2); -- 其他到主库组 LOAD MYSQL QUERY RULES TO RUN;
关键注意事项
| 问题 | 解决方案 |
|---|---|
| 主从延迟 | 读操作判断延迟:查询从库 Seconds_Behind_Master,延迟大时切换到主库读取 |
| 事务一致性 | 事务内读写必须使用主库(例如开启事务后强制走主库) |
| 负载均衡 | 从库间使用轮询或最少连接算法 |
| 故障转移 | 监控脚本自动切换从库为新主库,或使用MySQL Group Replication |
| 连接池 | 使用长连接池(Swoole/Workerman)避免频繁创建连接 |
高级实现:读写分离过滤器(原生PHP示例)
<?php
class DatabaseRouter {
private $connections = [];
private $useMaster = false;
public function __construct() {
// 初始化主从连接...
}
public function query($sql, $params = []) {
$isSelect = stripos(trim($sql), 'SELECT') === 0;
// 事务中强制走主库
if ($this->inTransaction || !$isSelect) {
return $this->executeOnMaster($sql, $params);
}
// 检查从库延迟
if ($this->getSlaveSecondsBehind() > 10) {
return $this->executeOnMaster($sql, $params);
}
return $this->executeOnSlave($sql, $params);
}
// 记录当前操作需要强制读主库(例如用户资料更新后读取)
public function forceMaster() {
$this->useMaster = true;
}
}
总结推荐方案
- 小型项目:使用框架内置读写分离(Laravel/ThinkPHP)。
- 中型项目:PHP代码层使用路由逻辑 + 数据库连接池。
- 大型项目/高并发:使用ProxySQL或Mycat中间件,结合LVS负载均衡。
最后测试主从同步状态,确认应用层读写分离生效。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播