Mysql 主从复制 读写分离 分库分表

184 阅读21分钟

风景篇 海边 柏油路_1_口袋壁纸_来自小红书网页版.jpg

前言

在互联网业务爆发式增长的时代背景下,传统单体数据库架构面临着三大核心挑战:海量数据存储、高并发访问压力、业务连续性保障。本章将重点解析 MySQL 生态中主从复制、读写分离、分库分表三大核心技术的体系化应用。

主从复制

什么是主从复制

MySQL 主从复制是指将主数据库的数据自动复制到一个或多个从数据库的过程。主数据库(Master)负责写操作,从数据库(Slave)负责读操作,这种架构可以实现读写分离,提高系统的并发处理能力。

MySQL支持一台主库同时向多台从库进行复制, 从库同时也可以作为其他从服务器的主库,实现链状

复制。

主从复制原理

1739111731117.png MySQL 主从复制涉及三个步骤:

  1. 主库:Master 主库在事务提交时,会把数据变更记录在二进制日志文件 Binlog 中。
  2. I/O 线程(从库):从库中由 IOthread 线程负责读取主库的二进制日志文件 Binlog ,写入到从库的中继日志 Relay Log 。
  3. SQL 线程(从库):读取 relay log 中的日志事件并且重做,以改变数据。

复制模式

  1. 异步复制(默认)

    • 主库执行完事务后立即返回客户端
    • 不等待从库复制完成
  2. 半同步复制

    • 主库执行完事务后等待至少一个从库接收并写入 relay log
    • 才返回给客户端
  3. 全同步复制

    • 主库执行完事务后等待所有从库执行完成
    • 才返回给客户端

配置步骤

主库配置

  1. 修改 MySQL 配置文件(/etc/my.cnf):

    [mysqld]
    # mysql 服务ID,保证整个集群环境中唯一,取值范围:1 – 232-1,默认为1
    server-id=1
    #是否只读,1 代表只读, 0 代表读写
    read-only=0
    # 开启二进制日志
    log-bin=mysql-bin
    # 需要复制的数据库
    #binlog-do-db=需要复制的数据库名
    # 不需要复制的数据库
    #binlog-ignore-db=mysql
    
  2. 重启MySQL服务器

    systemctl restart mysqld
    
  3. 登录mysql,创建远程连接的账号,并授予主从复制权限

    #创建itcast用户,并设置密码,该用户可在任意主机连接该MySQL服务
    CREATE USER 'itcast'@'%' IDENTIFIED WITH mysql_native_password BY 'Root@123456';
    #为 'itcast'@'%' 用户分配主从复制权限
    GRANT REPLICATION SLAVE ON *.* TO 'itcast'@'%';
    
  4. 通过指令,查看二进制日志坐标

    show master status;
    

    输出结果字段说明:

    file : 从哪个日志文件开始推送日志文件

    position : 从哪个位置开始推送日志

    binlog_ignore_db : 指定不需要同步的数据库

从库配置

  1. 修改 MySQL 配置文件:

    [mysqld]
    # mysql 服务ID,保证整个集群环境中唯一,取值范围:1 – 2^32-1,和主库不一样即可
    server-id=2
    #是否只读,1 代表只读, 0 代表读写
    read-only=1
    # 开启中继日志
    relay-log=mysql-relay
    
  2. 重启 Mysql

    systemctl restart mysqld
    
  3. 登录mysql,设置主库配置

    CHANGE REPLICATION SOURCE TO 
    SOURCE_HOST='192.168.200.200', 
    SOURCE_USER='itcast',
    SOURCE_PASSWORD='Root@123456', 
    SOURCE_LOG_FILE='binlog.000004',
    SOURCE_LOG_POS=663;
    

    上述是8.0.23中的语法。如果mysql是 8.0.23 之前的版本,执行如下SQL:

    CHANGE MASTER TO
    MASTER_HOST='主库IP',
    MASTER_PORT=3306,
    MASTER_USER='repl',
    MASTER_PASSWORD='password',
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=0;
    
  4. 启动从库复制:

    start replica ; #8.0.22之后
    start slave ; #8.0.22之前
    
  5. 查看从库状态

    show replica status ; #8.0.22之后
    show slave status ; #8.0.22之前
    

    这里主要确保 Replica_IO_Running 和 Replica_SQL_Running 是正常运行的。

    1739117789329.png

  6. 测试

    现在可以在主库中创建数据库、表并插入数据,然后验证是否自动主从同步。

