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 次