导读:本期聚焦于小伙伴创作的《PHP数据库读写分离怎么配置?主从复制与负载均衡设置指南》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《PHP数据库读写分离怎么配置?主从复制与负载均衡设置指南》有用,将其分享出去将是对创作者最好的鼓励。

PHP数据库读写分离是提升高并发场景下数据库性能的核心方案,核心思路是将写操作指向主数据库,读操作分发到多个从数据库,结合主从复制保证数据一致性,再通过负载均衡优化从库的请求分配。

一、MySQL主从复制配置

主从复制是读写分离的基础,需要先完成主从数据库的环境搭建与同步配置,这里以MySQL 8.0为例说明步骤。

1. 主数据库配置

首先修改主库的配置文件,Linux系统下路径通常为/etc/my.cnf,Windows系统下为my.ini,添加以下配置:

[mysqld]
# 启用二进制日志,主从复制必须开启
log-bin=mysql-bin
# 设置服务器唯一ID,主从库ID不能重复
server-id=1
# 需要同步的数据库名,多个数据库可重复配置
binlog-do-db=test_db
# 忽略同步的数据库
binlog-ignore-db=mysql

配置完成后重启MySQL服务,然后登录主库执行以下命令创建用于同步的账号并授权:

-- 创建同步账号,密码为slave_pass
CREATE USER 'slave_user'@'%' IDENTIFIED BY 'slave_pass';
-- 授予同步权限
GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%';
-- 刷新权限
FLUSH PRIVILEGES;
-- 查看主库状态,记录File和Position值
SHOW MASTER STATUS;

2. 从数据库配置

修改从库的配置文件,设置唯一的服务器ID:

[mysqld]
# 从库唯一ID,不能和主库及其他从库重复
server-id=2
# 启用中继日志
relay-log=mysql-relay

重启从库服务后,登录从库执行同步配置命令,将之前记录的主库File和Position值填入:

-- 配置主库连接信息
CHANGE MASTER TO
MASTER_HOST='主库IP地址',
MASTER_USER='slave_user',
MASTER_PASSWORD='slave_pass',
MASTER_LOG_FILE='mysql-bin.000001', -- 替换为SHOW MASTER STATUS得到的File值
MASTER_LOG_POS=156; -- 替换为SHOW MASTER STATUS得到的Position值
-- 启动同步
START SLAVE;
-- 查看同步状态,确保Slave_IO_Running和Slave_SQL_Running都是Yes
SHOW SLAVE STATUSG

二、PHP层读写分离实现

完成主从复制后,需要在PHP代码中实现读写请求的分发逻辑,这里以PDO扩展为例实现简单的读写分离。

1. 基础配置类实现

首先定义数据库配置数组,区分主库和从库信息:

<?php
class DbConfig {
    // 主库配置,处理写操作
    public static $master = [
        'host' => '127.0.0.1',
        'port' => 3306,
        'dbname' => 'test_db',
        'user' => 'root',
        'pass' => 'master_pass'
    ];
    // 从库配置数组,处理读操作,可配置多个从库
    public static $slaves = [
        [
            'host' => '192.168.0.2',
            'port' => 3306,
            'dbname' => 'test_db',
            'user' => 'root',
            'pass' => 'slave_pass1'
        ],
        [
            'host' => '192.168.0.3',
            'port' => 3306,
            'dbname' => 'test_db',
            'user' => 'root',
            'pass' => 'slave_pass2'
        ]
    ];
}

2. 读写分离连接类实现

实现连接管理类,根据SQL语句类型选择对应的数据库连接:

