Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL 读写分离与分库分表

MySQL之读写分离与分库分表

作者:bksczm

本文基于ShardingSphere详解MySQL读写分离与分库分表核心实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

 一、ShardingSphere 定位

ShardingSphere-Proxy 对应用层伪装成一个 MySQL 服务(默认端口 3307)。应用把它当成一个普通 MySQL 连接,SQL 全部发给它,由它负责:

它的角色和之前讲的"网关服务器"一致:一个无状态的 SQL 路由/负载均衡层。

二、读写分离

2.1 读写分离的思想

ShardingSphere 负责把 SQL 按类型分流,应用无需关心主从地址。

2.2 配置文件config-readwrite-splitting.yaml(逐行注释)

# ─────────────────────────────────────────────────────
# 逻辑数据库名:应用连接 Proxy 后 USE 的库名,由 Proxy 虚拟出来
# ─────────────────────────────────────────────────────
databaseName: readwrite_splitting_db
# ─────────────────────────────────────────────────────
# dataSources:声明所有「真实 MySQL 实例」的连接池
# ─────────────────────────────────────────────────────
dataSources:
  write_ds:                                          # 自定义数据源名(主库/写库)
    url: jdbc:mysql://127.0.0.1:3306/test_db?        # JDBC 地址:协议://IP:端口/库名
         characterEncoding=utf8&                     # 连接字符编码
         serverTimezone=Asia/Shanghai&               # 时区
         allowPublicKeyRetrieval=true&               # 8.0 允许获取公钥
         useSSL=false                                # 内网关闭 SSL
    username: root                                   # 连接用户名
    password: 'xxxxxxxxxxxxxx'                       # 密码(含 @、. 等特殊字符必须加引号)
    connectionTimeoutMilliseconds: 30000             # 建立连接超时(毫秒)
    idleTimeoutMilliseconds: 60000                   # 空闲连接回收时间(毫秒)
    maxLifetimeMilliseconds: 1800000                 # 连接最大存活时间(30 分钟)
    maxPoolSize: 50                                  # 连接池最大连接数
    minPoolSize: 1                                   # 连接池最小空闲连接数
  read_ds_0:                                         # 从库 1(容器映射端口 53307)
    url: jdbc:mysql://127.0.0.1:53307/test_db?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
    username: backup
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  read_ds_1:                                         # 从库 2(容器映射端口 53308,不能与从库1重复)
    url: jdbc:mysql://127.0.0.1:53308/test_db?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
    username: backup
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
# ─────────────────────────────────────────────────────
# rules:规则区(读写分离、分片、加密等可叠加)
# ─────────────────────────────────────────────────────
rules:
  - !READWRITE_SPLITTING                             # 声明:读写分离规则
    dataSources:
      readwrite_ds:                                  # 逻辑读写分离数据源名(对外引用)
        staticStrategy:                              # 静态策略:主从角色固定
          writeDataSourceName: write_ds              # 写请求 → write_ds
          readDataSourceNames:                       # 读请求 → 从下面列表中选
            - read_ds_0
            - read_ds_1
          loadBalancerName: random                   # 引用负载均衡算法
    loadBalancers:                                   # 负载均衡算法定义区
      random:                                        # 算法名(与上面对应)
        type: RANDOM                                 
    # 类型:RANDOM / ROUND_ROBIN / WEIGHT

⚠️ YAML 格式红线:全部用空格缩进,禁止 Tab;每层 2 个空格;冒号后面必须有一个空格。内容一样却报错时,十有八九是格式问题,建议手敲一遍。

JDBC URL 各段含义

jdbc:mysql://127.0.0.1:3306/test_db?characterEncoding=utf8&serverTimezone=...
└──┬──┘ └──┬──┘ └────┬────┘ └─┬─┘ └─┬──┘ └──────────┬───────────────┘
 协议      子协议      主机IP    端口   库名           连接参数

2.3 负载均衡算法

算法含义适用
ROUND_ROBIN轮询,读请求依次分给各从库机器性能相同,最常用
RANDOM随机配置简单
WEIGHT按权重比例分发从库性能不同

WEIGHT 配置示例:

    loadBalancers:
      weight:
        type: WEIGHT
        props:
          read_ds_0: 2.0
          read_ds_1: 1.0

表示总体上按 2:1 分配(不是"先给 0 发两条、再给 1 发一条")。

2.4 连接与测试

# 连接 ShardingSphere-Proxy(注意是 3307,不是 3306;-h 小写)
mysql -h 127.0.0.1 -P 3307 -uroot -p