注意事项

  • 主从服务器操作系统版本和位数最好一致
  • MySQL 版本最好一致
  • 主从数据库数据初始化时最好一致
  • 主库和从库的 server-id 必须不同
  • 从库配置要比主库配置大,否则可能导致主库写入数据从库无法同步

分库分表

什么是分库分表

分库分表是通过数据库拆分策略,将单一数据库/表的数据分布到多个数据库/表的架构设计。主要解决单机数据库面临的三大瓶颈:

  1. 存储瓶颈:单机磁盘容量限制
  2. 性能瓶颈:单机I/O瓶颈,热点数据太多,数据库缓存不足,产生大量磁盘IO,效率较低。 请求数据太多,带宽不够,网络IO瓶颈。CPU 瓶颈,排序、分组、连接查询、聚合统计等SQL会耗费大量的CPU资源,请求数太多,CPU出现瓶颈。
  3. 连接瓶颈:单机连接数限制

1739201101801.png 分为垂直和水平两种核心拆分维度,按拆分粒度分,又分为分库和分表,可两两组合,可能的拆分策略如下图所示。

  • 垂直拆分:按业务模块划分数据
  • 水平拆分:按数据特征分片存储

1739201325477.png

垂直拆分

垂直分库

把所有表按业务领域拆分到不同的数据库,如图所示

1739201933490.png

优势

  • 业务解耦,降低耦合度
  • 隔离故障影响范围
  • 支持按业务特性选择存储引擎

挑战

  • 分布式事务管理
  • 跨库关联查询困难
  • 需要服务层改造

垂直分表

把表按字段拆分成多张表,如下图所示。 1739201871152.png 适用场景

  • 存在大字段(BLOB/TEXT)
  • 高频访问字段与低频字段分离
  • 字段具有明显冷热特征

水平拆分

水平分库

将同一业务数据分布到多个数据库实例

1739202741889.png

水平分表

将单表数据拆分到多个物理表:

1739202756038.png 常见分片策略

策略类型实现方式优点缺点
范围分片按时间或ID区间划分易于扩容,支持范围查询数据分布可能不均匀
哈希取模hash(key) % N数据分布均匀扩容需数据迁移
一致性哈希环形哈希空间平滑扩容,最小化数据迁移实现复杂度高
地理位置按地域划分符合业务特征,降低延迟需要业务适配
基因算法用户ID包含分库分表信息避免跨分片查询ID设计复杂度高

实现技术

以下是主流的一些方案,本文着重介绍使用 Mycat 实现分库分表。

技术方案特点
shardingJDBC基于AOP原理,在应用程序中对本地执行的SQL进行拦截,解析、改写、路由处理。需要自行编码配置实现,只支持java语言,性能较高。
MyCat数据库分库分表中间件,不用调整代码即可实现分库分表,支持多种语言,性能不及前
VitessKubernetes原生,专为MySQL设计

1739206420328.png

MyCat

Mycat是开源的、活跃的、基于Java语言编写的MySQL数据库中间件。可以像使用mysql一样来使用 mycat,对于开发人员来说根本感觉不到mycat的存在。

概念介绍

在 Mycat 的整体结构中,主要分为上下两部分,分别是逻辑结构和物理结构,如下图所示。

1739207302304.png 逻辑结构包含逻辑库、逻辑表、分片规则、分片节点等,但是数据实际上是存在物理结构的节点主机上的。

MyCat 配置

schema.xml

schema.xml 作为MyCat中最重要的配置文件之一 , 涵盖了MyCat的逻辑库 、 逻辑表 、 分片规则、分片节点及数据源的配置。

