php实现mysql读写分离实现
PHP实现MySQL读写分离的方法
MySQL读写分离通过将读操作和写操作分配到不同的数据库服务器,提高系统性能和负载能力。以下是几种常见的实现方式:
使用MySQL主从复制配合PHP代码判断
配置MySQL主从复制环境,主库负责写操作,从库负责读操作。在PHP代码中根据SQL类型选择不同的数据库连接:
// 写操作使用主库
function getMasterConnection() {
$conn = new mysqli('master_host', 'username', 'password', 'dbname');
return $conn;
}
// 读操作使用从库
function getSlaveConnection() {
$conn = new mysqli('slave_host', 'username', 'password', 'dbname');
return $conn;
}
// 根据SQL类型选择连接
function executeQuery($sql) {
if (isWriteQuery($sql)) {
$conn = getMasterConnection();
} else {
$conn = getSlaveConnection();
}
return $conn->query($sql);
}
// 判断是否为写操作
function isWriteQuery($sql) {
$sql = strtolower(trim($sql));
return (strpos($sql, 'insert') === 0) ||
(strpos($sql, 'update') === 0) ||
(strpos($sql, 'delete') === 0) ||
(strpos($sql, 'replace') === 0) ||
(strpos($sql, 'create') === 0) ||
(strpos($sql, 'alter') === 0) ||
(strpos($sql, 'drop') === 0);
}
使用MySQL代理中间件
部署MySQL代理中间件如MySQL Router、ProxySQL或MaxScale,PHP应用只需连接代理服务器:
// 统一连接代理服务器
$conn = new mysqli('proxy_host', 'username', 'password', 'dbname');
代理服务器会自动将写操作路由到主库,读操作路由到从库。
使用PDO实现读写分离
通过PDO扩展实现更灵活的连接管理:
class DB {
private static $master;
private static $slaves = [];
private static $slaveIndex = 0;
public static function getMaster() {
if (!self::$master) {
self::$master = new PDO('mysql:host=master_host;dbname=dbname', 'user', 'pass');
}
return self::$master;
}
public static function getSlave() {
if (empty(self::$slaves)) {
self::$slaves[] = new PDO('mysql:host=slave1_host;dbname=dbname', 'user', 'pass');
self::$slaves[] = new PDO('mysql:host=slave2_host;dbname=dbname', 'user', 'pass');
}
$slave = self::$slaves[self::$slaveIndex % count(self::$slaves)];
self::$slaveIndex++;
return $slave;
}
public static function query($sql) {
if (self::isWriteQuery($sql)) {
return self::getMaster()->query($sql);
} else {
return self::getSlave()->query($sql);
}
}
}
使用框架内置功能
许多PHP框架内置了读写分离支持:
Laravel示例配置:
// config/database.php
'mysql' => [
'read' => [
'host' => ['slave1_host', 'slave2_host'],
],
'write' => [
'host' => 'master_host',
],
'sticky' => true,
'driver' => 'mysql',
// 其他配置...
]
ThinkPHP配置示例:
// database.php
return [
'type' => 'mysql',
'hostname' => 'master_host,slave1_host,slave2_host',
'rw_separate' => true,
// 其他配置...
];
注意事项
- 主从同步延迟问题需要考虑,特别是对实时性要求高的场景
- 事务操作通常需要在主库上执行
- 连接池管理可以提高性能
- 监控主从状态和延迟非常重要
- 故障转移机制需要提前规划
以上方法可根据实际项目需求和规模选择适合的实现方案。对于大型项目,推荐使用专业的中间件解决方案;对于中小型项目,代码层面的实现可能更为简单直接。