另开一个终端监控日志:

tail -f logs/stdout.log

验证:

2.5主从延迟问题

异步复制下,刚写入主库的数据可能还没同步到从库,此时读从库会读到旧数据。处理策略:

三、分库分表核心概念

ShardingSphere 把分库分表统称为分片(Sharding)。

3.1 垂直分库

一个库里表太多、业务太杂,按业务关联性拆库,部署到不同服务器:

3.2 垂直分表

一个表字段太多、存在大字段(如商品描述 TEXT),把不常用大字段拆成 1:1 扩展表:

3.3 水平分表

表行数太多,按分片键 + 算法把数据行拆到多张结构相同的表:

3.4 水平分库

把数据行拆到不同服务器上的同名库:

3.5 四种方式对比

方式拆分对象是否扩容解决问题
垂直分库按业务拆库是业务耦合、整体压力
垂直分表拆字段否大字段、行过大
水平分表拆数据行否单表行数过多
水平分库拆数据行到不同机器是单表大 + 容量

分库基本针对服务器层面;分表常在单服务器内操作。

四、垂直分库配置

config-sharding.yaml:

databaseName: sharding_db
dataSources:
  server_user:
    url: jdbc:mysql://127.0.0.1:3306/test_db_id?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: '@Czm388512369.'
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  server_order:
    url: jdbc:mysql://192.168.80.138:53311/test_db_desc?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: backup
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
rules:
  - !SHARDING
    tables:
      user:                                        # 逻辑表名称(自定义)
        actualDataNodes: server_user.t_user        # 数据源名.真实表名
      order:
        actualDataNodes: server_order.t_order

只在读写分离文件里配多个写库也能"间接"实现垂直分库,参考附录!!!,但 SHARDING 规则提供了自动路由、分片算法、绑定表、主键生成等完整能力,生产应在分片规则中做(或两条规则叠加,见第九章)。

五、水平分片配置(包括bind、broadcast、keygenerator)

假设:先按 user_id 分库(2 个库),再按 goods_id 分表(每个库 2 张表),共 4 个真实节点。

5.1 建真实表

-- 实例0(test_db_id0)
CREATE DATABASE IF NOT EXISTS test_db_id0;
USE test_db_id0;
CREATE TABLE IF NOT EXISTS goods_id_gd0 (id INT PRIMARY KEY, user_id INT NOT NULL, goods_id VARCHAR(20) NOT NULL);
CREATE TABLE IF NOT EXISTS goods_id_gd1 (id INT PRIMARY KEY, user_id INT NOT NULL, goods_id VARCHAR(20) NOT NULL);
-- 实例1(test_db_id1)
CREATE DATABASE IF NOT EXISTS test_db_id1;
USE test_db_id1;
CREATE TABLE IF NOT EXISTS goods_id_gd0 (id INT PRIMARY KEY, user_id INT NOT NULL, goods_id VARCHAR(20) NOT NULL);
CREATE TABLE IF NOT EXISTS goods_id_gd1 (id INT PRIMARY KEY, user_id INT NOT NULL, goods_id VARCHAR(20) NOT NULL);

5.2 完整配置与逐行注释

databaseName: sharding_db                            # 逻辑库名
dataSources:
  server_user0:                                      # 物理数据源 0
    url: jdbc:mysql://127.0.0.1:3306/test_db_id0?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: '@Czm388512369.'
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  server_user1:                                      # 物理数据源 1
    url: jdbc:mysql://192.168.80.138:53311/test_db_id1?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: backup
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
rules:
  - !SHARDING
    tables:
      t_goods:                                       # 逻辑表名(应用 SQL 里写的表名)
        # 行表达式,展开后是 4 个真实节点:
        # server_user0.goods_id_gd0 / server_user0.goods_id_gd1
        # server_user1.goods_id_gd0 / server_user1.goods_id_gd1
        actualDataNodes: server_user${0..1}.goods_id_gd${0..1}
        databaseStrategy:                            # 分库策略(选库)
          standard:                                  # 标准分片:单分片键,支持 =、IN、范围
            shardingColumn: user_id                  # 分片键
            shardingAlgorithmName: alg_mod           # 引用算法
        tableStrategy:                               # 分表策略(选表)
          standard:
            shardingColumn: goods_id
            shardingAlgorithmName: alg_hash_mod
        keyGenerateStrategy:                         # 分布式主键
          column: id
          keyGeneratorName: snowflake
    bindingTables:                                   # 绑定表
      - t_goods,t_goods_item
    broadcastTables:                                 # 广播表
      - t_dict
    shardingAlgorithms:                              # 分片算法定义
      alg_mod:
        type: MOD                                    # 取模(分片键须为数值)
        props:
          sharding-count: 2                          # 分片值 % 2
      alg_hash_mod:
        type: HASH_MOD                               # 先哈希再取模(字符串也能用)
        props:
          sharding-count: 2
      alg_inline:
        type: INLINE                                 # 行表达式
        props:
          algorithm-expression: server_user${user_id % 2}
    keyGenerators:
      snowflake:
        type: SNOWFLAKE
        props:
          worker-id: 1