1739286218138.png 如图所示,主要包含三种标签:

  • schema 标签

    用于配置逻辑数据库、逻辑表,分片规则等,在 Mycat 实例中,可以配置多个逻辑库,逻辑库等同于 Mysql 中 database 的概念,需要操作某个库下的表时,也需要先切换到该库(use xxx)。

    核心属性:

    • name:指定自定义的逻辑库库名

    • checkSQLschema:在SQL语句操作时指定了数据库名称,执行时是否自动去除;true:自动去

      除,false:不自动去除

    • sqlMaxLimit:如果未指定limit进行查询,列表查询模式查询多少条记录

    子标签 table: 定义逻辑库下的逻辑表,所有需要拆分的表都需要在 table 标签中定义,核心属性如下:

    • name:定义逻辑表表名,在该逻辑库下唯一

    • dataNode:定义逻辑表所属的dataNode,该属性需要与dataNode标签中name对应;多个

    • dataNode逗号分隔

    • rule:分片规则的名字,分片规则名字是在rule.xml中定义的

    • primaryKey:逻辑表对应真实表的主键

    • type:逻辑表的类型,目前逻辑表只有全局表和普通表,如果未配置,就是普通表;全局表,配

      置为 global

  • datanode 标签

    用于配置分片节点

    核心属性:

    • name:定义数据节点名称
    • dataHost:数据库实例主机名称,引用自 dataHost 标签中name属性
    • database:定义分片所属数据库
  • datahost 标签

    用于配置物理节点,直接定义了具体的数据库实例、读写分离策略、心跳语句等

    核心属性:

    • name:唯一标识,供上层标签使用

    • maxCon/minCon:最大连接数/最小连接数

    • balance:负载均衡策略,取值 0,1,2,3

    • writeType:写操作分发方式(0:写操作转发到第一个writeHost,第一个挂了,切换到第二

      个;1:写操作随机分发到配置的writeHost)

    • dbDriver:数据库驱动,支持 native、jdbc

rule.xml

rule.xml 中定义了所有的表拆分策略,在使用过程中可灵活配置使用的分片算法,以及可以对分片策略配置相关的参数。主要包含 tableRule 和 function。

1739288963223.png

server.xml

主要包含 Mycat 的系统配置信息,包含 system 和 user 两个重要标签

  • system 标签

    system 下可配置的信息比较多,这里不一一介绍,有需要的可以查阅相关文档。

1739289481797.png user 标签

配置 MyCat 的用户、密码,以及用户对于逻辑库和逻辑表的访问权限,具体说明如下图所示。

1739289761473.png

Mycat 实现分片

这里以 垂直分片 为例,说明如何通过 MyCat 实现分片,水平分片的配置方法相似,这里就不再给出。

背景

由于每天都会产生大量的数据,单台服务器难以支撑,因此需要根据业务将表划分到不同的实例上。

1739290725574.png 划分后的架构图如下:

1739291344227.png

schema.xml 配置

<schema name="SHOPPING" checkSQLschema="true" sqlMaxLimit="100">
    <table name="tb_goods_base" dataNode="dn1" primaryKey="id" />
    <table name="tb_goods_brand" dataNode="dn1" primaryKey="id" />
    <table name="tb_goods_cat" dataNode="dn1" primaryKey="id" />
    <table name="tb_goods_desc" dataNode="dn1" primaryKey="goods_id" />
    <table name="tb_goods_item" dataNode="dn1" primaryKey="id" />
    <table name="tb_order_item" dataNode="dn2" primaryKey="id" />
    <table name="tb_order_master" dataNode="dn2" primaryKey="order_id" />
    <table name="tb_order_pay_log" dataNode="dn2" primaryKey="out_trade_no" />
    <table name="tb_user" dataNode="dn3" primaryKey="id" />
    <table name="tb_user_address" dataNode="dn3" primaryKey="id" />
    <table name="tb_areas_provinces" dataNode="dn3" primaryKey="id"/>
    <table name="tb_areas_city" dataNode="dn3" primaryKey="id"/>
    <table name="tb_areas_region" dataNode="dn3" primaryKey="id"/>
</schema>
​
<dataNode name="dn1" dataHost="dhost1" database="shopping" />
<dataNode name="dn2" dataHost="dhost2" database="shopping" />
<dataNode name="dn3" dataHost="dhost3" database="shopping" />
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="master" url="jdbc:mysql://192.168.200.210:3306?
useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="1234" />
</dataHost>
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="master" url="jdbc:mysql://192.168.200.213:3306?
useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="1234" />
</dataHost>
<dataHost name="dhost3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="master" url="jdbc:mysql://192.168.200.214:3306?
useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="1234" />
</dataHost>

server.xml 配置


<user name="root" defaultAccount="true">
    <property name="password">123456</property>
    <property name="schemas">SHOPPING</property>
    <!-- 表级 DML 权限设置 -->
    <!--
    <privileges check="true">
        <schema name="DB01" dml="0110" >
            <table name="TB_ORDER" dml="1110"></table>
        </schema>
    </privileges>
    -->
