一. 传统的读写分离方式
在 MySQL 中实现读写分离可以通过以下几种方式来达到目的:
1. 主从复制
使用主从复制(Master-Slave Replication)是实现读写分离的常见方式。
- 主库:处理所有的写入操作(INSERT、UPDATE、DELETE)。
- 从库:负责处理读操作(SELECT)。
步骤:
-
设置主从复制:
- 在主库上配置 binlog,并创建复制用户。
- 在从库上配置 server-id,并指向主库的 binlog。
-
应用程序配置:
- 将写操作指向主库。
- 将读操作指向从库。可以在应用层实现逻辑来决定查询使用哪个库。
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 Shell 中 ReplicaSet 对象的状态:
Bootstrap MySQL Router 8.2
配置 (bootstrap) MySQL Router:
the router in the MySQL Shell ReplicaSet object:
使用读写端口连接(6450):
我们可以看到,默认情况下,如果我们执行读取,我们将到达副本(辅助),但是如果我们启动事务,我们将到达复制源(主),而无需更改端口并使用相同的连接。
我们还可以看到使用只读事务时的区别:
我们可以在 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=: 在会话中定义要访问的实例类型:
结论
总之,MySQL Router 8.2 支持读写拆分。这是一项有价值的功能,可用于优化数据库性能和可扩展性,而无需对应用程序进行任何更改。
此配置使您能够将所有读取流量引导至只读实例,并将所有写入流量引导至读写实例。
此功能不仅增强了整体用户体验,还简化了数据库管理和部署。
读写实例是主实例或源。只读实例是副本(InnoDB 群集辅助实例、ReplicaSet 辅助实例或副本群集中的辅助实例)。
享受 MySQL,再也没有借口不将工作负载分散到副本!
参考链接:
MySQL 8.2 – transparent read/write splitting