5.3 行表达式

5.4 分片策略

策略适用场景
STANDARD单分片键,处理精确(=、IN)和范围(>、<、BETWEEN)
COMPLEX多分片键
HINT不依赖 SQL,代码手动指定路由
NONE不强制

5.5 分片算法

算法说明
MOD分片值直接取模(数值)
HASH_MOD先哈希再取模(字符串可用)
INLINEGroovy 表达式,最灵活
INTERVAL按时间区间(按月/天)
BOUNDARY_RANGE / VOLUME_RANGE按范围/容量
CLASS自定义算法类

六、绑定表(bind)完整场景

6.1 构造场景

t_order 和 t_order_item 都按 order_id 分 2 个库(偶数→ds0,奇数→ds1)。

这样子做也能够确保有关数据在同一个库中,避免跨库事务

ds0:

-- t_order
order_id=100 user_id=1 amount=100
order_id=102 user_id=2 amount=200
-- t_order_item
item_id=1 order_id=100 goods='手机'
item_id=2 order_id=100 goods='耳机'
item_id=3 order_id=102 goods='电脑'

ds1:

-- t_order
order_id=101 user_id=3 amount=50
order_id=103 user_id=4 amount=80
-- t_order_item
item_id=4 order_id=101 goods='书'
item_id=5 order_id=103 goods='键盘'

全量关联查询:

SELECT o.order_id, i.goods
FROM t_order o
JOIN t_order_item i ON o.order_id = i.order_id;

6.2 没有配置 bindingTables(笛卡尔积路由)

Proxy 不知道两表分片规则相同,把路由集合做笛卡尔积:t_order 集合 {ds0,ds1} × t_order_item 集合 {ds0,ds1} = 4 条 SQL:

编号位置结果
①ds0.t_order × ds0.t_order_item有效本地 JOIN
②ds1.t_order × ds1.t_order_item有效本地 JOIN
③ds0 × ds1跨库 JOIN,MySQL 无法执行,数据拉到内存归并
④ds1 × ds0跨库 JOIN,MySQL 无法执行,数据拉到内存归并

带 WHERE o.order_id=100 时:t_order 能确定到 ds0,但 t_order_item 未被声明绑定,仍向 ds0、ds1 都发,产生 2 条 SQL(ds1 白跑)。

6.3 配置绑定表后

    bindingTables:
      - t_order,t_order_item

Proxy 知道同一 order_id 的订单和明细必在同一节点:

6.4 对比

情形全量 JOIN带 order_id=100跨库 JOIN
未绑定4 条(2×2)2 条有,内存归并
绑定2 条(本地)1 条(精确)无

七、广播表完整场景

本质上就是在每一个库中都备份一个相同的表,以避免跨库事务

7.1 构造场景

t_dict 是订单状态字典表(5 行,几乎不变),t_order 是分片表:

status_code=1 status_name='待支付'
status_code=2 status_name='已支付'
status_code=3 status_name='已发货'
status_code=4 status_name='已完成'

查询:

SELECT o.order_id, d.status_name
FROM t_order o JOIN t_dict d ON o.status = d.status_code;

7.2 没有广播表(字典只在 ds0)

7.3 配置广播表后

    broadcastTables:
      - t_dict

7.4 选用条件

特征说明
数据量小全量副本,太大浪费存储
读多写少写要广播,写频繁成本高
经常被 JOIN/查询广播收益就在本地 JOIN
一致性要求高Proxy 自动维护副本一致

典型:字典表、配置表、地区表。

八、统一序列号(分布式主键)

8.1 为什么分库分表后需要

分库/分表后,每个库各自自增,会产生重复主键(库 0 和库 1 都从 1 开始),因此必须有全局唯一 ID 方案。