</user>
<user name="user">
    <property name="password">123456</property>
    <property name="schemas">SHOPPING</property>
    <property name="readOnly">true</property>
</user>

测试

至此,可以进行测试,例如创建上面定义的表以及插入数据,然后查看数据的分布情况是否符合预期。

这里需要特别说明的是联表查询,执行一下查询语句是可以正确查询的。


select ua.user_id, ua.contact, p.province, c.city, r.area , ua.address from
tb_user_address ua ,tb_areas_city c , tb_areas_provinces p ,tb_areas_region r
where ua.province_id = p.provinceid and ua.city_id = c.cityid and ua.town_id =
r.areaid ;

但如果执行的是以下查询语句,则会报错,这是因为前者查询涉及到的表都在同一个节点上,而后者涉及到了跨节点查询,而 Mycat 在执行查询时,是会把语句路由至具体的节点上执行的,所以导致无法完成该查询。


SELECT order_id , payment ,receiver, province , city , area FROM tb_order_master o
, tb_areas_provinces p , tb_areas_city c , tb_areas_region r WHERE
o.receiver_province = p.provinceid AND o.receiver_city = c.cityid AND
o.receiver_region = r.areaid ;

如何解决呢?这里就要引出全局表的概念了,前面也已经提到过,但是没有具体说明用法。这里通过实操演示会更容易理解。

全局表

当把表配置为 全局表 后,会在 dataNode 属性中指定的所有节点上都创建该表,并且修改也是同步修改的,也就是说,这些节点上都有该表,也就能够访问得到,完成联表查询等操作了。

在本例子中,把 tb_areas_provinces、tb_areas_city、tb_areas_region 等会被其他模块依赖的基础表设置成了全局表(增加 type 属性,配置为globalt)。


<table name="tb_areas_provinces" dataNode="dn1,dn2,dn3" primaryKey="id"
type="global"/>
<table name="tb_areas_city" dataNode="dn1,dn2,dn3" primaryKey="id"
type="global"/>
<table name="tb_areas_region" dataNode="dn1,dn2,dn3" primaryKey="id"
type="global"/>

配置完成后重启 MyCat ,删除原来的表并且重新创建,重试前面的查询语句发现可以正确执行,同时可以发现,每个节

点的全局表数据时刻保持一致。

分片策略

MyCat 有多种分片策略供配置,以下介绍一些常用的策略。

策略适用场景优点缺点
范围分片递增数据、范围查询管理简单数据可能倾斜
取模分片均匀分布、无状态业务负载均衡扩容复杂
一致性哈希动态扩缩容扩容影响小配置复杂
枚举分片业务分类明确查询高效扩展性差
应用指定算法高度定制化需求完全灵活侵入业务
固定分片哈希可控哈希分布扩容灵活配置复杂
字符串哈希字符串主键支持非数值字段哈希冲突风险
按天/自然月分片时间序列数据时间范围查询快分片数量增长快

范围分片

  • 原理根据某个字段的数值范围(如 ID、时间戳)将数据分配到不同分片。例如:

    • 分片1:1~1000
    • 分片2:1001~2000
  • 适用场景适合按时间范围查询、数值递增且分布均匀的场景(如订单按月份归档)。

  • 优缺点

    • 优点:支持快速范围查询,管理简单。
    • 缺点:数据分布可能不均,存在热点风险(如新数据集中在最新分片)。

1739374237059.png

取模分片

  • 原理对分片字段值取模(hash(field) % 分片数),将数据均匀分布到各分片。

  • 适用场景数据分布需高度均匀的场景(如用户表、无状态业务)。

  • 优缺点

    • 优点:数据分布均衡,查询效率高。
    • 缺点:扩容困难(需重新哈希),无法直接范围查询。

1739374317861.png 一致性hash分片

  • 原理使用一致性哈希环,将数据和分片节点映射到环上,通过顺时针查找分配数据。相同的哈希因子计算值总是被划分到相同的分区表中,不会因为分区节点的增加而改变原来数据的分区位置,有效的解决了分布式数据的拓容问题。

  • 适用场景分片节点可能动态增减的场景(如云环境)。

  • 优缺点

    • 优点:扩容时数据迁移量小,负载均衡较好。
    • 缺点:配置复杂,查询性能略低于取模

