Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • Python
  • Shell
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • Python
  • Shell
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL8-SOP

  • MySQL实战45讲学习笔记

    • MySQL45讲学习笔记
    • MySQL基础架构
    • MySQL日志系统 (Redo Log 与 Binlog)
    • MySQL字符串字段索引优化
    • MySQL索引原理与优化
    • MySQL锁机制详解
    • MySQL事务与MVCC机制
    • MySQL普通索引与唯一索引的选择
    • MySQL优化器如何选择索引
    • MySQL抖动刷脏页
    • 表空间管理与回收
    • count函数详解
    • 日志索引
    • orderby工作原理
    • 随机排序实现
    • SQL性能差异函数与转换
    • 慢查询分析锁与版本
    • 幻读与间隙锁
    • 加锁规则分析
    • 应急性能优化方法
    • 数据持久化保证
    • 主备一致性原理
    • 高可用架构与切换
    • 备库延迟分析与优化
    • 主备切换GTID
    • 读写分离实践与问题
      • 1. 读写分离概述
      • 2. 读写分离的优势
        • 2.1 提高并发性能
        • 2.2 负载均衡
        • 2.3 提高可用性
      • 3. 实现方式
        • 3.1 应用层实现
        • 3.2 中间件实现
        • 3.3 数据库层面实现
      • 4. 常见问题及解决方案
        • 4.1 数据同步延迟
        • 4.2 事务一致性问题
        • 4.3 查询路由策略
      • 5. 实践最佳实践
        • 5.1 配置管理
        • 5.2 监控与告警
        • 5.3 故障切换
      • 6. 性能优化建议
        • 6.1 从库优化
        • 6.2 查询优化
        • 6.3 连接池管理
      • 7. 常见陷阱
        • 7.1 事务中的读写混合
        • 7.2 频繁切换
      • 8. 总结
    • 数据库健康检查
    • 锁与死锁
    • 数据误删恢复
    • Kill命令详解
    • 查询与内存使用分析
    • Join原理与选择
    • 临时表原理与应用
    • 内部临时表详解
    • Memory引擎详解
    • 自增ID详解
    • Insert加锁分析
    • 表复制方法比较
    • Grant与权限管理
    • 分区表详解
    • SQL语句中的Join问题
    • 自增ID用尽问题
  • 专题系列
  • MySQL实战45讲学习笔记
Carry の Blog
2026-03-04
目录

读写分离实践与问题

# 读写分离实践与问题

# 1. 读写分离概述

读写分离是一种数据库架构模式,将数据库的读操作和写操作分别路由到不同的数据库实例上。通常将写操作路由到主库(Master),读操作路由到从库(Slave)。

# 2. 读写分离的优势

# 2.1 提高并发性能

  • 主库专注处理写操作,减少锁竞争
  • 从库处理读操作,提高整体吞吐量
  • 读写操作并行执行,提升系统响应速度

# 2.2 负载均衡

  • 分散数据库负载
  • 避免单点压力过大
  • 提高系统的可扩展性

# 2.3 提高可用性

  • 当主库出现故障时,可以快速切换到从库
  • 从库可以独立进行备份和维护
  • 降低单点故障风险

# 3. 实现方式

# 3.1 应用层实现

// Java伪代码示例
public class DBRouter {
    private static final ThreadLocal<String> dbType = new ThreadLocal<>();
    
    public static void setDbType(String type) {
        dbType.set(type);
    }
    
    public static String getDbType() {
        return dbType.get();
    }
}

// 写操作路由到主库
DBRouter.setDbType("master");
// 读操作路由到从库
DBRouter.setDbType("slave");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 3.2 中间件实现

  • 使用MyCat
  • 使用ShardingSphere
  • 使用Atlas
  • 使用ProxySQL

# 3.3 数据库层面实现

  • MySQL主从复制
  • Percona XtraDB Cluster
  • MariaDB Galera Cluster

# 4. 常见问题及解决方案

# 4.1 数据同步延迟

