当前位置: 首页 > news >正文

MySQL 运维知识点(十六)---- 读写分离

一、 读写分离介绍

1. 什么是读写分离?

读写分离是基于主从复制架构,让 主数据库处理事务性写操作从数据库处理查询读操作,通过应用逻辑或中间件将读写操作路由到不同数据库服务器。

2. 为什么要读写分离?
  • 提升性能:分摊数据库负载,避免读写冲突

  • 提高并发:主库专注写,多个从库分担读压力

  • 高可用性:从库可作为主库的故障备用

  • 业务解耦:不同业务模块可使用不同的数据库连接

3. 实现方式
实现方式描述优点缺点
应用层实现在代码中区分读写数据源灵活可控,性能好代码侵入性强,维护复杂
中间件代理使用Mycat、ShardingSphere等中间件对应用透明,集中管理单点风险,增加网络跳转

二、 一主一从架构

1. 架构图
┌─────────────┐   复制    ┌─────────────┐
│  主库 Master │ ────────> │ 从库 Slave  │
│   (写)      │           │   (读)      │
└─────────────┘           └─────────────┘
2. 配置步骤

主库配置 (my.cnf)

[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW

从库配置 (my.cnf)

[mysqld]
server-id = 2
relay-log = mysql-relay-bin
read_only = 1  # 从库只读

建立复制

-- 在主库创建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';-- 在从库配置主从连接
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;START SLAVE;

三、 一主一从读写分离

1. 应用层实现(Spring Boot示例)
# application.yml
spring:datasource:master:url: jdbc:mysql://master:3306/dbusername: userpassword: passslave:url: jdbc:mysql://slave:3306/dbusername: userpassword: pass
@Configuration
public class DataSourceConfig {@Bean@Primarypublic DataSource dataSource() {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("master", masterDataSource());targetDataSources.put("slave", slaveDataSource());RoutingDataSource routingDataSource = new RoutingDataSource();routingDataSource.setTargetDataSources(targetDataSources);routingDataSource.setDefaultTargetDataSource(masterDataSource());return routingDataSource;}
}// 使用注解切换数据源
@Service
public class UserService {@Transactional@DataSource("master")  // 写操作使用主库public void createUser(User user) {userMapper.insert(user);}@DataSource("slave")   // 读操作使用从库public User getUserById(Long id) {return userMapper.selectById(id);}
}
2. 中间件实现(Mycat配置)

schema.xml

<dataHost name="host1" maxCon="1000" minCon="10" balance="1"writeType="0" dbType="mysql" dbDriver="jdbc"><heartbeat>select user()</heartbeat><writeHost host="hostM1" url="jdbc:mysql://master:3306" user="root" password="123456"><readHost host="hostS1" url="jdbc:mysql://slave:3306" user="root" password="123456"/></writeHost>
</dataHost>

balance参数说明

  • 0:不开启读写分离

  • 1:所有读操作随机发送到所有读Host

  • 2:所有读操作随机发送到所有Host(包括WriteHost)

  • 3:所有读操作随机发送到所有读Host,不在writeHost的readHost上执行

四、 双主双从架构

1. 架构图
┌─────────────┐           ┌─────────────┐
│ 主库1 Master1│ ←───────→ │ 主库2 Master2│
└─────────────┘           └─────────────┘↓                           ↓
┌─────────────┐           ┌─────────────┐
│ 从库1 Slave1 │           │ 从库2 Slave2 │
└─────────────┘           └─────────────┘
2. 双主配置

Master1 配置

[mysqld]
server-id = 1
log-bin = mysql-bin
auto_increment_increment = 2  # 自增步长
auto_increment_offset = 1     # 自增起始值

Master2 配置

[mysqld]
server-id = 2
log-bin = mysql-bin
auto_increment_increment = 2
auto_increment_offset = 2

配置互为主从

-- 在Master1上执行
CHANGE MASTER TO
MASTER_HOST='master2_ip',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;-- 在Master2上执行  
CHANGE MASTER TO
MASTER_HOST='master1_ip',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
3. 双主双从优势
  • 高可用:任一主库故障,另一主库可继续提供服务

  • 负载均衡:写操作可分摊到两个主库

  • 容灾备份:多节点数据冗余,数据更安全

五、 双主双从读写分离

1. Mycat 配置实现

schema.xml

<dataHost name="host1" maxCon="1000" minCon="10" balance="1"writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"><heartbeat>select user()</heartbeat><writeHost host="hostM1" url="jdbc:mysql://master1:3306" user="root" password="123456"><readHost host="hostS1" url="jdbc:mysql://slave1:3306" user="root" password="123456"/></writeHost><writeHost host="hostM2" url="jdbc:mysql://master2:3306" user="root" password="123456"><readHost host="hostS2" url="jdbc:mysql://slave2:3306" user="root" password="123456"/></writeHost>
</dataHost>

关键参数

  • switchType="1":自动切换,当写Host宕机时自动切换到其他写Host

  • balance="1":读请求负载均衡到所有读Host

2. 应用层多数据源配置
@Configuration
public class MultiDataSourceConfig {@Beanpublic DataSource routingDataSource() {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("master1", master1DataSource());targetDataSources.put("master2", master2DataSource());targetDataSources.put("slave1", slave1DataSource());targetDataSources.put("slave2", slave2DataSource());RoutingDataSource routingDataSource = new RoutingDataSource();routingDataSource.setTargetDataSources(targetDataSources);routingDataSource.setDefaultTargetDataSource(master1DataSource());return routingDataSource;}// 动态数据源路由public class ReadWriteRoutingStrategy {private AtomicInteger masterCounter = new AtomicInteger(0);private AtomicInteger slaveCounter = new AtomicInteger(0);public String determineMasterLookupKey() {int index = masterCounter.incrementAndGet() % 2;return "master" + (index + 1);}public String determineSlaveLookupKey() {int index = slaveCounter.incrementAndGet() % 2;return "slave" + (index + 1);}}
}

六、 读写分离的注意事项

1. 数据一致性问题
  • 复制延迟:主从同步存在毫秒级延迟

  • 解决方案

    • 对实时性要求高的读操作强制走主库

    • 使用半同步复制减少数据丢失风险

    • 应用层根据业务容忍度选择数据源

2. 事务问题
@Service
public class OrderService {@Transactionalpublic void createOrder(Order order) {// 强制使用主库,避免事务中读写分离DataSourceContext.setDataSource("master");try {orderMapper.insert(order);// 即使查询也走主库,保证事务内数据一致性Order newOrder = orderMapper.selectById(order.getId());// ... 其他业务逻辑} finally {DataSourceContext.clear();}}
}
3. 故障转移处理
  • 监控主从复制状态

  • 自动或手动切换故障节点

  • 应用层重试机制

4. 负载均衡策略
  • 轮询:依次分配请求

  • 权重:根据服务器性能分配不同权重

  • 最少连接:选择当前连接数最少的服务器

  • 响应时间:选择响应时间最短的服务器

七、 监控与维护

1. 关键监控指标
-- 监控主从延迟
SHOW SLAVE STATUS\G
-- 关注:Seconds_Behind_Master-- 监控数据库连接数
SHOW STATUS LIKE 'Threads_connected';-- 监控QPS/TPS
SHOW STATUS LIKE 'Queries';
SHOW STATUS LIKE 'Com_commit';
SHOW STATUS LIKE 'Com_rollback';
2. 日常维护命令
-- 检查复制状态
SHOW REPLICA STATUS;  -- MySQL 8.0+
SHOW SLAVE STATUS;    -- MySQL 5.7-- 停止/启动复制
STOP REPLICA;
START REPLICA;-- 跳过复制错误(谨慎使用)
SET GLOBAL sql_replica_skip_counter = 1;

总结

读写分离架构演进

单机MySQL → 一主一从 → 一主多从 → 双主多从

技术选型建议

  • 小型项目:应用层实现 + 一主一从

  • 中型项目:Mycat中间件 + 一主多从

  • 大型项目:ShardingSphere + 双主多从 + 分库分表

核心价值:通过读写分离,可以显著提升数据库系统的读性能可用性,是构建高并发应用的基础架构之一。

http://www.dtcms.com/a/445895.html

相关文章:

  • 网站建设生存期模型希音电商网站
  • 济南网站建设培训班永久免费网站建设
  • 高层次综合报告分析-vivado hls第四章
  • Go语言中的Zap日志库
  • Linux网络编程——UdpServer
  • Daily算法刷题【面试经典150题-3️⃣】
  • MybatisPlus和pagehelper分页冲突—关于jsqlparser、pagehelper、MybatisPlus三者的版本兼容问题
  • R 数组:深入解析与高效使用
  • 缩点学习笔记
  • Go基础:用Go语言操作MongoDB详解
  • 第六章:适配器模式 - 接口转换的艺术大师
  • ARM环境日志系统的简单设计思路
  • 网站名称推荐大气聚财的公司名字
  • 【JVM】——实战篇
  • 那里有正规网站开发培训学校个人网站是怎么样的
  • 高端网站设计简介推荐外贸网站建设的公司
  • asp.net 网站安装工商核名在哪个网站
  • 基于websocket的多用户网页五子棋(五)
  • 【图像处理基石】什么是全景视觉?
  • 【Linux】线程同步和生产者消费者模型
  • 《嵌入式驱动(三):字符设备驱动开发》
  • 做的网站提示磁盘空间不足投票活动网站怎么做
  • 项目1:FFMPEG推流器讲解(二):FFMPEG输出模块初始化
  • 中级前端进阶方向 框架篇 三十四) 前端自动化测试 + 【步骤落地 + 了解】
  • 【开题答辩全过程】以 python杭州亚运会数据分析与可视化开题为例,包含答辩的问题和答案
  • 中国做外贸网站有哪些网站下雪的效果怎么做的
  • XSLT `<choose>` 元素详解
  • 汽车零部件英语词汇 | 3000 最常用单词系列
  • 深圳优秀网站建设价格网站视频开发平台
  • 菏泽最好的网站建设公司安徽建设工程信息网查