枚举分片

  • 原理根据字段的枚举值(如地区、类型)直接映射到指定分片。

  • 适用场景业务有明显分类属性的数据(如按省份存储用户)。

  • 优缺点

    • 优点:灵活匹配业务分类,查询效率高。
    • 缺点:需提前预定义枚举值,扩展性差。

应用指定算法

  • 原理由应用程序在 SQL 中显式指定分片(如通过注解或 Hint)。

  • 配置方式在 SQL 中添加分片路由信息,例如:

    
    /*!mycat: schema=shard1 */ SELECT * FROM table;
    
  • 适用场景需要完全由业务逻辑控制分片的场景(如多租户隔离)。

  • 优缺点

    • 优点:灵活性极高,可定制复杂规则。
    • 缺点:需侵入业务代码,维护成本高。

固定分片hash算法

  • 原理将分片字段的哈希值划分为固定区间,每个区间对应一个分片。例如:哈希值范围 0511 分片1,5121023 分片2。

  • 适用场景需要平衡数据分布且避免扩容问题的场景。

  • 优缺点

    • 优点:数据分布可控,扩容时可通过调整区间实现。
    • 缺点:配置复杂,需预先规划区间

字符串 hash 解析算法

  • 原理对字符串字段(如用户名)进行哈希(如 CRC32、MD5),再取模分片。

  • 适用场景以字符串为主键或查询条件的表(如用户名、邮箱)。

  • 优缺点

    • 优点:支持字符串字段分片,分布较均匀。
    • 缺点:哈希冲突可能导致数据倾斜。

按天分片算法

  • 原理根据日期字段(如创建时间)按天分片,每天数据存入独立分片,按日期循环选择分片。

  • 适用场景时间序列数据(如日志、监控数据)。

  • 优缺点

    • 优点:按时间范围查询高效,易于冷热数据分离。
    • 缺点:分片数量随时间线性增长,需定期归档

自然月分片

  • 原理按自然月分片,每月数据存入一个分片(如 202301202302)。

  • 配置方式类似按天分片,但日期格式为 yyyyMM

  • 适用场景按月统计的业务(如财务报表、月度订单)。

  • 优缺点

    • 优点:便于月度聚合查询,管理简单。
    • 缺点:单月数据量过大时可能性能下降。

MyCat 管理及监控

MyCat 原理

1739377938830.png 在 MyCat 中,当执行一条 SQL 语句时,MyCat 需要进行 SQL 解析、分片分析、路由分析、读写分离分析

等操作,最终经过一系列的分析决定将当前的 SQL 语句到底路由到那几个(或哪一个)节点数据库,数据

库将数据执行完毕后,如果有返回的结果,则将结果返回给 MyCat,最终还需要在MyCat中进行结果合

并、聚合处理、排序处理、分页处理等操作,最终再将结果返回给客户端。

Mycat 默认开通 2 个端口,可以在 server.xml 中进行修改。

  • 8066 :数据访问端口,即进行 DML 和 DDL 操作。
  • 9066 :数据库管理端口,即 mycat 服务管理控制功能,用于管理 mycat 的整个集群状态以及可监控一些信息

连接MyCat的管理控制台:

mysql -h 192.168.200.210 -p 9066 -uroot -p123456

这里的管理监控是基于命令行操作的,操作相对繁琐,MyCat 官方也提供了一个管理监控平台MyCat-Web(MyCat-eye)。Mycat-web 是 Mycat 可视化运维的管理和监控平台,弥补了 Mycat 在监控上的空白。帮 Mycat 分担统计任务和配置管理任务。Mycat-web 引入了 ZooKeeper 作为配置中心,可以管理多个节点。Mycat-web 主要管理和监控 Mycat 的流量、连接、活动线程和内存等,具备 IP 白名单、邮件告警等模块,还可以统计 SQL 并分析慢 SQL 和高频 SQL 等。为优化 SQL 提供依据。

MyCat-eye

Mycat-web(Mycat-eye)是对mycat-server提供可视化界面监控服务,功能不局限于对mycat-server使用。他通过JDBC连接对Mycat、Mysql监控,监控远程服务器(目前仅限于linux系统)的cpu、内存、网络、磁盘。

Mycat-eye运行过程中需要依赖 zookeeper,因此需要先安装 zookeeper,安装步骤及使用方法这里就不进行阐述了,可自行查找相关文档。