问题描述:从库数据落后于主库,导致读到旧数据。

解决方案:

-- 检查主从同步状态
SHOW SLAVE STATUS\G

-- 优化主从同步
-- 1. 调整binlog同步参数
SET GLOBAL sync_binlog = 1;
SET GLOBAL innodb_flush_log_at_trx_commit = 1;

-- 2. 优化网络和硬件配置
-- 3. 定期监控同步延迟
1
2
3
4
5
6
7
8
9
10

# 4.2 事务一致性问题

问题描述:在同一个事务中先写后读,可能读到旧数据。

解决方案:

// 方案1:强制走主库
@Transactional
public void updateAndQuery() {
    // 写操作强制走主库
    masterDAO.update(data);
    // 读操作也强制走主库
    slaveDAO.query(data);
}

// 方案2:使用事务隔离级别
// 设置为SERIALIZABLE级别确保一致性
1
2
3
4
5
6
7
8
9
10
11

# 4.3 查询路由策略

问题描述:如何决定哪些查询走主库,哪些走从库。

解决方案:

-- 根据SQL类型判断
-- 写操作:INSERT/UPDATE/DELETE
-- 读操作:SELECT

-- 也可以根据业务逻辑
-- 重要数据读操作走主库
-- 一般数据读操作走从库
1
2
3
4
5
6
7

# 5. 实践最佳实践

# 5.1 配置管理

# 数据库配置示例
database:
  master:
    url: jdbc:mysql://master-host:3306/db
    username: user
    password: password
  slave:
    - url: jdbc:mysql://slave1-host:3306/db
      username: user
      password: password
    - url: jdbc:mysql://slave2-host:3306/db
      username: user
      password: password
1
2
3
4
5
6
7
8
9
10
11
12
13

# 5.2 监控与告警

-- 监控主从延迟
SELECT 
    Slave_IO_Running,
    Slave_SQL_Running,
    Seconds_Behind_Master,
    Last_Error
FROM information_schema.slave_status;
1
2
3
4
5
6
7

# 5.3 故障切换

# 自动检测主库状态
#!/bin/bash
if ! mysql -h master_host -u user -p -e "SELECT 1;" >/dev/null 2>&1; then
    echo "主库不可用,切换到从库"
    # 执行切换逻辑
fi
1
2
3
4
5
6

# 6. 性能优化建议

# 6.1 从库优化

-- 从库配置优化
SET GLOBAL read_only = ON;
SET GLOBAL super_read_only = ON;
SET GLOBAL innodb_flush_log_at_trx_commit = 2;
1
2
3
4

# 6.2 查询优化

-- 避免在从库上执行复杂查询
-- 适当使用索引
-- 减少JOIN操作
-- 控制返回数据量
1
2
3
4

# 6.3 连接池管理

// 连接池配置示例
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(20);
config.setMinimumIdle(5);
config.setConnectionTimeout(30000);
1
2
3
4
5

# 7. 常见陷阱

# 7.1 事务中的读写混合

-- 错误示例:在一个事务中混用主从库
BEGIN;
UPDATE users SET balance = balance - 100 WHERE id = 1;  -- 主库
SELECT balance FROM users WHERE id = 1;                 -- 从库(可能读到旧数据)
COMMIT;
1
2
3
4
5

# 7.2 频繁切换

-- 避免频繁切换主从库
-- 应该在事务开始时确定路由策略
-- 不要在事务中动态切换
1
2
3

# 8. 总结

读写分离是提高数据库性能的有效手段,但在实施时需要注意:

  1. 数据一致性问题
  2. 同步延迟问题
  3. 事务处理问题
  4. 故障切换机制
  5. 监控告警机制

合理设计和实现读写分离架构,能够显著提升系统的整体性能和可用性。

上次更新: 3/4/2026

← 主备切换GTID 数据库健康检查→

最近更新
01
表空间管理与回收
03-04
02
MySQL抖动刷脏页
03-04
03
count函数详解
03-04
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式