You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python-SQLAlchemy主从数据库复制读写分离最佳实践咨询

SQLAlchemy 读写分离(主从复制)最佳实践

核心思路

SQLAlchemy 通过绑定多数据库引擎 + 自定义会话路由逻辑,实现主库处理写操作(INSERT/UPDATE/DELETE)、从库处理读操作(SELECT)的分离,本质是让会话根据当前操作类型自动选择对应的数据库连接。


具体实现步骤

1. 配置主从库引擎

分别创建主库(写)和从库(读)的数据库引擎,从库可配置多个实现负载均衡:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import random

# 主库连接配置
master_engine = create_engine(
    "mysql+pymysql://username:password@master-host:3306/your_db",
    pool_size=10,
    max_overflow=20
)

# 多从库连接配置
slave_engines = [
    create_engine(
        "mysql+pymysql://username:password@slave1-host:3306/your_db",
        pool_size=10,
        max_overflow=20
    ),
    create_engine(
        "mysql+pymysql://username:password@slave2-host:3306/your_db",
        pool_size=10,
        max_overflow=20
    )
]

2. 自定义路由会话类

继承 SQLAlchemy 的 Session 类,重写 get_bind 方法实现操作路由:

class RoutingSession(Session):
    def get_bind(self, mapper=None, clause=None):
        # 写操作(触发flush时)走主库
        if self._flushing:
            return master_engine
        
        # 读操作随机选择从库(可替换为轮询等负载均衡策略)
        return random.choice(slave_engines)

# 创建会话工厂
SessionFactory = sessionmaker(class_=RoutingSession)

3. 业务代码中使用

通过会话工厂创建会话,读写操作自动路由:

# 获取会话
session = SessionFactory()

# 写操作:自动走主库
new_user = User(name="Bob", email="bob@example.com")
session.add(new_user)
session.commit()

# 读操作:自动随机走从库
users = session.query(User).filter(User.name.like("%ob%")).all()

# 手动指定主库读(适用于读取刚写入数据的场景)
users_from_master = session.query(User).with_session(session.bind(master_engine)).all()

进阶优化点

  • 事务内强制主库读:事务中需要保证数据一致性时,强制所有操作走主库:
    class RoutingSession(Session):
        def get_bind(self, mapper=None, clause=None):
            # 事务中强制走主库
            if self.is_active:
                return master_engine
            if self._flushing:
                return master_engine
            return random.choice(slave_engines)
    
  • 从库轮询负载均衡:替换随机选择,用计数器实现轮询:
    slave_index = 0
    def get_slave_engine():
        global slave_index
        engine = slave_engines[slave_index]
        slave_index = (slave_index + 1) % len(slave_engines)
        return engine
    
    # 在RoutingSession的get_bind中调用get_slave_engine()
    
  • 连接池优化:根据业务量调整每个引擎的pool_size、max_overflow参数,避免连接耗尽。

注意事项

  • 主从同步延迟:对数据一致性要求极高的场景,刚写入后需手动指定主库读取。
  • 只读会话:纯读业务可创建只读会话,强制所有操作走从库,降低主库压力。
  • 故障转移:路由逻辑中可增加从库可用性检测,跳过不可用节点。

内容的提问来源于stack exchange,提问作者subhadip pahari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:30:49