Django 读写分离实现深度教程

一、架构原理与方案选型

1. 读写分离核心价值

  • 提升读性能:水平扩展读能力
  • 保障写安全:主库专注事务处理
  • 灾备容错:从库故障不影响核心业务

2. 典型部署方案

异步复制
异步复制
应用服务器
Master DB
Replica1
Replica2

二、Django 多数据库配置

1. 基础配置(settings.py

DATABASES = {
    'default': {  # 默认数据库(主库)
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'master.db.example.com',
        'NAME': 'mydb',
        'USER': 'write_user',
        'PASSWORD': 'secure_pwd'
    },
    'replica1': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'replica1.db.example.com',
        'NAME': 'mydb',
        'USER': 'read_user',
        'PASSWORD': 'read_pwd'
    },
    'replica2': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'replica2.db.example.com',
        'NAME': 'mydb',
        'USER': 'read_user',
        'PASSWORD': 'read_pwd'
    }
}

2. 连接池优化(推荐)

# 使用 django-db-connections
DATABASES['default']['CONN_MAX_AGE'] = 300  # 5分钟连接复用
DATABASES['replica1']['CONN_MAX_AGE'] = 60

三、路由策略实现

1. 基础路由类(database_routers.py

import random

class PrimaryReplicaRouter:
    def db_for_read(self, model, **hints):
        """读操作路由到从库"""
        return random.choice(['replica1', 'replica2'])

    def db_for_write(self, model, **hints):
        """写操作强制使用主库"""
        return 'default'

    def allow_relation(self, obj1, obj2, **hints):
        """允许跨库关系"""
        return True

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """迁移仅限主库"""
        return db == 'default'

2. 注册路由策略(settings.py

DATABASE_ROUTERS = ['myproject.database_routers.PrimaryReplicaRouter']

四、高级路由场景

1. 强制主库读取(解决复制延迟)

from django.db import connections

def get_real_time_data():
    """关键数据强制主库读取"""
    with connections['default'].cursor() as cursor:
        cursor.execute("SELECT * FROM sensitive_table")
        return cursor.fetchall()

2. 写后同步读取保障

from django.db import transaction

@transaction.atomic
def create_order(data):
    order = Order.objects.create(**data)  # 写主库
    # 立即主库读取
    return Order.objects.using('default').get(pk=order.pk)

五、生产环境注意事项

1. 主从同步监控

# 主库检查
SHOW MASTER STATUS\G

# 从库检查
SHOW SLAVE STATUS\G

2. 故障转移策略

class SmartRouter(PrimaryReplicaRouter):
    def db_for_read(self, model, **hints):
        """健康检查后路由"""
        alive_replicas = check_replica_health()
        return random.choice(alive_replicas) if alive_replicas else 'default'

3. 性能监控指标

  • 主库写 QPS 监控
  • 从库复制延迟时间
  • 连接池使用率

六、完整实现示例

1. 项目结构

myproject/
├── core/
│   ├── database_routers.py  # 路由策略
│   └── health_check.py      # 健康检查
└── myproject/
    ├── settings.py          # 数据库配置
    └── urls.py

2. 健康检查实现

# health_check.py
import MySQLdb
from django.conf import settings

def check_replica_health():
    healthy = []
    for alias in ['replica1', 'replica2']:
        try:
            conn = MySQLdb.connect(**settings.DATABASES[alias])
            with conn.cursor() as cursor:
                cursor.execute("SELECT 1")
            healthy.append(alias)
        except Exception:
            pass
    return healthy

七、读写分离验证方法

1. 日志追踪

# settings.py 开启查询日志
LOGGING = {
    'version': 1,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'level': 'DEBUG',
            'handlers': ['console'],
        }
    }
}

2. 手动验证

# 写入验证
obj = MyModel.objects.create(name="test")  # 主库
print(obj.pk)

# 读取验证
MyModel.objects.get(pk=obj.pk)  # 随机从库

八、扩展方案推荐

1. 结合缓存层

from django.core.cache import cache

def get_with_cache(pk):
    data = cache.get(f'obj_{pk}')
    if not data:
        data = MyModel.objects.get(pk=pk)
        cache.set(f'obj_{pk}', data, 30)
    return data

2. 分库分表整合

class ShardingRouter:
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'user':
            return 'user_replica'
        return super().db_for_read(model, **hints)

通过以上实现方案,可构建出企业级读写分离架构。建议在实施后持续监控数据库性能指标,并建立自动化的故障转移机制。对于需要强一致性的业务场景,可采用同步复制或应用层双读验证策略。
高级用户可结合ProxySQL等中间件实现更智能的流量调度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yant224

点滴鼓励,汇成前行星光🌟

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值