全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-21 8 分钟 ✍️ juanwangdev

GORM 读写分离实现

读写分离是数据库扩展的常见方案,本文介绍 GORM 中配置主从分离与自动路由的核心方法。

什么是读写分离

读写分离指将写入操作路由到主库,读取操作路由到从库,实现负载分散与性能提升。

基础配置

使用 dbresolver 插件配置读写分离。

Go
import (
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "gorm.io/plugin/dbresolver"
)

db, err := gorm.Open(mysql.Open("master_dsn"), &gorm.Config{})

db.Use(dbresolver.Register(dbresolver.Config{
    // 主库:写入
    Sources:  []gorm.Dialector{mysql.Open("master_dsn")},
    // 从库:读取
    Replicas: []gorm.Dialector{
        mysql.Open("replica1_dsn"),
        mysql.Open("replica2_dsn"),
    },
    // 负载均衡策略:随机
    Policy: dbresolver.RandomPolicy{},
}))

自动路由规则

GORM 根据操作类型自动路由:

操作类型路由目标示例
写入主库Create, Update, Delete
读取从库Find, First, Select
事务主库Begin().Create().Commit()
Go
// 自动路由到从库
var users []User
db.Find(&users)

// 自动路由到主库
db.Create(&User{Name: "test"})

// 事务固定使用主库
tx := db.Begin()
tx.Create(&order)
tx.Model(&user).Update("balance", -100)
tx.Commit()

指定数据源

可强制指定使用主库或从库。

Go
// 强制从主库读取(强一致性场景)
db.Clauses(dbresolver.Write).Find(&users)

// 强制从从库读取
db.Clauses(dbresolver.Read).First(&user)

多数据库组

不同模型可绑定不同数据库组。

Go
db.Use(dbresolver.Register(dbresolver.Config{
    Sources:  []gorm.Dialector{mysql.Open("orders_master")},
    Replicas: []gorm.Dialector{mysql.Open("orders_replica")},
}).For("Order", "Payment"))

db.Use(dbresolver.Register(dbresolver.Config{
    Sources:  []gorm.Dialector{mysql.Open("users_master")},
    Replicas: []gorm.Dialector{mysql.Open("users_replica")},
}).For("User", "Profile"))
  • **主从延迟:**从库可能存在复制延迟,强一致性查询应使用主库。
  • **事务固定主库:**事务内所有操作路由到主库,避免主从不一致。
  • **健康检查:**定期检测从库状态,自动剔除不可用节点。
  • **负载均衡:**默认轮询策略,可自定义路由逻辑。

要点总结

  • 使用 dbresolver 插件配置读写分离,简洁高效。
  • GORM 自动路由:写入走主库,读取走从库。
  • 强一致性场景强制使用主库: db.Clauses(dbresolver.Write)
  • 不同模型可绑定不同数据库组,实现细粒度控制。

存放路径: D:\git2\jwdev\articles\GORM\专家\性能优化与调优\读写分离实现.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 GORM 查询计划分析与优化
下一篇 → 乐观锁实现
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库