php自己实现读者分离
PHP实现读写分离的方法
读写分离是一种常见的数据库优化策略,通过将读操作和写操作分发到不同的数据库服务器,减轻主库压力。以下是在PHP中实现读写分离的几种方法:
使用PDO或MySQLi手动切换连接
通过代码逻辑判断SQL类型,动态选择主库或从库连接:

// 主库配置
$master = new PDO('mysql:host=master_host;dbname=db', 'user', 'pass');
// 从库配置
$slave = new PDO('mysql:host=slave_host;dbname=db', 'user', 'pass');
function getConnection($sql) {
// 判断SQL类型
if (preg_match('/^(INSERT|UPDATE|DELETE|REPLACE)/i', $sql)) {
return $GLOBALS['master'];
} else {
return $GLOBALS['slave'];
}
}
// 使用示例
$sql = "SELECT * FROM users";
$conn = getConnection($sql);
$stmt = $conn->query($sql);
使用中间件实现读写分离
通过数据库中间件自动路由请求,应用层无需关心具体实现:

// 使用ProxySQL或MySQL Router等中间件
$db = new PDO('mysql:host=proxy_host;dbname=db', 'user', 'pass');
// 所有查询通过中间件自动路由
$sql = "SELECT * FROM products"; // 自动路由到从库
$db->query($sql);
$sql = "UPDATE products SET stock=10"; // 自动路由到主库
$db->exec($sql);
使用ORM框架的读写分离功能
主流PHP框架通常内置读写分离支持:
// Laravel示例配置
'mysql' => [
'driver' => 'mysql',
'read' => [
'host' => ['slave1', 'slave2'],
],
'write' => [
'host' => 'master',
],
// 其他配置...
],
// 使用时不需手动区分
$users = DB::table('users')->get(); // 自动使用从库
DB::table('users')->insert(['name' => 'test']); // 自动使用主库
实现自定义数据库连接池
对于高性能场景可考虑连接池管理:
class DBConnectionPool {
private $master;
private $slaves = [];
private $currentSlave = 0;
public function getWriteConnection() {
return $this->master;
}
public function getReadConnection() {
$conn = $this->slaves[$this->currentSlave];
$this->currentSlave = ($this->currentSlave + 1) % count($this->slaves);
return $conn;
}
}
注意事项
- 主从同步延迟问题:写后立即读可能导致数据不一致,需要根据业务场景处理
- 事务处理:涉及事务的操作必须使用主库
- 负载均衡:多个从库时需要合理分配读请求
- 故障转移:需要处理主库或从库宕机的情况
实现时应根据具体业务需求选择合适方案,简单场景可使用手动切换,复杂系统建议采用中间件或框架内置功能。