8.2 雪花算法(Snowflake,ShardingSphere 默认)

64 位 long 型 ID,分四段:

 1 bit     41 bit 时间戳        10 bit 工作机器        12 bit 序列号
┌──┬────────────────────┬────────────────┬──────────────────┐
│ 0│   毫秒级时间戳       │ 5位数据中心+5位机器│ 同毫秒内自增序列   │
└──┴────────────────────┴────────────────┴──────────────────┘

优点:本地生成无网络开销、性能高、整体趋势递增(对 B+ 树索引友好)。

8.3 时钟回拨

机器时钟因 NTP 校时往回拨时可能生成重复 ID。(这也要求了我们不能够轻易更换时区)

处理:记录上次时间戳,回拨很小则等待追上,回拨较大则报错拒绝。

8.4 其他方案

方案优缺点
UUID简单但无序、太长,B+ 树插入性能差
数据库号段(美团 Leaf)批量取号,压力小
Redis INCR简单高性能,依赖 Redis 高可用
百度 UidGenerator雪花变种 + RingBuffer,极高性能

8.5 配置

        keyGenerateStrategy:
          column: id
          keyGeneratorName: snowflake
    keyGenerators:
      snowflake:
        type: SNOWFLAKE
        props:
          worker-id: 1

插入时不指定 id,Proxy 自动填充雪花 ID。

九、读写分离 + 多集群垂直分库(其余组合可以参考)

9.1 架构形态

多个业务集群,每个集群内部是一主多从的读写分离,集群之间是垂直分库:

                    ShardingSphere-Proxy :3307(逻辑库 mall_db)
                                  │
          ┌───────────────────────┴───────────────────────┐
          ▼                                                 ▼
   用户库集群 user_ds                                  订单库集群 order_ds
   ├─ user_master  写  3306                            ├─ order_master 写  53311
   ├─ user_slave0  读  53307                           └─ order_slave0 读  53312
   └─ user_slave1  读  53308
          │                                                 │
   t_user / t_user_log                                 t_order / t_order_item
                                                       t_goods / t_goods_desc(垂直分表)

核心思路:先用 READWRITE_SPLITTING 把每个集群的物理主从封装成一个逻辑数据源(user_ds、order_ds),再用 SHARDING 的 actualDataNodes 引用这些逻辑数据源——两条规则叠加,路由两层级联。

9.2 完整配置

databaseName: mall_db
dataSources:
  # ───── 用户库集群(一主两从) ─────
  user_master:
    url: jdbc:mysql://127.0.0.1:3306/db_user?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: '123456'
  user_slave0:
    url: jdbc:mysql://127.0.0.1:53307/db_user?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: '123456'
  user_slave1:
    url: jdbc:mysql://127.0.0.1:53308/db_user?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: '123456'
  # ───── 订单库集群(一主一从) ─────
  order_master:
    url: jdbc:mysql://127.0.0.1:53311/db_order?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: '123456'
  order_slave0:
    url: jdbc:mysql://127.0.0.1:53312/db_order?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: '123456'
rules:
  # ════════ 规则 1:读写分离(把每个集群封装成逻辑数据源) ════════
  - !READWRITE_SPLITTING
    dataSources:
      user_ds:                                         # 用户库集群逻辑数据源
        staticStrategy:
          writeDataSourceName: user_master
          readDataSourceNames:
            - user_slave0
            - user_slave1
        loadBalancerName: round_robin
      order_ds:                                        # 订单库集群逻辑数据源
        staticStrategy:
          writeDataSourceName: order_master
          readDataSourceNames:
            - order_slave0
        loadBalancerName: round_robin
    loadBalancers:
      round_robin:
        type: ROUND_ROBIN
  # ════════ 规则 2:垂直分库(逻辑表 → 逻辑数据源) ════════
  - !SHARDING
    tables:
      # 用户域的表全部落在用户库集群
      t_user:
        actualDataNodes: user_ds.t_user
      t_user_log:
        actualDataNodes: user_ds.t_user_log
      # 订单域的表全部落在订单库集群
      t_order:
        actualDataNodes: order_ds.t_order
      t_order_item:
        actualDataNodes: order_ds.t_order_item
      # 垂直分表:商品主表与大字段扩展表(1:1),都在订单库集群
      t_goods:
        actualDataNodes: order_ds.t_goods
      t_goods_desc:
        actualDataNodes: order_ds.t_goods_desc
    bindingTables:
      - t_order,t_order_item
    broadcastTables:
      - t_dict

