mysql读写分离的最佳实践

一. 传统的读写分离方式

在 MySQL 中实现读写分离可以通过以下几种方式来达到目的:

1. 主从复制

使用主从复制(Master-Slave Replication)是实现读写分离的常见方式。

  • 主库:处理所有的写入操作(INSERT、UPDATE、DELETE)。
  • 从库:负责处理读操作(SELECT)。

步骤

  1. 设置主从复制
    • 在主库上配置 binlog,并创建复制用户。
    • 在从库上配置 server-id,并指向主库的 binlog。
  2. 应用程序配置
    • 将写操作指向主库。
    • 将读操作指向从库。可以在应用层实现逻辑来决定查询使用哪个库。
2. 连接池配置

在应用程序中,使用连接池(如 HikariCP、C3P0)来管理数据库连接。

  • 读写分离:配置连接池分别用于写(主库)和读(从库)。

示例

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://主库地址");
config.setUsername("用户名");
config.setPassword("密码");
HikariDataSource dataSource = new HikariDataSource(config);

// 读操作
HikariConfig readConfig = new HikariConfig();
readConfig.setJdbcUrl("jdbc:mysql://从库地址");
HikariDataSource readDataSource = new HikariDataSource(readConfig);
3. 使用中间件

使用中间件(如 Mycat、Atlas)可以简化读写分离的实现。

  • 中间件负责路由请求,将写操作转发到主库,将读操作转发到从库。
  • 配置和管理更加灵活。
4. 应用程序逻辑

在应用程序中根据业务需求手动控制读写操作。例如:

  • 所有的写操作都通过一个 DAO(数据访问对象)发送到主库。
  • 所有的读操作则通过另一个 DAO 发送到从库。
注意事项
  • 延迟问题:从库的数据可能会有延迟,因此在进行读操作时要注意数据一致性。
  • 负载均衡:可以配置多个从库进行负载均衡。
  • 故障转移:确保主库或从库发生故障时能够快速切换。

实现读写分离可以显著提升数据库的性能,尤其是在读操作较多的场景中。


二.基于MySQL 8.2的 InnoDB ReplicaSet组件实现读写分离

我们一直在等待它!现在它已经可用!MySQL 中的读/写拆分!!

在规模上,我们在副本之间分配读取,但这必须在应用程序中以某种方式进行管理:将写入指向某处,将读取指向其他地方。

使用 MySQL 8.2,MySQL Router 现在能够识别读取和写入,并将它们路由到 InnoDB 集群中的主实例,或者路由到异步复制源进行写入,路由到辅助实例或副本进行读取。

为了说明这一点,我部署了最简单的架构:MySQL InnoDB ReplicaSet。

MySQL InnoDB ReplicaSet

MySQL InnoDB ReplicaSet

这是 MySQL Shell 中 ReplicaSet 对象的状态:

ReplicaSet status

Bootstrap MySQL Router 8.2
配置 (bootstrap) MySQL Router:

Bootstrap MySQL Router 8.2

the router in the MySQL Shell ReplicaSet object:

routers configuration

使用读写端口连接(6450):

use write&read port connect

我们可以看到,默认情况下,如果我们执行读取,我们将到达副本(辅助),但是如果我们启动事务,我们将到达复制源(主),而无需更改端口并使用相同的连接。

我们还可以看到使用只读事务时的区别:

read transaction use read replica

我们可以在 MySQL Router 的配置文件中看到生成的 R/W 分割设置:

[routing:bootstrap_rw_split]
bind_address=0.0.0.0
bind_port=6450
destinations=metadata-cache://myreplica/?role=PRIMARY_AND_SECONDARY
routing_strategy=round-robin
protocol=classic
connection_sharing=1
client_ssl_mode=PREFERRED
server_ssl_mode=PREFERRED
access_mode=auto

您还可以使用命令 ROUTER SET access_mode=: 在会话中定义要访问的实例类型:

RouterSetAccressMode

结论

总之,MySQL Router 8.2 支持读写拆分。这是一项有价值的功能,可用于优化数据库性能和可扩展性,而无需对应用程序进行任何更改。

此配置使您能够将所有读取流量引导至只读实例,并将所有写入流量引导至读写实例。

此功能不仅增强了整体用户体验,还简化了数据库管理和部署。

读写实例是主实例或源。只读实例是副本(InnoDB 群集辅助实例、ReplicaSet 辅助实例或副本群集中的辅助实例)。

享受 MySQL,再也没有借口不将工作负载分散到副本!


参考链接:

MySQL 8.2 – transparent read/write splitting

上一篇:【大模型专栏—实战篇】从0到1带你QLora微调


下一篇:Windows开发工具使用技巧