插件窝 干货文章 php如何实现mysql读写分离

php如何实现mysql读写分离

master 读写 slave 分离 710    来源:    2025-03-18

在PHP中实现MySQL的读写分离,通常需要结合数据库中间件或手动配置来实现。以下是几种常见的实现方式:

1. 使用数据库中间件(如MySQL Proxy、MaxScale、ProxySQL等)

数据库中间件可以自动处理读写分离,应用程序只需要连接到中间件,中间件会根据SQL语句的类型(读或写)将请求转发到相应的数据库服务器。

示例:使用ProxySQL

  1. 安装和配置ProxySQL

    • 安装ProxySQL并配置主从数据库服务器。
    • 配置读写分离规则,例如将SELECT查询转发到从库,将INSERTUPDATEDELETE等写操作转发到主库。
  2. PHP连接ProxySQL

    $host = 'proxysql_host';
    $user = 'your_username';
    $pass = 'your_password';
    $dbname = 'your_database';
    
    $conn = new mysqli($host, $user, $pass, $dbname);
    
    if ($conn->connect_error) {
       die("Connection failed: " . $conn->connect_error);
    }
    
    // 执行查询
    $sql = "SELECT * FROM your_table";
    $result = $conn->query($sql);
    
    if ($result->num_rows > 0) {
       while($row = $result->fetch_assoc()) {
           echo "id: " . $row["id"]. " - Name: " . $row["name"]. "<br>";
       }
    } else {
       echo "0 results";
    }
    
    $conn->close();
    

2. 手动实现读写分离

如果你不想使用中间件,可以在PHP代码中手动实现读写分离。通常的做法是维护两个数据库连接,一个用于读操作,一个用于写操作。

示例:手动实现读写分离

// 主库连接(写操作)
$master_host = 'master_host';
$master_user = 'master_user';
$master_pass = 'master_pass';
$master_dbname = 'master_db';

$master_conn = new mysqli($master_host, $master_user, $master_pass, $master_dbname);

if ($master_conn->connect_error) {
    die("Master Connection failed: " . $master_conn->connect_error);
}

// 从库连接(读操作)
$slave_host = 'slave_host';
$slave_user = 'slave_user';
$slave_pass = 'slave_pass';
$slave_dbname = 'slave_db';

$slave_conn = new mysqli($slave_host, $slave_user, $slave_pass, $slave_dbname);

if ($slave_conn->connect_error) {
    die("Slave Connection failed: " . $slave_conn->connect_error);
}

// 读操作
$sql = "SELECT * FROM your_table";
$result = $slave_conn->query($sql);

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo "id: " . $row["id"]. " - Name: " . $row["name"]. "<br>";
    }
} else {
    echo "0 results";
}

// 写操作
$sql = "INSERT INTO your_table (name) VALUES ('John Doe')";
if ($master_conn->query($sql) === TRUE) {
    echo "New record created successfully";
} else {
    echo "Error: " . $sql . "<br>" . $master_conn->error;
}

$master_conn->close();
$slave_conn->close();

3. 使用ORM框架(如Laravel、Doctrine等)

许多PHP框架内置了读写分离的支持。例如,Laravel框架可以通过配置文件轻松实现读写分离。

示例:Laravel中的读写分离

  1. 配置数据库连接: 在config/database.php中配置主从数据库连接:

    'mysql' => [
       'read' => [
           'host' => ['slave1_host', 'slave2_host'],
       ],
       'write' => [
           'host' => ['master_host'],
       ],
       'sticky' => true,
       'driver' => 'mysql',
       'database' => 'your_database',
       'username' => 'your_username',
       'password' => 'your_password',
       'charset' => 'utf8mb4',
       'collation' => 'utf8mb4_unicode_ci',
       'prefix' => '',
    ],
    
  2. 使用Eloquent ORM: Laravel会自动处理读写分离,你只需要正常使用Eloquent ORM即可:

    // 读操作
    $users = DB::table('users')->get();
    
    // 写操作
    DB::table('users')->insert(['name' => 'John Doe']);
    

总结

  • 使用中间件:适合需要自动化管理读写分离的场景,减少代码复杂性。
  • 手动实现:适合需要精细控制读写分离的场景,但代码复杂度较高。
  • 使用ORM框架:适合使用框架的项目,简化配置和代码。

根据你的项目需求和复杂度,选择合适的方式来实现MySQL的读写分离。