Laravel 8中如何配置使用master/slave主从读写分离节点
Laravel 8 一主两从读写分离配置实操
一、读节点(2个从库)配置与选择策略
Laravel 框架原生自带多从库读写分离支持,不需要额外引入第三方包,也不需要手写连接切换逻辑。
基础配置方法
直接修改项目下config/database.php中的mysql连接配置,拆分读、写节点的host配置即可:
'mysql' => [ 'driver' => 'mysql', // 写节点(主库)单独配置 'write' => [ 'host' => [ env('DB_WRITE_HOST', '主库内网IP'), ], ], // 2个读节点(从库)配置 'read' => [ 'host' => [ env('DB_READ1_HOST', '从库1内网IP'), env('DB_READ2_HOST', '从库2内网IP'), ], ], // 同请求写后读自动走主库,强烈建议开启 'sticky' => true, // 以下公共配置主从保持一致即可直接写在外层,单节点有特殊配置可以单独在对应节点数组内覆盖 'database' => env('DB_DATABASE', '你的库名'), 'username' => env('DB_USERNAME', '数据库账号'), 'password' => env('DB_PASSWORD', '数据库密码'), 'port' => env('DB_PORT', '3306'), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], ],
对应的.env文件里新增三个host配置项即可:
DB_WRITE_HOST=192.168.1.100 DB_READ1_HOST=192.168.1.101 DB_READ2_HOST=192.168.1.102
读节点选择策略说明
- 框架默认对
read数组下的多个host,会在每次请求初始化数据库连接时随机选择一个作为当前请求的读连接,两个节点的流量分布基本是1:1,只要两个从库硬件配置一致,负载差会维持在很小的范围,90%以上的项目直接用这个默认策略就够,不需要额外开发。 - 不建议初期就做节点空闲状态检测、实时负载优先的调度逻辑:这类逻辑需要配套数据库监控探针、节点熔断降级机制,开发维护成本极高,没有大流量场景完全是过度设计。如果后续出现单节点负载过高的问题,优先排查慢SQL、索引缺失问题,实在需要调整流量分配,可以扩展框架的数据库连接器实现加权轮询,比实时拉取节点负载指标稳定得多。
二、主写节点配置与实际使用方式
配置方法
主节点的配置就是上面代码块里的write配置块,单写节点场景下host数组里只填主库地址即可,框架会自动把所有写操作路由到该节点。
使用方式
不需要手动切换数据库连接,框架底层会自动根据SQL类型路由到对应节点:
- 所有普通
SELECT查询,默认走当前请求随机选中的从库 - 所有
INSERT/UPDATE/DELETE/DDL语句,以及开启事务后的所有操作(不管是读还是写),都会自动走主库,直到事务提交
常见踩坑注意
- 配置完一定要做连通性验证:可以写临时测试路由,多次执行
DB::select('SELECT @@hostname as host'),刷新页面看返回的hostname是否在两个从库之间切换;执行一条insert语句后立刻执行相同查询,看是否返回主库hostname,验证sticky配置生效。 - 遇到必须读实时数据的场景(比如支付后立刻查询订单状态),可以在查询后链式调用
->useWritePdo()强制当前查询走主库,不要自己手动切换连接。 - 跨请求场景下的主从同步延迟没有银弹,不要全量把读请求切到主库,对实时性要求极高的接口单独强制走主库即可,普通业务场景接受几十到几百毫秒的延迟是性价比最高的方案。
内容的提问来源于stack exchange,提问作者Mikaele
相关产品推荐
相关产品推荐

