MySQL 读写分离的实现逻辑及步骤详解

 更新时间:2025年02月19日 14:27:32   作者:Smile sea breeze  
文章介绍了MySQL读写分离的架构、实现步骤、可能遇到的问题及解决方案,并总结了优化点,以提高MySQL数据库的性能和可扩展性,感兴趣的朋友一起看看吧

读写分离 是数据库架构优化的一种常见策略,主要用于提高数据库的吞吐能力和查询性能。

MySQL 读写分离的核心思想是:

  • 写操作(INSERT、UPDATE、DELETE)只在 主库(Master) 上执行。
  • 读操作(SELECT)在 从库(Slave) 上执行。
  • 通过 主从复制(Master-Slave Replication)保持数据一致性。

一、读写分离的基本架构

通常采用 一主多从(Master-Slave)的架构,即:

  • Master(主库) 负责处理所有写请求,并将数据变更同步到从库。
  • Slave(从库) 负责处理读请求,提高查询性能。
  • 中间件或代理(如 MySQL Proxy、MyCat、ShardingSphere-Proxy)用于路由 SQL 请求。

二、MySQL 读写分离的实现步骤

1. 配置 MySQL 主从复制

(1)在主库(Master)上配置

① 修改 MySQL 配置文件 (my.cnf 或 my.ini):

[mysqld]
server-id=1  # 设置唯一的服务器ID
log-bin=mysql-bin  # 启用二进制日志(binlog),用于数据同步
binlog-format=ROW  # 推荐使用行格式(ROW)以保证数据一致性

② 创建用于复制的账号:

CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

③ 查看 Master 的二进制日志信息:

SHOW MASTER STATUS;

输出示例:

±-----------------±---------±-------------±-----------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
±-----------------±---------±-------------±-----------------+
| mysql-bin.000001 | 157 | testdb | |
±-----------------±---------±-------------±-----------------+

记住 File 和 Position,稍后在从库中使用。

(2)在从库(Slave)上配置

① 修改 MySQL 配置文件 (my.cnf 或 my.ini):

server-id=2  # 每个从库都需要唯一的 server-id
relay-log=relay-bin  # 设定 relay log 用于主从同步
read-only=1  # 设定为只读,防止误写

② 配置从库连接主库:

CHANGE MASTER TO
    MASTER_HOST='主库IP',
    MASTER_USER='repl',
    MASTER_PASSWORD='password',
    MASTER_LOG_FILE='mysql-bin.000001',  -- Master 服务器上 SHOW MASTER STATUS 查询得到的 File
    MASTER_LOG_POS=157;  -- Master 服务器上 SHOW MASTER STATUS 查询得到的 Position

③ 启动复制进程:

START SLAVE;

④ 检查主从同步状态:

SHOW SLAVE STATUS\G;

如果 Slave_IO_Running 和 Slave_SQL_Running 都是 Yes,表示复制正常。

2. 配置读写分离

主从复制完成后,需要将 写请求发往主库,读请求发往从库。实现方式有:

  • 应用层代码控制(手动选择数据库连接)
  • MySQL 代理中间件(MySQL Router、MyCat、ShardingSphere-Proxy)
  • 数据库连接池方案(如 C3P0、HikariCP)

(1)应用层代码控制

在 Java 代码中,可以使用不同的数据源进行读写分离:

// 写操作 - 连接 Master
try (Connection conn = masterDataSource.getConnection()) {
    String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
    try (PreparedStatement stmt = conn.prepareStatement(sql)) {
        stmt.setString(1, "Amy");
        stmt.setString(2, "amy@example.com");
        stmt.executeUpdate();
    }
}
// 读操作 - 连接 Slave
try (Connection conn = slaveDataSource.getConnection()) {
    String sql = "SELECT * FROM users";
    try (Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery(sql)) {
        while (rs.next()) {
            System.out.println("User: " + rs.getString("name"));
        }
    }
}

(2)使用 MySQL Router

MySQL Router 是官方的读写分离代理工具:

安装 MySQL Router:

sudo apt install mysql-router

配置路由规则(mysqlrouter.conf):

[routing:read_write]
bind_address = 0.0.0.0
bind_port = 3306
routing_strategy = first-available
destinations = master_ip:3306
[routing:read_only]
bind_address = 0.0.0.0
bind_port = 3307
routing_strategy = round-robin
destinations = slave1_ip:3306,slave2_ip:3306

应用程序连接:

  • 写请求 连接 127.0.0.1:3306
  • 读请求 连接 127.0.0.1:3307

(3)使用 ShardingSphere-JDBC

