ThinkPHP6数据库读写分离配置与部署教程

作者:技术拾光时间:2026-05-10 11:16:32浏览:151

ThinkPHP6中配置数据库读写分离需同时满足三个条件:启用部署模式总开关(deploy=1)、开启读写分离开关(rw_separate=true),并正确定义名为“master”和“slave”的数据库连接。连接命名必须严格使用框架规定的键名,否则所有查询仍会指向主库。配置后若未生效,需依次检查开关状态、连接命名、从库连通性及是否手动指定了连接。该功能仅

在ThinkPHP6项目中,配置数据库读写分离是提升应用性能的常见做法。然而,许多开发者在实践中会遇到问题:即使按照文档设置了 deploy 和 rw_separate 参数,查询请求仍然全部指向主库。问题的根源在于,这两个配置项并非独立的开关,而是一套需要协同工作的组合指令。

deploy=1是启用分布式部署模式的总开关,rw_separate=true才是开启读写分离的具体开关。两者必须同时正确配置,并且正确定义名为master和sla ve的数据库连接,否则所有操作仍将使用主库。

ThinkPHP6数据库读写分离配置与部署教程

简而言之,在ThinkPHP6中成功启用读写分离功能,必须同时满足三个条件:开启总开关、开启分离开关、并严格遵循框架规定的命名方式定义数据库连接。三者缺一不可。

理解 deploy 与 rw_separate 的分工

这两个配置项共同决定了框架处理数据库连接的方式,它们的关系可以这样理解:

  • deploy => 0:这是默认的“单机模式”。所有数据库操作,无论读写,都通过同一个连接完成。
  • deploy => 1:这开启了“分布式部署模式”。框架会开始识别主从结构,但具体是否进行读写分离,取决于下一个参数。
  • rw_separate => false:即使开启了分布式模式(deploy=1),如果此开关关闭,所有数据库流量依然会指向主库。这种配置常用于初期只有主库,但为未来架构扩展预留接口的场景。
  • rw_separate => true:这才是真正的“读写分离”开关。开启后,框架会尝试将SELECT查询路由到从库,而写入操作(INSERT/UPDATE/DELETE)则固定使用主库。但这里有一个关键前提:你必须明确定义好名为 master 和 sla ve 的连接配置。

连接命名是硬性规定,不能自定义

这是配置中最容易出错的地方。ThinkPHP6内部是通过固定的键名 master 和 sla ve 来识别主从连接的,而不是读取开发者自定义的连接名称。下面这种看似合理的配置其实是无效的:

return [
    'connections' => [
        'my_master' => [/* ... */], // 错误!框架不认识这个键
        'my_sla ve'  => [/* ... */], // 错误!
    ],
];

正确的配置模板如下所示:

return [
    'connections' => [
        // 主库连接键名必须叫 'master'
        'master' => [
            'type'     => 'mysql',
            'hostname' => '192.168.1.10',
            'database' => 'app_db',
            'username' => 'root',
            'password' => 'xxx',
        ],
        // 从库连接键名必须叫 'sla ve'
        'sla ve' => [
            'type'     => 'mysql',
            'hostname' => '192.168.1.11',
            'database' => 'app_db',
            'username' => 'ro_user',
            'password' => 'ro_pass',
        ],
    ],
    'deploy'      => 1,         // 总开关打开
    'rw_separate' => true,     // 分离开关打开
];

此外,sla ve 支持配置为数组,用于定义多个从库。框架会自动进行随机选择,实现简单的负载均衡。例如:'sla ve' => [['hostname'=>'s1'], ['hostname'=>'s2']]。

高级参数:master_num 与 sla ve_no 的作用

当配置涉及多个从库时,以下两个参数才会发挥作用:

  • master_num:目前ThinkPHP6仅支持单一主库,因此此值固定设为 1 即可,设置为其他数字没有实际意义。
  • sla ve_no:此参数控制从库的选择策略。
    • 保持默认值(空字符串):框架会随机从 sla ve 数组中选取一个从库连接。
    • 设置为 0:强制固定使用配置数组中第一个从库(索引0)。
    • 设置为 1:强制固定使用第二个从库(索引1)。如果索引值超出范围,框架会回退到随机策略。

通常,在生产环境中,不建议硬编码 sla ve_no。保持其为空,利用随机负载是更合理的做法。此参数更多用于特定的调试场景或灰度发布测试。

配置后不生效?逐一排查这些原因

如果所有配置都已就绪,但SQL日志显示查询仍然运行在主库上,请按顺序检查以下几点:

  • 遗漏总开关:只设置了 rw_separate => true,却漏掉了 deploy => 1。这是最高频的错误。
  • 连接名错误:在 connections 配置中,主库的连接键名必须是 master,从库必须是 sla ve。写成 write/read 或其他自定义名称是无效的。
  • 从库连接不通:sla ve 配置的数据库地址、端口、用户名或密码有误,导致连接失败。为了稳定性,框架此时会静默降级到使用 master 连接,而不会直接抛出异常。
  • 手动指定连接覆盖了自动逻辑:在代码中使用了类似 Db::connect('sla ve')->... 或在模型内指定连接的方式,这会绕过框架的自动路由机制。

最直接的验证方法是开启SQL日志(配置 trigger_sql => true),然后执行一个简单的SELECT查询,观察日志中输出的连接主机名(hostname)是否是你配置的从库IP地址。

最后,需要明确一点:ThinkPHP6的部署模式只是一个应用层的SQL路由开关。它负责根据配置和SQL类型,将请求分发到不同的数据库连接。至于数据库集群本身的高可用、主从同步延迟、从库健康检测、故障自动切换(Failover)等复杂问题,框架并不负责处理。这些需要依靠数据库中间件(如ProxySQL)、云服务商的高可用方案或完善的运维监控体系来保障。正确配置只是实现读写分离的第一步。