跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

如何在ThinkPHP中配置数据库主从分离_分布式数据库连接方案

ThinkPHP 6 主从配置需满足:default 必须存在且 type=‘mysql’,slave 为含完整数据库参数的数组;读写分离默认生效,SELECT 轮询从库,INSERT/UPDATE/DELETE 走主库;强一致性读需显式调用 ->master(true)。 ThinkPHP 6 的
database.php
怎么配主从? 主从配置不是加个“slave”键就完事,TP6 要求显式声明
type
为
mysql
,且主库必须叫
default
,从库必须放在
slave
数组里——漏掉任一条件都会降级成单库连接。 常见错误现象:
Db::table('user')->select()
始终走主库,
slave
配置完全不生效。
default
必须存在,且不能是空数组;它只负责写操作和未指定读写意图的查询
slave
是数组,每个元素是一个完整数据库配置(含
hostname
、
username
等),不是只填 IP 所有从库配置里不要设
deploy
或
rw_separate
,TP6 已废弃这些旧键 如果用了 PDO 连接池或长连接,记得在从库配置中加
'params' => [PDO::ATTR_PERSISTENT => true]
,否则每次查从库都重建连接 示例关键片段:
'default' => [ 'type' => 'mysql', 'hostname' => 'master.example.com', 'database' => 'app_db', 'username' => 'root', 'password' => 'xxx', ], 'slave' => [ [ 'type' => 'mysql', 'hostname' => 'slave1.example.com', 'database' => 'app_db', 'username' => 'ro_user', 'password' => 'yyy', ], [ 'type' => 'mysql', 'hostname' => 'slave2.example.com', 'database' => 'app_db', 'username' => 'ro_user', 'password' => 'zzz', ], ],
读写分离怎么触发?
Db::connect()
和
->master()
有什么区别? TP6 默认只在
INSERT
/
UPDATE
/
DELETE
时自动走主库,
SELECT
默认轮询从库——但前提是没手动干预连接对象。一旦你调用
Db::connect('slave')
,就等于绕过内置路由,后续所有操作都固定走那个从库,不再负载均衡。 立即学习 “ PHP免费学习笔记(深入) ”; 容易踩的坑:在事务中混用读写,比如先
Db::transaction(function () { ... Db::table('log')->select(); ... });
,此时
select()
仍可能被发到从库,导致事务一致性断裂(MySQL 从库默认不支持事务内读写混合)。 强制走主库查数据:用
Db::name('user')->master(true)->select()
强制走某从库:不推荐,但可
Db::connect(['hostname' => 'slave1.example.com', ...])->table('user')->select()
想让某个
SELECT
也走主库(比如刚写完立刻读),必须显式加
->master(true)
,别指望“刚写完会自动同步” 关联查询(
with()
)默认主库 + 从库混合走,但如果关联表跨库或主从延迟高,结果可能不一致 从库延迟导致数据查不到,怎么兜底? TP6 没内置延迟检测或自动切回主库机制。所谓“强一致性读”,得自己控制:对时效性敏感的读操作(如用户刚提交订单后查订单状态),一律加
->master(true)
。 更现实的做法是分层处理:普通列表页走从库,详情页 ID 查询加缓存+主库兜底。别幻想靠配置项解决延迟问题。 不要依赖
slave_balance
(TP6 不支持该配置),轮询策略是硬编码在
think\db\connector\Mysql
里的,无法插件化替换 监控从库延迟:需单独执行
SHOW SLAVE STATUS
,TP6 不提供钩子自动采集 如果业务允许几秒延迟,可在从库查询前加
sleep(0.1)
等待同步(仅测试环境,生产禁用) 真正可靠的方案是应用层加缓存,比如用 Redis 存刚写入的记录,查缓存命中则不查 DB 多从库下连接数爆了怎么办? TP6 每个从库配置会独立维护连接池,默认最大连接数由
params' => [PDO::MYSQL_ATTR_MAX_BUFFER_SIZE]
之类控制不了,实际取决于 PHP-FPM 的
pm.max_children
和 MySQL 侧的
max_connections
。 现象:上线后 MySQL 报
Too many connections
,但
show processlist
显示大量 Sleep 状态连接来自不同从库地址。 给每个从库配置加
'break_reconnect' => true
,断连时主动释放资源,而不是等超时 限制从库数量,TP6 对超过 3 个从库的轮询性能无优化,反而增加连接管理开销 确认是否误开了
'debug' => true
,开启调试后每条 SQL 都会额外建连接做日志记录 用
Db::close()
主动关闭不用的从库连接,尤其在长生命周期的 CLI 命令中 主从分离不是银弹,配置只是第一步。真正卡住人的,永远是主从延迟、连接泄漏、事务边界和缓存一致性——这些没法靠改几个数组键解决。

相关文章