Laravel 多数据库连接与读写分离:配置、事务与查询路由的工程化落地
test12026-10-031 次阅读
为什么需要多数据库与读写分离
当单体库撑不住读流量,或业务要跨多个数据源(比如主库加一个分析库)时,Laravel 的连接管理就该上场了。Laravel 原生支持多连接定义,并且能在一组主从配置上自动做读写分离,无需引入额外中间件。
配置读库与写库
在 config/database.php 的 mysql 连接里,把 host 换成 read 与 write 两个数组,Laravel 会自动把写操作路由到 write、读操作路由到 read。
// config/database.php
"mysql" => [
"driver" => "mysql",
"read" => [
"host" => ["10.0.0.2", "10.0.0.3"],
],
"write" => [
"host" => ["10.0.0.1"],
],
"sticky" => true,
"database" => "app",
"username" => env("DB_USERNAME"),
"password" => env("DB_PASSWORD"),
],
在模型与查询里指定连接
除了默认分离,也可以显式指定某个模型走专属连接,比如统计库。
class Report extends Model
{
protected $connection = "analytics";
}
// 单次查询临时切库
$users = DB::connection("analytics")->table("daily_active")->get();
事务里的陷阱
读写分离最容易踩的坑是:在写事务里刚插入一条数据,紧接着的读却落到还没有这条数据的从库,读到旧值。sticky 选项就是为解决这个问题——它保证“本次请求内、写操作之后的读都走主库”,直到请求结束。
// sticky=true 时,下面这段读会命中刚才写入的主库
DB::transaction(function () {
$id = DB::table("orders")->insertGetId([...]);
$row = DB::table("orders")->find($id); // 走主库,能读到
});
工程化注意点
- sticky 只在同一请求生命周期内有效,跨请求仍可能遇到主从延迟,对强一致要求的读要手动 DB::connection("mysql::write") 强制走主。
- 多连接会在每个连接上各自维护连接池,连接数预算要按连接数乘算,避免打满数据库 max_connections。
- 迁移命令要指定连接:php artisan migrate --database=analytics,否则默认只在主库跑。
- 读库列表支持多个 host,Laravel 会做随机选择,但本身不带健康检查,坏节点需要外部探活或代理层兜底。
读写分离是数据库扩展的第一步,把它配置对、事务边界想清楚,系统的读吞吐能轻松翻几倍而不必立即拆微服务。
T
test1
文章作者
为什么需要多数据库与读写分离 当单体库撑不住读流量,或业务要跨多个数据源(比如主库加一个分析库)时,Laravel 的...
- 分类
- 技术
- 发布时间
- 2026-10-03
- 字数
- 约 1372 字
- 阅读
- 1 次