Spring Boot 可使用 ShardingSphere-JDBC 进行自动读写分离:

spring:
  shardingsphere:
    datasource:
      names: master, slave
      master:
        url: jdbc:mysql://master_ip:3306/testdb
        username: root
        password: password
      slave:
        url: jdbc:mysql://slave_ip:3306/testdb
        username: root
        password: password
    rules:
      readwrite-splitting:
        data-sources:
          readwrite_ds:
            type: Static
            props:
              write-data-source-name: master
              read-data-source-names: slave

三、可能遇到的问题及解决方案

四、总结

主从复制通过 binlog 机制同步数据,为读写分离提供基础。

读写分离策略:

  • 代码层手动控制
  • 代理中间件(MySQL Router、MyCat)
  • 数据库连接池(ShardingSphere-JDBC)

优化点:

  • 通过 负载均衡 分配从库查询压力
  • 避免 复制延迟 影响查询结果
  • 采用 事务管理策略,确保数据一致性

这样可以大幅提高 MySQL 读查询性能,减少主库压力,提高整体数据库系统的可扩展性。

到此这篇关于MySQL 读写分离的实现逻辑的文章就介绍到这了,更多相关MySQL 读写分离内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Mysql的MHA高可用及故障切换问题小结

    Mysql的MHA高可用及故障切换问题小结

    MHA是基于MySQL主从复制的高可用解决方案,通过自动切换到从节点并提升其为新主,实现数据库的高可用和故障恢复,配置包括主从复制、MHA组件、VIP管理等,通过配置无密码认证和测试连接,可以确保MHA正常运行,感兴趣的朋友一起看看吧
    2024-12-12
  • MySQL ERROR 1045 (28000): Access denied for user ''root''@''localhost'' (using password: NO) 的原因分解决办法

    MySQL ERROR 1045 (28000): Access denied for user ''root''@''

    这篇文章主要介绍了MySQL ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) 的原因分解决办法的相关资料,需要的朋友可以参考下
    2016-05-05
  • Mysql InnoDB引擎中的数据页结构详解

    Mysql InnoDB引擎中的数据页结构详解

    这篇文章主要为大家介绍了Mysql InnoDB引擎中的数据页结构详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • xampp中修改mysql默认空密码(root密码)的方法分享

    xampp中修改mysql默认空密码(root密码)的方法分享

    以前开发我一直都是用的phpnow做php开发环境,phpnow的特点就是一键安装,安装的时候会要求用户输入mysql的root密码。今天由于客户机器使用的xampp作为开发环境,所以碰到了修改mysql默认空密码的问题
    2014-04-04
  • 简单了解mysql InnoDB MyISAM相关区别

    简单了解mysql InnoDB MyISAM相关区别

    这篇文章主要介绍了简单了解mysql InnoDB MyISAM相关区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Mysql误操作后利用binlog2sql快速回滚的方法详解

    Mysql误操作后利用binlog2sql快速回滚的方法详解

    相信每个和数据库打交道的程序员都会碰一个问题,MySQL误操作后如何快速回滚?那么下面这篇文章主要给大家介绍了关于Mysql误操作后利用binlog2sql快速回滚的相关资料,文中介绍的非常详细,需要的朋友可以参考下。
    2017-07-07
  • Mysql如何避免全表扫描的方法

    Mysql如何避免全表扫描的方法

    如果MySQL需要做一次全表扫描来处理查询时,在 EXPLAIN 的结果中 type 字段的值是 ALL。
    2008-10-10
  • prometheus监控MySQL并实现可视化的操作详解

    prometheus监控MySQL并实现可视化的操作详解

    mysqld_exporter 是一个用于监控 MySQL 服务器的开源工具,它是由 Prometheus 社区维护的一个官方 Exporter,本文给大家介绍了prometheus监控MySQL并实现可视化的操作,文中通过代码和图文讲解的非常详细,需要的朋友可以参考下
    2024-04-04
  • MySQL延迟问题和数据刷盘策略流程分析

    MySQL延迟问题和数据刷盘策略流程分析

    这篇文章主要介绍了MySQL延迟问题和数据刷盘策略流程分析,本文要给大家提到了mysql复制流程,需要的朋友可以参考下
    2020-02-02
  • MySQL高级开发中视图的详细教程

    MySQL高级开发中视图的详细教程

    对MySQL数据库的查询,除了基本的查询外,有时候需要对查询的结果集进行处理,下面这篇文章主要给大家介绍了关于MySQL数据库基本SQL语句教程之高级操作中视图的相关资料,需要的朋友可以参考下
    2023-01-01

最新评论