<?php
class DbConnection {
    private $masterPdo;
    private $slavePdos = [];
    // 获取主库连接
    public function getMasterPdo() {
        if (!$this->masterPdo) {
            $cfg = DbConfig::$master;
            $dsn = "mysql:host={$cfg['host']};port={$cfg['port']};dbname={$cfg['dbname']};charset=utf8mb4";
            $this->masterPdo = new PDO($dsn, $cfg['user'], $cfg['pass'], [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
            ]);
        }
        return $this->masterPdo;
    }
    // 随机获取一个从库连接,实现简单负载均衡
    public function getSlavePdo() {
        $slaveCfg = DbConfig::$slaves[array_rand(DbConfig::$slaves)];
        $key = $slaveCfg['host'] . ':' . $slaveCfg['port'];
        if (!isset($this->slavePdos[$key])) {
            $dsn = "mysql:host={$slaveCfg['host']};port={$slaveCfg['port']};dbname={$slaveCfg['dbname']};charset=utf8mb4";
            $this->slavePdos[$key] = new PDO($dsn, $slaveCfg['user'], $slaveCfg['pass'], [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
            ]);
        }
        return $this->slavePdos[$key];
    }
    // 根据SQL语句判断使用主库还是从库
    public function getPdoBySql($sql) {
        $sql = trim($sql);
        // 写操作相关关键字,匹配则使用主库
        $writeKeywords = ['INSERT', 'UPDATE', 'DELETE', 'REPLACE', 'CREATE', 'ALTER', 'DROP'];
        foreach ($writeKeywords as $keyword) {
            if (stripos($sql, $keyword) === 0) {
                return $this->getMasterPdo();
            }
        }
        // 读操作使用从库
        return $this->getSlavePdo();
    }
}

3. 使用示例

调用连接类执行数据库操作:

<?php
$db = new DbConnection();
// 写操作,自动使用主库
$writeSql = "INSERT INTO user (name, age) VALUES ('张三', 25)";
$pdo = $db->getPdoBySql($writeSql);
$pdo->exec($writeSql);
// 读操作,自动使用从库
$readSql = "SELECT * FROM user WHERE age > 20";
$pdo = $db->getPdoBySql($readSql);
$result = $pdo->query($readSql)->fetchAll();
print_r($result);

三、负载均衡优化设置

上述示例中使用随机算法分配从库请求,实际场景中可以根据需求调整负载均衡策略:

  • 轮询策略:按顺序依次分配请求到每个从库,保证请求均匀分布
  • 权重策略:根据从库的性能配置不同权重,性能高的从库分配更多请求
  • 故障转移:检测从库连接状态,自动剔除不可用的从库,避免请求失败

以下是权重轮询策略的实现示例:

<?php
class WeightedRoundRobin {
    private $servers = [];
    private $currentIndex = 0;
    private $totalWeight = 0;
    public function __construct($servers) {
        // $servers格式:[['host' => 'xxx', 'weight' => 2], ...]
        $this->servers = $servers;
        foreach ($servers as $server) {
            $this->totalWeight += $server['weight'];
        }
    }
    public function getServer() {
        $server = $this->servers[$this->currentIndex % count($this->servers)];
        $this->currentIndex++;
        return $server;
    }
}
// 配置带权重的从库
$slaves = [
    ['host' => '192.168.0.2', 'weight' => 2, 'port' => 3306, 'user' => 'root', 'pass' => 'slave_pass1'],
    ['host' => '192.168.0.3', 'weight' => 1, 'port' => 3306, 'user' => 'root', 'pass' => 'slave_pass2']
];
$robin = new WeightedRoundRobin($slaves);
// 获取从库时调用$robin->getServer()即可得到按权重分配的从库信息

四、注意事项

配置读写分离时需要注意以下问题:

  • 主从复制存在延迟,写操作后立刻读可能读不到最新数据,需要根据业务场景做延迟处理或使用主库读
  • 事务操作中的读写都需要使用主库连接,避免事务内数据不一致
  • 定期监控主从同步状态,及时处理同步异常问题
  • 从库数量需要根据实际读请求量调整,避免从库过载

PHP读写分离主从复制负载均衡修改时间:2026-07-07 19:12:45

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。