Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > mysql读写分离

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

作者:Smile sea breeze

文章介绍了MySQL读写分离的架构、实现步骤、可能遇到的问题及解决方案,并总结了优化点,以提高MySQL数据库的性能和可扩展性,感兴趣的朋友一起看看吧

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

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

一、读写分离的基本架构

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

二、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. 配置读写分离

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

(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

应用程序连接:

(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 读查询性能,减少主库压力,提高整体数据库系统的可扩展性。

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

您可能感兴趣的文章:
阅读全文