第435集MySQL主从复制架构详解 | 字数总计: 4.7k | 阅读时长: 18分钟 | 阅读量:
MySQL主从复制架构详解 1. 架构概述 1.1 MySQL主从复制架构类型 MySQL主从复制有多种架构模式,根据业务需求和技术场景,可以选择不同的架构方案。本文详细介绍以下四种常见的架构模式:
MySQL主从复制 :基础的一主一从架构
MySQL读写分离复制 :主库写,从库读
MySQL一主多从复制 :一个主库,多个从库
MySQL一主多从负载均衡 :一主多从 + 负载均衡器
1.2 架构选择原则 选择依据 :
业务规模 :数据量、并发量
可用性要求 :RTO、RPO要求
性能要求 :读写比例、响应时间
成本预算 :硬件、运维成本
架构演进路径 :
1 2 3 4 5 6 7 8 9 单机架构 ↓ 主从复制(备份) ↓ 读写分离复制(性能优化) ↓ 一主多从复制(读扩展) ↓ 一主多从负载均衡(高可用)
2. MySQL主从复制 2.1 架构说明 MySQL主从复制(Master-Slave Replication) 是最基础的复制架构,采用一主一从的模式。
架构图 :
1 2 3 4 5 6 7 Client │ ├─ 读写 ──→ MySQL Master │ │ │ │ 同步 │ ↓ │ MySQL Slave
特点 :
一个主库(Master)
一个从库(Slave)
主库负责所有读写操作
从库主要用于数据备份
2.2 应用场景 1. 数据备份 场景 :
需要定期备份数据
备份不能影响主库性能
需要保留历史数据快照
优势 :
从库可以独立进行备份
备份过程对主库透明
不影响业务运行
2. 实时灾备 场景 :
优势 :
3. 数据分析 场景 :
需要分析历史数据
分析不影响业务
需要独立的数据副本
优势 :
从库可以用于数据分析
不影响主库性能
可以保留多个时间点快照
2.3 配置步骤 环境准备 1 2 3 4 5 6 192.168.70.160 master 192.168.70.161 slave
Master配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 [mysqld] log-bin=master-bin server-id=1 gtid_mode=ON enforce_gtid_consistency=1 systemctl restart mysqld mysql> CREATE USER 'repl' @'192.168.70.%' IDENTIFIED BY 'Rep123.com' ; mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl' @'192.168.70.%' ; mysql> FLUSH PRIVILEGES; mysql> SHOW MASTER STATUS; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | master-bin.000001| 154 | | | | +------------------+----------+--------------+------------------+-------------------+
Slave配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [mysqld] server-id=2 gtid_mode=ON enforce_gtid_consistency=1 systemctl restart mysqld mysql> CHANGE MASTER TO -> MASTER_HOST='master' , -> MASTER_USER='repl' , -> MASTER_PASSWORD='Rep123.com' , -> MASTER_AUTO_POSITION=1; mysql> START SLAVE; mysql> SHOW SLAVE STATUS\G
2.4 验证测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 mysql> CREATE DATABASE testdb; mysql> USE testdb; mysql> CREATE TABLE t1(id INT PRIMARY KEY, name VARCHAR (50 )); mysql> INSERT INTO t1 VALUES (1 , 'test1' ); mysql> INSERT INTO t1 VALUES (2 , 'test2' ); mysql> SELECT * FROM testdb.t1; + | id | name | + | 1 | test1 | | 2 | test2 | +
2.5 架构优缺点 优点
配置简单 :架构简单,易于配置和维护
成本低 :只需要两台服务器
数据备份 :从库可以独立备份
故障切换 :主库故障可以切换到从库
缺点
单点故障 :主库是单点故障
读压力 :所有读操作都在主库
扩展性差 :无法扩展读性能
资源浪费 :从库资源利用率低
3. MySQL读写分离复制 3.1 架构说明 MySQL读写分离复制(Read-Write Separation) 是在主从复制基础上,将读操作和写操作分离到不同的服务器。
架构图 :
1 2 3 4 5 6 7 Client │ ├─ 写操作 ──→ MySQL Master │ │ │ │ 同步 │ ↓ ├─ 读操作 ──→ MySQL Slave
特点 :
主库负责写操作(INSERT、UPDATE、DELETE)
从库负责读操作(SELECT)
读写分离,减轻主库压力
提高系统整体性能
3.2 应用场景 1. 高并发读场景 场景 :
优势 :
2. 报表查询 场景 :
需要大量报表查询
查询不影响业务
需要独立查询环境
优势 :
从库专门用于报表查询
不影响主库性能
查询性能更好
3. 数据分析 场景 :
需要实时数据分析
分析不影响业务
需要独立分析环境
优势 :
从库用于数据分析
不影响主库性能
可以保留历史数据
3.3 实现方式 方式一:应用层实现 原理 :在应用程序代码中区分读写操作。
示例代码(Java) :
1 2 3 4 5 6 7 8 9 10 11 @DataSource("master") public void insertData (Data data) { dataMapper.insert(data); } @DataSource("slave") public Data selectData (int id) { return dataMapper.selectById(id); }
优点 :
缺点 :
方式二:中间件实现 原理 :使用中间件自动路由读写操作。
常用中间件 :
MyCat :开源数据库中间件
ProxySQL :高性能代理
MySQL Router :MySQL官方路由
配置示例(MyCat) :
1 2 3 4 5 6 7 8 9 10 <dataHost name ="testdb" maxCon ="1000" minCon ="10" balance ="1" writeType ="0" dbType ="mysql" dbDriver ="native" > <heartbeat > SELECT user()</heartbeat > <writeHost host ="master" url ="192.168.70.160:3306" user ="root" password ="Bgx123.com" > <readHost host ="slave" url ="192.168.70.161:3306" user ="root" password ="Bgx123.com" /> </writeHost > </dataHost >
优点 :
缺点 :
3.4 配置步骤 使用MyCat实现读写分离 1. 安装MyCat 1 2 3 4 5 6 yum install -y java wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz tar -xzf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/
2. 配置server.xml 1 2 3 4 5 <user name ="appuser" > <property name ="password" > 123456</property > <property name ="schemas" > testdb</property > </user >
3. 配置schema.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <schema name ="testdb" checkSQLschema ="false" dataNode ="dn1" > </schema > <dataNode name ="dn1" dataHost ="dh1" database ="testdb" /> <dataHost name ="dh1" maxCon ="1000" minCon ="10" balance ="1" writeType ="0" dbType ="mysql" dbDriver ="native" > <heartbeat > SELECT user()</heartbeat > <writeHost host ="master" url ="192.168.70.160:3306" user ="root" password ="Bgx123.com" > <readHost host ="slave" url ="192.168.70.161:3306" user ="root" password ="Bgx123.com" /> </writeHost > </dataHost >
balance参数说明 :
0:不开启读写分离,所有操作都发送到writeHost
1:所有readHost和writeHost都参与读操作负载均衡
2:读操作随机在writeHost和readHost上分发
4. 启动MyCat 1 2 3 4 5 /usr/local/mycat/bin/mycat start netstat -tlnp | grep 8066
5. 测试读写分离 1 2 3 4 5 6 7 8 mysql -h127.0.0.1 -P8066 -uappuser -p123456 mysql> INSERT INTO testdb.t1 VALUES (3, 'test3' ); mysql> SELECT * FROM testdb.t1;
3.5 注意事项 1. 数据一致性 问题 :主从复制存在延迟,可能导致读不到最新数据。
解决方案 :
强制读主 :关键业务强制读主库
延迟容忍 :非关键业务容忍延迟
最终一致性 :接受最终一致性
2. 主从延迟 问题 :主从复制延迟导致数据不一致。
监控 :
1 2 3 mysql> SHOW SLAVE STATUS\G Seconds_Behind_Master: 0
优化 :
3.6 架构优缺点 优点
性能提升 :读操作分散,减轻主库压力
扩展性好 :可以增加从库扩展读性能
资源利用 :充分利用从库资源
高可用 :主库故障可以切换
缺点
数据延迟 :主从延迟导致数据不一致
复杂度增加 :需要中间件或代码支持
成本增加 :需要额外组件
维护成本 :需要维护中间件
4. MySQL一主多从复制 4.1 架构说明 MySQL一主多从复制(One Master Many Slaves) 是在主从复制基础上,增加多个从库。
架构图 :
1 2 3 4 5 6 7 8 9 Client │ ├─ 写操作 ──→ MySQL Master │ │ │ ├─ 同步 ──→ MySQL Slave1 │ ├─ 同步 ──→ MySQL Slave2 │ └─ 同步 ──→ MySQL Slave3 │ └─ 读操作 ──→ [Slave1, Slave2, Slave3] (负载均衡)
特点 :
一个主库(Master)
多个从库(Slave1, Slave2, Slave3…)
主库负责写操作
从库负责读操作,负载均衡
4.2 应用场景 1. 高并发读场景 场景 :
读操作并发量非常大
单个从库无法承受读压力
需要多个从库分担读压力
优势 :
读操作分散到多个从库
大幅提升读性能
更好的扩展性
2. 多业务场景 场景 :
不同业务需要不同的从库
报表查询需要独立从库
数据分析需要独立从库
优势 :
3. 地理分布 场景 :
优势 :
4.3 配置步骤 环境准备
Master配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [mysqld] log-bin=master-bin server-id=1 gtid_mode=ON enforce_gtid_consistency=1 systemctl restart mysqld mysql> CREATE USER 'repl' @'192.168.70.%' IDENTIFIED BY 'Rep123.com' ; mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl' @'192.168.70.%' ; mysql> FLUSH PRIVILEGES; mysqldump -uroot -pBgx123.com \ --all-databases \ --master-data=1 \ --single-transaction \ --flush-logs > /root/master-all.sql
Slave1配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [mysqld] server-id=2 gtid_mode=ON enforce_gtid_consistency=1 systemctl restart mysqld mysql -uroot -pBgx123.com < /root/master-all.sql mysql> CHANGE MASTER TO -> MASTER_HOST='192.168.70.160' , -> MASTER_USER='repl' , -> MASTER_PASSWORD='Rep123.com' , -> MASTER_AUTO_POSITION=1; mysql> START SLAVE; mysql> SHOW SLAVE STATUS\G
Slave2和Slave3配置 配置步骤与Slave1相同 ,只需要修改server-id:
4.4 读操作负载均衡 方式一:应用层负载均衡 原理 :在应用层实现读操作的负载均衡。
示例代码(Java) :
1 2 3 4 5 6 7 @DataSource("slave") public Data selectData (int id) { String slave = getSlaveByRoundRobin(); return dataMapper.selectById(id, slave); }
方式二:使用中间件 使用MyCat实现 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <dataHost name ="testdb" maxCon ="1000" minCon ="10" balance ="1" writeType ="0" dbType ="mysql" dbDriver ="native" > <heartbeat > SELECT user()</heartbeat > <writeHost host ="master" url ="192.168.70.160:3306" user ="root" password ="Bgx123.com" > <readHost host ="slave1" url ="192.168.70.161:3306" user ="root" password ="Bgx123.com" /> <readHost host ="slave2" url ="192.168.70.162:3306" user ="root" password ="Bgx123.com" /> <readHost host ="slave3" url ="192.168.70.163:3306" user ="root" password ="Bgx123.com" /> </writeHost > </dataHost >
4.5 架构优缺点 优点
读性能大幅提升 :多个从库分担读压力
扩展性好 :可以随时增加从库
高可用性 :多个从库,容错能力强
资源隔离 :不同业务可以使用不同从库
缺点
成本增加 :需要多台从库服务器
维护复杂 :需要维护多个从库
数据延迟 :多个从库延迟可能不同
主库压力 :主库需要同步到多个从库
5. MySQL一主多从负载均衡 5.1 架构说明 MySQL一主多从负载均衡(One Master Many Slaves with Load Balancer) 是在一主多从基础上,使用负载均衡器分发读请求。
架构图 :
1 2 3 4 5 6 7 8 9 10 11 12 13 Client │ ├─ 写操作 ──→ MySQL Master │ │ │ ├─ 同步 ──→ MySQL Slave1 │ ├─ 同步 ──→ MySQL Slave2 │ └─ 同步 ──→ MySQL Slave3 │ └─ 读操作 ──→ LVS+Keepalived (VIP) │ ├─→ MySQL Slave1 ├─→ MySQL Slave2 └─→ MySQL Slave3
特点 :
一个主库(Master)
多个从库(Slave1, Slave2, Slave3…)
使用LVS+Keepalived实现负载均衡
高可用性和高性能
5.2 应用场景 1. 高可用性要求 场景 :
优势 :
Keepalived实现高可用
从库故障自动切换
服务持续可用
2. 大规模读场景 场景 :
优势 :
3. 生产环境 场景 :
优势 :
5.3 LVS+Keepalived配置 环境准备
安装Keepalived 1 2 yum install -y keepalived ipvsadm
LVS节点1配置 1 2 vim /etc/keepalived/keepalived.conf
配置内容 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 global_defs { router_id LVS_DEVEL } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.70.100 } } virtual_server 192.168.70.100 3306 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 50 protocol TCP real_server 192.168.70.161 3306 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3306 } } real_server 192.168.70.162 3306 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3306 } } real_server 192.168.70.163 3306 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 3306 } } }
LVS节点2配置 配置与节点1相同 ,只需修改:
1 2 state BACKUP priority 90
从库配置(DR模式) 在每个从库上配置VIP :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 vim /etc/sysconfig/network-scripts/ifcfg-lo:0 DEVICE=lo:0 IPADDR=192.168.70.100 NETMASK=255.255.255.255 ONBOOT=yes ifup lo:0 echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignoreecho "2" > /proc/sys/net/ipv4/conf/lo/arp_announceecho "1" > /proc/sys/net/ipv4/conf/all/arp_ignoreecho "2" > /proc/sys/net/ipv4/conf/all/arp_announce
启动Keepalived 1 2 3 4 5 6 systemctl start keepalived systemctl enable keepalived ip addr show
5.4 应用配置 应用连接配置 应用连接VIP进行读操作 :
1 2 3 4 5 6 @DataSource("slave") public Data selectData (int id) { return dataMapper.selectById(id); }
或者使用MyCat连接VIP :
1 2 <readHost host ="slave-vip" url ="192.168.70.100:3306" user ="root" password ="Bgx123.com" />
5.5 故障切换测试 测试从库故障 1 2 3 4 5 6 7 8 systemctl stop mysqld ipvsadm -ln mysql -h192.168.70.100 -uroot -pBgx123.com -e "SELECT * FROM testdb.t1;"
预期结果 :
LVS自动检测到从库1故障
读请求自动切换到其他从库
服务不中断
测试LVS节点故障 1 2 3 4 5 6 systemctl stop keepalived ip addr show
预期结果 :
VIP自动切换到LVS节点2
服务不中断
读操作正常
5.6 监控告警 监控LVS状态 1 2 3 4 5 6 7 8 ipvsadm -ln systemctl status keepalived ip addr show
监控从库状态 1 2 3 4 5 mysql> SHOW SLAVE STATUS\G Slave_IO_Running: Yes Slave_SQL_Running: Yes Seconds_Behind_Master: 0
5.7 架构优缺点 优点
高可用性 :LVS+Keepalived实现高可用
负载均衡 :自动分发读请求
故障自动切换 :从库故障自动切换
性能优秀 :充分利用所有从库资源
扩展性好 :可以随时增加从库
缺点
架构复杂 :需要配置LVS+Keepalived
成本较高 :需要额外的LVS节点
维护复杂 :需要维护多个组件
网络要求 :需要配置VIP和ARP
6. 架构对比 6.1 架构对比表
特性
主从复制
读写分离
一主多从
一主多从负载均衡
从库数量
1个
1个
多个
多个
读性能
低
中
高
最高
可用性
中
中
高
最高
复杂度
低
中
中
高
成本
低
低
中
高
适用场景
备份、灾备
读多写少
高并发读
生产环境
6.2 选择建议 小型应用 推荐 :主从复制
中型应用 推荐 :读写分离或一主多从
大型应用 推荐 :一主多从负载均衡
7. 最佳实践 7.1 配置建议 1. 使用GTID 推荐 :使用GTID模式进行复制
优势 :
自动定位binlog位置
故障恢复更简单
支持多源复制
2. 并行复制 推荐 :开启并行复制
配置 :
1 2 3 slave_parallel_workers= 4 slave_parallel_type= LOGICAL_CLOCK
优势 :
3. 半同步复制 推荐 :使用半同步复制
配置 :
1 2 3 4 5 6 7 plugin_load= "rpl_semi_sync_master=semisync_master.so" rpl_semi_sync_master_enabled= 1 plugin_load= "rpl_semi_sync_slave=semisync_slave.so" rpl_semi_sync_slave_enabled= 1
优势 :
7.2 监控建议 1. 复制延迟监控 1 2 3 4 5 6 7 SELECT server_id, Seconds_Behind_Master, Slave_IO_Running, Slave_SQL_Running FROM information_schema.slave_status;
2. 主从状态监控 1 2 3 4 5 SHOW MASTER STATUS;SHOW SLAVE STATUS\G
3. 性能监控 1 2 3 SHOW PROCESSLIST;SHOW STATUS LIKE 'Threads_connected' ;
7.3 故障处理 1. 复制中断处理 1 2 3 4 5 6 SHOW SLAVE STATUS\GSET GLOBAL sql_slave_skip_counter = 1 ;START SLAVE;
2. 主从切换 1 2 3 4 5 6 STOP SLAVE; RESET SLAVE;
8. 总结 8.1 架构演进路径 1 2 3 4 5 6 7 8 9 单机架构 ↓ 主从复制(备份、灾备) ↓ 读写分离(性能优化) ↓ 一主多从(读扩展) ↓ 一主多从负载均衡(高可用)
8.2 选择原则
根据业务规模 :选择适合的架构
根据可用性要求 :选择高可用方案
根据性能要求 :选择性能优化方案
根据成本预算 :平衡性能和成本
8.3 架构师建议
优先使用GTID :简化配置和管理
开启并行复制 :提高复制性能
使用半同步复制 :保证数据安全
完善监控告警 :及时发现问题
定期演练 :测试故障切换流程
相关文章 :