【数据库架构】MySQL读写分离详解

MySQL 读写分离

一、读写分离的基本概念

读写分离是一种常见的数据库架构优化策略,其核心是将数据库操作按类型分流:所有写操作(如 INSERT、UPDATE、DELETE)由主库(Master)处理,而读操作(如 SELECT)则由一个或多个从库(Slave)承担。该设计充分利用了大多数应用"读多写少"的访问特征,有效降低主库负载,提升系统整体并发能力和可用性。

读写分离依赖于 MySQL 的主从复制机制。主库将数据变更记录到二进制日志(binlog),从库通过拉取并重放这些日志实现数据同步,从而提供只读服务。

二、读写分离的实现方式

目前主流的实现方式分为两类:

  1. 中间件代理
    使用 ProxySQL、MySQL Router 或 Apache ShardingSphere-Proxy 等中间件,在数据库前端自动识别 SQL 类型并路由请求。应用程序仅需连接中间件地址,无需感知后端主从结构,具有良好的透明性和可维护性。
  2. 应用层数据源路由
    通过 ORM 框架(如 MyBatis、Django、Sequelize)配置多个数据源,在代码层面根据操作类型选择主库或从库。这种方式实现简单,但对业务代码有一定侵入性,且难以统一管理一致性策略。

相比手动编码控制,中间件方案更推荐用于生产环境。

三、实践中的关键问题与应对

尽管读写分离能显著提升读性能,但在实际应用中需注意以下问题:

  • 主从延迟:从库数据同步存在时间差,可能导致读取旧数据。解决方案包括:对"写后立即读"的关键路径强制走主库、基于会话绑定读写节点、监控复制延迟并动态降级。
  • 事务内读一致性:事务中若包含写操作,后续读必须访问主库,否则可能破坏事务隔离性。
  • 适用场景限制:读写分离适用于读密集型、可容忍短暂延迟的业务;对于强一致性或写密集型系统(如金融核心交易),需谨慎评估或结合其他架构方案。

四、实验配置

整个实验的环境 以及服务器信息

  • 环境部署 cetos7.6
  • 虚拟机服务环境
    Master服务器:192.168.65.131
    slave1服务器:192.168.65.133
    Slave2服务器:192.168.65.135
    Amoeba服务器:192.168.65.128 jdk1.6、Amoeba

4.1 搭建 MySQL读写分离

4.1.1 Amoeba服务器配置----
复制代码
① ##安装 Java 环境##
cd /opt/
cp jdk-6u14-linux-x64.bin /usr/local/
cd /usr/local/
chmod +x jdk-6u14-linux-x64
./jdk-6u14-linux-x64.bin
//按yes,按enter
cd
mv jdk1.6.0_14/ /usr/local/jdk1.6

vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin

source /etc/profile
java -version

② ##安装 Amoeba软件##
mkdir /usr/local/amoeba
tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
chmod -R 755 /usr/local/amoeba/
/usr/local/amoeba/bin/amoeba
//如显示amoeba start|stop说明安装成功

③ ##配置 Amoeba读写分离,两个 Slave 读负载均衡##
#先在Master、Slave1、Slave2 的mysql上开放权限给 Amoeba 访问
grant all on *.* to test@'192.168.65.%' identified by '123456';

#再回到amoeba服务器配置amoeba服务:
cd /usr/local/amoeba/conf/

cp amoeba.xml amoeba.xml.bak
#修改amoeba配置文件
vim amoeba.xml									
--30行--
<property name="user">amoeba</property>
--32行-- 
<property name="password">123456</property>
--115行--
<property name="defaultPool">master</property>
--117-去掉注释-
<property name="writePool">master</property>
<property name="readPool">slaves</property>

cp dbServers.xml dbServers.xml.bak
#修改数据库配置文件
vim dbServers.xml								
--23行--注释掉  作用:默认进入test库 以防mysql中没有test库时,会报错
<!-- <property name="schema">test</property> -->
--26--修改
<property name="user">test</property>
--28-30--去掉注释
<property name="password">123456</property>
--45--修改,设置主服务器的名Master
<dbServer name="master"  parent="abstractServer">
--48--修改,设置主服务器的地址
<property name="ipAddress">192.168.65.131</property>
--52--修改,设置从服务器的名slave1
<dbServer name="slave1"  parent="abstractServer">
--55--修改,设置从服务器1的地址
<property name="ipAddress">192.168.65.133</property>
--58--复制上面6行粘贴,设置从服务器2的名slave2和地址
<dbServer name="slave2"  parent="abstractServer">
<property name="ipAddress">192.168.65.135</property>
--65行--修改
<dbServer name="slaves" virtual="true">
--71行--修改
<property name="poolNames">slave1,slave2</property>

#启动Amoeba软件,按ctrl+c 返回
/usr/local/amoeba/bin/amoeba start &	
#查看8066端口是否开启,默认端口为TCP 8066
netstat -anpt | grep java							
4.1.2 测试读写分离
复制代码
#先安装数据库
yum install -y mariadb-server mariadb
systemctl start mariadb.service
在客户端服务器上测试
mysql -u amoeba -p123456 -h 192.168.65.128 -P8066		
//通过amoeba服务器代理访问mysql ,在通过客户端连接mysql后写入的数据只有主服务会记录,然后同步给从--从服务器

#在主服务器上:
use db_test;
create table test (id int(10),name varchar(10),address varchar(20));

#在两台从服务器上:
#关闭同步
stop slave;											
use db_test;
#在slave1上:
insert into test values('1','zhangsan','this_is_slave1');

#在slave2上:
insert into test values('2','lisi','this_is_slave2');

#在主服务器上:
insert into test values('3','wangwu','this_is_master');

#在客户端服务器上:
use db_test;
#客户端会分别向slave1和slave2读取数据,显示的只有在两个从服务器上添加的数据,没有在主服务器上添加的数据
select * from test;		
#只有主服务器上有此数据
insert into test values('4','qianqi','this_is_client');		

//在两个从服务器上执行 start slave; 即可实现同步在主服务器上添加的数据
start slave;
相关推荐
松涛和鸣29 分钟前
72、IMX6ULL驱动实战:设备树(DTS/DTB)+ GPIO子系统+Platform总线
linux·服务器·arm开发·数据库·单片机
likangbinlxa1 小时前
【Oracle11g SQL详解】UPDATE 和 DELETE 操作的正确使用
数据库·sql
r i c k1 小时前
数据库系统学习笔记
数据库·笔记·学习
野犬寒鸦1 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
IvorySQL2 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·2 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德2 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫3 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i3 小时前
完全卸载MariaDB
数据库·mariadb
纤纡.3 小时前
Linux中SQL 从基础到进阶:五大分类详解与表结构操作(ALTER/DROP)全攻略
linux·数据库·sql