9.3 路由验证

SQL路由过程实际节点
INSERT INTO t_user ...分片→user_ds;读写分离→主user_master:3306
SELECT * FROM t_user ...分片→user_ds;读写分离→从(轮询)user_slave0:53307
INSERT INTO t_order ...分片→order_ds;读写分离→主order_master:53311
SELECT * FROM t_order ...分片→order_ds;读写分离→从order_slave0:53312
SELECT * FROM t_dict广播表,任意节点随机节点

两级路由:先由 SHARDING 决定"去哪个业务集群",再由 READWRITE_SPLITTING 决定"走该集群的主还是从"。

9.4 关于垂直分表

垂直分表是同一个库内把大字段拆成 1:1 扩展表(如 t_goods 拆出 t_goods_desc),物理上就是两张独立表,不需要分片算法,在同一数据源下分别声明即可(见 9.2);应用层按需查询或用 goods_id 关联。若以后还要水平拆分,再为它们配置相同分片键并加入 bindingTables。

十、CAP 理论

10.1 三要素

要素含义
C:一致性所有节点同一时刻看到相同数据,读总返回最新写入
A:可用性每个非故障节点的请求都能在有限时间内得到响应
P:分区容错性网络分区(中断/丢消息)时系统仍能工作

10.2 为什么 P 必选

网络分区不可避免,无法选择"不要 P"。实际权衡是分区发生时要 C 还是 A:

10.3 典型系统

类型系统
CPZooKeeper、etcd、HBase、MongoDB(默认)
APCassandra、Dynamo、Eureka、Redis Cluster

对应学过的组件:

CAP 不是简单"三选二":无分区时 C 和 A 可同时满足,只有分区期间才需取舍。

10.4 BASE 理论(AP 的实践)

十一、分库分表带来的其他问题

问题解决思路
分布式事务XA(2PC,偏 CP)、Saga(柔性事务,最终一致);ShardingSphere 均支持
跨库 JOIN绑定表、广播表、字段冗余、应用层组装
跨库分页/排序各节点取数后 Proxy 归并(深分页代价大)
全局唯一 ID雪花算法等
扩容成倍扩容 + 数据迁移,或一致性哈希
聚合函数各节点部分聚合后 Proxy 归并

十二.附录(只利用读写分离实现垂直分库)

databaseName: readwrite_splitting_db

dataSources:
  write_ds_0:
    url: jdbc:mysql://127.0.0.1:3306/test_db_id?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
    username: root
    password: '@Czm388512369.'
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  write_ds_1:
    url: jdbc:mysql://127.0.0.1:53306/test_db_desc?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
    username: backup
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  read_ds_0:
    url: jdbc:mysql://127.0.0.1:53307/test_db_id?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
    username: backup
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  read_ds_1:
    url: jdbc:mysql://127.0.0.1:53308/test_db_desc?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false
    username: backup
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1

rules:
- !READWRITE_SPLITTING
  dataSources:
    readwrite_ds_0:
      staticStrategy:
        writeDataSourceName: write_ds_0
        readDataSourceNames:
          - read_ds_0
      loadBalancerName: round_robin
    readwrite_ds_1:
      staticStrategy:
        writeDataSourceName: write_ds_1
        readDataSourceNames:
          - read_ds_1
      loadBalancerName: round_robin
  loadBalancers:
    round_robin:
      type: ROUND_ROBIN
维度当前方案:多套独立读写分离分片模式:垂直分库 + 读写分离
应用视角应用感知多个逻辑库,不同业务表需要切换不同库执行应用只看到一个统一逻辑库,所有表都在这个库下,完全不感知底层拆分
跨库关联完全不支持跨逻辑库 JOIN,应用必须自己拆两次查询再拼装支持跨分片的关联查询(由 Proxy 自动改写、分发、归并),应用可以正常写 JOIN
事务支持跨库事务需要应用自行处理分布式事务同一个逻辑库内,内置支持 XA、Seata 等分布式事务模式
后续扩展某张表要做水平分片时,需要整体重构配置,改动成本高本身就在分片体系内,给单张表加水平分片策略即可,架构平滑演进
配置复杂度简单直观,规则少,排错容易配置层级多,分片算法、路由策略复杂,排错成本高

这个方法大多数场景下没有分片模式好,但是也可以了解一下(博主自己突发奇想的)

到此这篇关于MySQL之读写分离与分库分表的文章就介绍到这了,更多相关MySQL 读写分离与分库分表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文