读写分离

概述

读写分离指的是将读与写请求分发到不同的数据库实例进行处理,减少单台服务器的压力,提高整体吞吐量。读写分离是建立在主从结构之上的,主库负责写,从库负责读。

Mycat 支持读写分离配置,而且可支持 Mysql、Oracle 等多种数据库。

一主一从

先介绍简单的基于一主一从架构的读写分离的配置方法,对于主从复制的配置,可以参考前面 【主从复制】章节,这里不重复阐述,假设已经配置好了主从复制,接下来继续完成配置

schema.xml 核心配置如下:

<!-- 配置逻辑库 -->
<schema name="ITCAST_RW" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn7">
</schema>
<dataNode name="dn7" dataHost="dhost7" database="itcast" /><dataHost name="dhost7" maxCon="1000" minCon="10" balance="1" writeType="0"
dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    
    <writeHost host="master1" url="jdbc:mysql://192.168.200.211:3306?
    useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="1234" >
 
        <readHost host="slave1" url="jdbc:mysql://192.168.200.212:3306?
        useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="1234" />
​
    </writeHost>
</dataHost>

其中,writeHost 用于指定写操作对应的数据库(配置为主库),readHost 用于指定读操作对应的数据库(配置为从库)。

此外,至关重要的配置是 dataHost 标签的 balance 属性,可配置值及含义如下:

参数值含义
0不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。
1全部的 readHost 与备用的 writeHost 都参与 SELECT 语句的负载均衡(主要针对双主双从模式)。
2所有的读写操作都随机在 writeHostreadHost 上分发。
3所有的读请求随机分发到 writeHost 对应的 readHost 上执行,writeHost 不负担读压力。

我们这里配置为 3 即可,由于我们是一主一从,所以配置为 1 也是同样的效果。

配置完重启 MyCat 即可实现读写分离。

但是,这种架构过于简单,试想一下,如果主节点崩了话,是不是就无法处理写请求,只能读了?

答案是肯定的,下面将介绍适合生产环境的 双主双从 架构。

双主双从

大致架构如图所示。由 m1 负责处理写操作,而 m2、s1、s2 均处理读请求。当 m1 不可用时,会自动切换为由 m2 处理写操作。在这种架构中,不光需要配置 s1 s2 分别为 m1 m2 的从库,同时也需要配置 m1 m2 互为对方的从库。对于主从库的配置,这里不再赘述,只介绍读写分离的配置。

1739461772847.png

schema.xml 核心配置如下:

<dataHost name="dhost7" maxCon="1000" minCon="10" balance="1" writeType="0"
dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="master1" url="jdbc:mysql://192.168.200.211:3306?
    useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="1234" >
        <readHost host="slave1" url="jdbc:mysql://192.168.200.212:3306?
        useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="1234" />
    </writeHost>
    <writeHost host="master2" url="jdbc:mysql://192.168.200.213:3306?
    useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="1234" >
        <readHost host="slave2" url="jdbc:mysql://192.168.200.214:3306?
        useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="1234" />
    </writeHost>
</dataHost>

主要配置说明:

  • balance

    代表全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),正常情况下,M2,S1,S2 都参与 select 语句的负载均衡

  • writeType

    0 : 写操作都转发到第1台writeHost, writeHost1挂了, 会切换到writeHost2上;

    1 : 所有的写操作都随机地发送到配置的writeHost上 ;

  • switchType

    -1 : 不自动切换

    1 : 自动切换

配置完后重启 MyCat 即可,可以尝试关闭一个主库后,观察是否能够自动切换。

总结

MySQL高可用架构通过主从复制实现数据同步与读写分离,利用分库分表(垂直拆分按业务解耦、水平拆分按数据分片)突破单机性能瓶颈,配合MyCat等中间件实现智能路由与负载均衡,结合双主双从架构保障故障自动切换,最终构建出支持海量数据、高并发访问且具备容灾能力的分布式数据库体系,有效解决了存储扩展、性能优化和业务连续性三大核心挑战。

项目推荐

推荐一个可用于练手、毕业设计参考、增加简历亮点的项目。

参考项目:lemon-puls/txing-oj-backend: Txing 在线编程学习平台,集在线做题、编程竞赛、即时通讯、文章创作、视频教程、技术论坛为一体