php自己实现读者分离
PHP实现读写分离的方法
读写分离是数据库优化的常见策略,通过将读操作和写操作分配到不同的数据库服务器上,提高系统性能。以下是几种实现方式:
使用PDO或MySQLi手动切换连接
创建两个数据库连接对象,分别对应主库(写)和从库(读),在代码中根据操作类型选择连接:

// 主库连接(写)
$master = new PDO('mysql:host=master_host;dbname=db', 'user', 'pass');
// 从库连接(读)
$slave = new PDO('mysql:host=slave_host;dbname=db', 'user', 'pass');
function getConnection($isWrite = false) {
global $master, $slave;
return $isWrite ? $master : $slave;
}
// 读操作
$readConn = getConnection();
$stmt = $readConn->query('SELECT * FROM table');
// 写操作
$writeConn = getConnection(true);
$stmt = $writeConn->prepare('INSERT INTO table VALUES(?)');
使用中间件代理
通过中间件自动路由SQL请求,例如MySQL Router或ProxySQL:

// 所有请求发送到代理服务器
$db = new PDO('mysql:host=proxy_host;dbname=db', 'user', 'pass');
// 代理会自动将SELECT路由到从库,其他语句路由到主库
$db->query('SELECT...'); // 从库
$db->exec('INSERT...'); // 主库
基于抽象层的实现
在ORM或数据库抽象层中实现逻辑,例如Laravel的数据库配置:
// config/database.php
'mysql' => [
'write' => [
'host' => 'master_host'
],
'read' => [
'host' => ['slave1_host', 'slave2_host']
]
]
// 使用时自动处理读写分离
DB::table('users')->get(); // 从读库查询
DB::table('users')->insert(...); // 写入主库
注意事项
- 主从同步延迟可能导致读取到旧数据,对一致性要求高的场景需要特殊处理
- 事务操作必须全部在主库执行
- 从库需要负载均衡时可采用轮询或随机选择策略
- 连接失败时需要有故障转移机制
扩展方案
对于更复杂的场景,可以考虑:
- 使用MySQL Group Replication构建多主集群
- 结合缓存层减少数据库压力
- 实现健康检查自动剔除故障节点
- 使用GTID跟踪同步状态
以上方法可根据项目规模和需求选择适合的实现方案,小型项目适合手动切换连接,大型项目建议使用专业中间件。






