Logo
弹性伸缩

弹性伸缩 #

随着业务快速发展,分布式数据库方案可能将再次面临数据存储容量的问题,因此,弹性扩缩容是分布式架构不可或缺的能力。

概述 #

SphereEx-DBPlusEngine 弹性伸缩插件可以实现同构存储节点在线地扩容或缩容,同时支持新旧环境的数据比对。

目前 SphereEx-DBPlusEngine 弹性伸缩插件所支持的数据库产品为 MySQL、PostgreSQL 和 openGauss,具体版本、环境要求和权限要求如下。

数据库
版本支持
环境要求
权限要求
1MySQL5.1.15 ~ 8.xmy.cnf 配置
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-format=row
binlog-row-image=full
–确认命令如下
show variables like ‘%log_bin%’;
show variables like ‘%binlog%’;
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON . TO ${username}@${host}
–确认命令如下
SHOW GRANTS FOR ‘user’;
2PostgreSQL9.4 或以上版本postgresql.conf 配置:
wal_level = logical
max_wal_senders = 10
max_replication_slots = 10
max_connections = 600
pg_hba.conf 配置:
host replication repl_acct 0.0.0.0/0 md5
3openGauss2.0.1 ~ 3.0.0postgresql.conf 配置:
wal_level = logical
max_wal_senders = 10
max_replication_slots = 10
max_connections = 600
pg_hba.conf 配置:
host replication repl_acct 0.0.0.0/0 md5

在作业执行过程中,SphereEx-DBPlusEngine 能够根据集群资源情况及进行合理地调度,尽可能提高整体资源利用率,避免资源争夺,从而保证作业执行效率。同时也支持任务的自动故障转移,给长时间运行的任务提供必要保障。

基本概念 #

  • 节点

指运行计算层或存储层进程的实例,可以是物理机、虚拟机、容器等。

  • 集群

为了提供特定服务而集合在一起的多个节点。

  • 扩缩容作业

把数据存储扩容或缩容的完整流程。

  • 存量数据

在扩缩容作业开始前,数据节点中已存在的数据。

  • 增量数据

在扩缩容作业执行过程中,业务系统所产生的新数据。

适用场景 #

  • 存储节点扩容,应对存储节点容量或连接数不足的场景;
  • 存储节点缩容,减少存储节点、提升资源利用率的场景。

使用前提 #

  • 已完成 SphereEx-DBPlusEngine 和新增数据库节点部署,网络通畅且服务正常。
  • 扩缩容作业流程中需要依赖 Zookeeper,需提前完成部署。
  • 当前已使用 SphereEx-DBPlusEngine 数据分片架构,且扩缩容节点与当前存储节点为同构、同版本数据库。
  • 因扩缩容过程中存储节点会保留两版本分片数据,请务必确保物理存储空间为当前数据文件的两倍以上。
  • 在追加增量数据阶段,请务必确保数据库日志不能被清除。
  • 扩缩容后需要对数据进行一致性校验,该阶段需要窗口时间,需提前规划。

使用限制 #

支持项 #

  • 支持任意索引结构的表。

不支持项 #

  • 不支持操作无主键且无唯一键的表;
  • 不支持目标端 proxy 使用 HINT 分片策略;
  • 源端表结构变更不会自动同步。

注意事项 #

  1. 在存量和增量扩缩容的阶段,可在线进行数据传输,对业务无影响。而流量切换阶段,需要一定窗口时间,来确保源端和目标端数据已追平,该阶段需要短暂的停止业务。

  2. 目前 mode 必须是 Cluster,需要提前启动对应的注册中心。

配置示例:

mode:
  type: Cluster
  repository:
    type: ZooKeeper
    props:
      namespace: governance_ds
      server-lists: localhost:2181
      retryIntervalMilliseconds: 500
      timeToLiveSeconds: 60
      maxRetries: 3
      operationTimeoutMilliseconds: 500

原理介绍 #

分片算法和使用方式满足条件的情况下,可以做到高效扩缩容,不需要移动数据或者只移动少量数据。

SphereEx-DBPlusEngine 弹性伸缩插件同样是通过 4 个阶段:准备阶段、存量数据扩缩容阶段、增量数据同步阶段及流量切换阶段。

  1. 准备阶段

在准备阶段,扩缩容模块会进行数据源连通性及权限的校验,同时进行存量数据的统计、日志位点的记录,最后根据数据量和用户设置的并行度,对任务进行分片。

  1. 存量数据扩缩容阶段

执行在准备阶段拆分好的存量数据扩缩容任务,存量数据扩缩容阶段采用 JDBC 查询的方式,直接从源端读取数据,基于配置的分片等规则写入到目标端。

  1. 增量数据同步阶段

由于存量扩缩容耗费的时间受到数据量和并行度等因素影响,此时需要对这段时间内业务新增的数据进行同步。 不同的数据库使用的技术细节不同,但总体上均为基于复制协议或 WAL 日志实现的变更数据捕获功能。

  • MySQL:订阅并解析 binlog;
  • PostgreSQL:采用官方逻辑复制 test_decoding。

这些捕获的增量数据,同样会由扩缩容模块写入到新数据节点中。当增量数据基本同步完成时(由于业务系统未停止,增量数据是不断的),则进入流量切换阶段。

  1. 流量切换阶段

在此阶段,可能存在一定时间的业务只读窗口期,通过 SphereEx-DBPlusEngine 的停写功能或者设置数据库只读、控制源头写流量等方式,让源端数据节点中的数据短暂静态,确保增量同步完全完成。

这个只读窗口期时长取决于用户是否需要对数据进行一致性校验以及数据量。一致性校验是独立的任务,支持单独启停,支持断点续传。

确认完成后,扩缩容完成。 然后用户可以把读流量或者写流量切换到 SphereEx-DBPlusEngine。

使用指南 #

  1. 制定分片策略

在弹性伸缩开始前,需要结合业务制定合理的分片策略,相关内容请参考数据分片

  1. 优化弹性伸缩配置(可选)

SphereEx-DBPlusEngine 提供了弹性伸缩的优化配置,可对数据抽取及数据写入的线程进行控制。在资源充沛的情况下,可最大限度使用资源,高效完成扩缩容作业。同时,为了尽量减少对业务系统的影响,也可对扩缩容流量进行限制。

  1. 数据一致性校验(可选)

为了确保数据的一致性,可通过数据校验功能进行确认,该过程通常在窗口时间进行。同一时间只允许同时运行一个一致性校验作业,用户可以对一致性校验进行查询、中断、重启和删除。

算法描述可参考数据一致性校验算法

  1. 切换元数据

确认目标环境具备上线条件后,可触发集群流量切换,完成弹性伸缩。

数据移动说明 #

算法扩容是否会移动数据
1Range
2List
3Mod
4Hash_mod

操作指南 #

具体操作命令请参考弹性伸缩 DistSQL

  1. 存储空间确认

在扩缩容过程中,数据库中会存在两个版本的数据,因此请确保各个节点存储空间为当前数据文件的两倍以上,为扩缩容期间两版本数据做预留空间准备。

  1. 当前分片确认

需确认操作前分片规则的信息,可使用 SHOW SHARDING TABLE NODES 或 PREVIEW 命令进行验证。

  1. 优化弹性伸缩配置(可选)

SphereEx-DBPlusEngine 提供了弹性伸缩的优化配置,可对数据抽取及数据写入的线程进行控制。在资源充沛的情况下,可最大限度使用资源,高效完成作业。同时,为了尽量减少对业务系统的影响,也可对扩缩容流量进行限制。

具体可参考Resharding 作业定义

  1. 数据校验(可选)

为了确保数据的一致性,可通过数据校验功能进行确认,该过程通常在窗口时间进行。

  1. 切换流量

确认目标环境具备上线条件后,可触发集群流量切换,完成扩缩容。

MySQL 使用手册 #

具体操作命令请参考弹性伸缩 DistSQL

环境要求 #

支持的 MySQL 版本:5.1.15 ~ 8.0.x。

权限要求 #

  1. 开启 binlog

MySQL 5.7 my.cnf 示例配置:

[mysqld]
server-id=1
log-bin=mysql-bin
binlog-format=row
binlog-row-image=full
max_connections=600

执行以下命令,确认是否有开启 binlog:

show variables like '%log_bin%';
show variables like '%binlog%';

如以下显示,则说明 binlog 已开启

+-----------------------------------------+---------------------------------------+
| Variable_name                           | Value                                 |
+-----------------------------------------+---------------------------------------+
| log_bin                                 | ON                                    |
| binlog_format                           | ROW                                   |
| binlog_row_image                        | FULL                                  |
+-----------------------------------------+---------------------------------------+
  1. 赋予 MySQL 账号 Replication 相关权限。

执行以下命令,查看该用户是否有复制权限:

SHOW GRANTS FOR 'user';

示例结果:

+------------------------------------------------------------------------------+
|Grants for ${username}@${host}                                                |
+------------------------------------------------------------------------------+
|GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO ${username}@${host}     |
|.......                                                                       |
+------------------------------------------------------------------------------+

完整流程示例 #

前提条件 #

  1. 在 MySQL 中创建好数据库。

示例:

DROP DATABASE IF EXISTS resharding_ds_0;
CREATE DATABASE resharding_ds_0 DEFAULT CHARSET utf8;
    
DROP DATABASE IF EXISTS resharding_ds_1;
CREATE DATABASE resharding_ds_1 DEFAULT CHARSET utf8;
    
DROP DATABASE IF EXISTS resharding_ds_2;
CREATE DATABASE resharding_ds_2 DEFAULT CHARSET utf8;

操作步骤 #

  1. 在 proxy 新建逻辑数据库并配置好资源和规则,建表并初始化一些数据。
CREATE DATABASE sharding_db;

USE sharding_db;

REGISTER STORAGE UNIT ds_0 (
    URL="jdbc:mysql://127.0.0.1:3306/resharding_ds_0?useServerPrepStmts=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf-8",
    USER="root",
    PASSWORD="root"
), ds_1 (
    URL="jdbc:mysql://127.0.0.1:3306/resharding_ds_1?useServerPrepStmts=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf-8",
    USER="root",
    PASSWORD="root"
);
    
CREATE SHARDING TABLE RULE t_order(
STORAGE_UNITS(ds_0,ds_1),
SHARDING_COLUMN=order_id,
TYPE(NAME="hash_mod",PROPERTIES("sharding-count"="4")),
KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME="snowflake"))
);

CREATE TABLE t_order (order_id INT NOT NULL, user_id INT NOT NULL, status VARCHAR(45) NULL, PRIMARY KEY (order_id));

INSERT INTO t_order (order_id, user_id, status) VALUES (1,2,'ok'),(2,4,'ok'),(3,6,'ok'),(4,1,'ok'),(5,3,'ok'),(6,5,'ok');
  1. 在 Proxy 中添加新数据源。

示例:

REGISTER STORAGE UNIT ds_2 (
    URL="jdbc:mysql://127.0.0.1:3306/resharding_ds_2?useServerPrepStmts=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf-8",
    USER="root",
    PASSWORD="root"
);
  1. 启动扩缩容。

启动扩容前,可结合资源情况对线程进行调整,请参考Resharding 作业定义

新增了 ds_2 数据源,示例:

RESHARD TABLE t_order BY(
    STORAGE_UNITS(ds_0, ds_1, ds_2),
    SHARDING_COLUMN=order_id,
    TYPE(NAME="hash_mod",PROPERTIES("sharding-count"="6")),
    KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME="snowflake"))
);
  1. 查看扩缩容作业列表。
SHOW RESHARDING LIST;

示例结果:

+---------------------------------------+---------+----------------------+--------+---------------------+-----------+
| id                                    | tables  | sharding_total_count | active | create_time         | stop_time |
+---------------------------------------+---------+----------------------+--------+---------------------+-----------+
| j51017f973ac82cb1edea4f5238a258c25e89 | t_order | 2                    | true   | 2022-10-25 10:10:58 | NULL      |
+---------------------------------------+---------+----------------------+--------+---------------------+-----------+
  1. 查看扩缩容详情。
SHOW RESHARDING STATUS 'j51017f973ac82cb1edea4f5238a258c25e89';

示例结果:

+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
| item | data_source | status                   | active | processed_records_count | inventory_finished_percentage | remaining_seconds | incremental_idle_seconds | error_message |
+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
| 0    | ds_0        | EXECUTE_INCREMENTAL_TASK | true   | 3                       | 100                           | 0                 | 92                       |               |
| 1    | ds_1        | EXECUTE_INCREMENTAL_TASK | true   | 3                       | 100                           | 0                 | 92                       |               |
+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
  1. 执行停写(可选)。

该语句会拦截增删改和部分DistSQL,是可选的。部分校验算法不需要停写。

STOP RESHARDING SOURCE WRITING 'j51017f973ac82cb1edea4f5238a258c25e89';
  1. 执行数据一致性校验。

示例 DistSQL:

CHECK RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89' BY TYPE (NAME='CRC32_MATCH');

数据一致性校验算法类型来自:

SHOW RESHARDING CHECK ALGORITHMS;

算法描述可参考一致性校验算法列表

查询数据一致性校验进度:

SHOW RESHARDING CHECK STATUS 'j51017f973ac82cb1edea4f5238a258c25e89';

示例结果:

+---------+--------+---------------------+-------------------+-------------------------+-------------------------+------------------+---------------+
| tables  | result | finished_percentage | remaining_seconds | check_begin_time        | check_end_time          | duration_seconds | error_message |
+---------+--------+---------------------+-------------------+-------------------------+-------------------------+------------------+---------------+
| t_order | true   | 100                 | 0                 | 2022-10-25 10:13:33.220 | 2022-10-25 10:13:35.338 | 2                |               |
+---------+--------+---------------------+-------------------+-------------------------+-------------------------+------------------+---------------+
  1. 切换元数据。
APPLY RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89';

预览生效后的规则

PREVIEW SELECT * FROM t_order;

示例结果:

+------------------+-----------------------------------------------------------------+
| data_source_name | actual_sql                                                      |
+------------------+-----------------------------------------------------------------+
| ds_0             | select * from v1_t_order_0 UNION ALL select * from v1_t_order_3 |
| ds_1             | select * from v1_t_order_1 UNION ALL select * from v1_t_order_4 |
| ds_2             | select * from v1_t_order_2 UNION ALL select * from v1_t_order_5 |
+------------------+-----------------------------------------------------------------+
  1. 恢复停写(可选)。

如果在之前执行了停写,需要进行恢复。

RESTORE RESHARDING SOURCE WRITING 'j51017f973ac82cb1edea4f5238a258c25e89';
  1. 完成扩缩容作业。

示例:

COMMIT RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89';

单表扩容为分片表 #

  1. MySQL 准备工作
DROP DATABASE IF EXISTS resharding_ds_0;
CREATE DATABASE resharding_ds_0 DEFAULT CHARSET utf8;
    
DROP DATABASE IF EXISTS resharding_ds_1;
CREATE DATABASE resharding_ds_1 DEFAULT CHARSET utf8;
    
DROP DATABASE IF EXISTS resharding_ds_2;
CREATE DATABASE resharding_ds_2 DEFAULT CHARSET utf8;

USE resharding_ds_0

CREATE TABLE t_order (
    order_id INT NOT NULL, 
    user_id INT NOT NULL, 
    status VARCHAR(45) NULL, 
    PRIMARY KEY (order_id));

INSERT INTO t_order (order_id, user_id, status) VALUES 
    (1,2,'ok'),
    (2,4,'ok'),
    (3,6,'ok'),
    (4,1,'ok'),
    (5,3,'ok'),
    (6,5,'ok');
  1. 创建逻辑库,添加数据库源
DROP DATABASE IF EXISTS sharding_db;

CREATE DATABASE sharding_db;

USE sharding_db;

REGISTER STORAGE UNIT ds_0 (
    URL="jdbc:mysql://192.168.xx.103:13306/resharding_ds_0?useServerPrepStmts=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf-8",
    USER="test",
    PASSWORD="Test@123"
), ds_1 (
    URL="jdbc:mysql://192.168.xx.104:13306/resharding_ds_1?useServerPrepStmts=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf-8",
    USER="test",
    PASSWORD="Test@123"
);
  1. 创建分片规则

CREATE SHARDING TABLE RULE no_use(
STORAGE_UNITS(ds_0,ds_1),
SHARDING_COLUMN=order_id,
TYPE(NAME="hash_mod",PROPERTIES("sharding-count"="4")),
KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME="snowflake"))
);
  1. 添加新的数据源
REGISTER STORAGE UNIT ds_2 (
    URL="jdbc:mysql://192.168.xx.105:13306/resharding_ds_2?useServerPrepStmts=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf-8",
    USER="test",
    PASSWORD="Test@123"
);
  1. 检查单表 t_order
mysql> show sharding table nodes t_order;
ERROR 20000 (44000): Can not find table rule with logic tables `[t_order]`.

mysql> preview select * from t_order;
+------------------+-----------------------+
| data_source_name | actual_sql            |
+------------------+-----------------------+
| ds_0             | select * from t_order |
+------------------+-----------------------+
1 row in set (0.21 sec)
  1. 启动扩容任务

启动扩容前,可结合资源情况对线程进行调整,请参考Resharding 作业定义

RESHARD TABLE t_order BY(
    STORAGE_UNITS(ds_0, ds_1, ds_2),
    SHARDING_COLUMN=order_id,
    TYPE(NAME="hash_mod",PROPERTIES("sharding-count"="6")),
    KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME="snowflake"))
);
  1. 查看任务状态,任务完成后提交
SHOW RESHARDING LIST;

SHOW RESHARDING STATUS 'j51017f973ac82cb1edea4f5238a258c25e89';

CHECK RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89' BY TYPE (NAME='CRC32_MATCH');

SHOW RESHARDING CHECK STATUS 'j51017f973ac82cb1edea4f5238a258c25e89';

APPLY RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89';

COMMIT RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89';
  1. 确认扩容结果
mysql> SHOW SHARDING TABLE NODES t_order;
+---------+------------------------------------------------------------------------------------------------+
| name    | nodes                                                                                          |
+---------+------------------------------------------------------------------------------------------------+
| t_order | ds_0.t_order_0, ds_1.t_order_1, ds_2.t_order_2, ds_0.t_order_3, ds_1.t_order_4, ds_2.t_order_5 |
+---------+------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

自动扩容 #

  1. 在 MySQL 中准备相应的数据源

  2. 在 SphereEx-DBPLusEngine 中创建好逻辑库,及规则

CREATE DATABASE sharding_db;

USE sharding_db;

REGISTER STORAGE UNIT ds_0 (
    URL="jdbc:mysql://127.0.0.1:3306/resharding_ds_0?useServerPrepStmts=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf-8",
    USER="root",
    PASSWORD="root"
), ds_1 (
    URL="jdbc:mysql://127.0.0.1:3306/resharding_ds_1?useServerPrepStmts=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf-8",
    USER="root",
    PASSWORD="root"
);
    
CREATE SHARDING TABLE RULE t_order(
STORAGE_UNITS(ds_0,ds_1),
SHARDING_COLUMN=order_id,
TYPE(NAME="hash_mod",PROPERTIES("sharding-count"="4")),
KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME="snowflake"))
);

CREATE TABLE t_order (order_id INT NOT NULL, user_id INT NOT NULL, status VARCHAR(45) NULL, PRIMARY KEY (order_id));

INSERT INTO t_order (order_id, user_id, status) VALUES (1,2,'ok'),(2,4,'ok'),(3,6,'ok'),(4,1,'ok'),(5,3,'ok'),(6,5,'ok');
  1. 确认当前分片
SHOW SHARDING TABLE NODES t_order;
+---------+----------------------------------------------------------------+
| name    | nodes                                                          |
+---------+----------------------------------------------------------------+
| t_order | ds_0.t_order_0, ds_1.t_order_1, ds_0.t_order_2, ds_1.t_order_3 |
+---------+----------------------------------------------------------------+
  1. 添加新的数据源
REGISTER STORAGE UNIT ds_2 (
    URL="jdbc:mysql://127.0.0.1:3306/resharding_ds_2?useServerPrepStmts=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf-8",
    USER="root",
    PASSWORD="root"
);
  1. 启动扩容
AUTO RESHARD TABLE t_order BY(
    STORAGE_UNITS(ds_0, ds_1, ds_2),
    SHARDING_COLUMN=order_id,
    TYPE(NAME="hash_mod",PROPERTIES("sharding-count"="6")),
    KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME="snowflake"))
);
  1. 查看任务详情
SHOW RESHARDING LIST;

SHOW RESHARDING STATUS 'j51017f973ac82cb1edea4f5238a258c25e89';
+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
| item | data_source | status                   | active | processed_records_count | inventory_finished_percentage | remaining_seconds | incremental_idle_seconds | error_message |
+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
| 0    | ds_0        | EXECUTE_INCREMENTAL_TASK | true   | 3                       | 100                           | 0                 | 1                        |               |
| 1    | ds_1        | EXECUTE_INCREMENTAL_TASK | true   | 3                       | 100                           | 0                 | 1                        |               |
+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
2 rows in set (0.04 sec)

-- 如果查询不到该作业,则作业已经完成,执行下一步即可
  1. 检查分片生效情况
SHOW SHARDING TABLE NODES t_order;
+---------+------------------------------------------------------------------------------------------------------------------+
| name    | nodes                                                                                                            |
+---------+------------------------------------------------------------------------------------------------------------------+
| t_order | ds_0.v1_t_order_0, ds_1.v1_t_order_1, ds_2.v1_t_order_2, ds_0.v1_t_order_3, ds_1.v1_t_order_4, ds_2.v1_t_order_5 |
+---------+------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

至此,完成扩容。

PostgreSQL 使用手册 #

具体操作命令请参考弹性伸缩 DistSQL

环境要求 #

支持的 PostgreSQL 版本:9.4 或以上版本。

权限要求 #

  1. 开启 test_decoding

  2. 调整 WAL 配置。

postgresql.conf 示例配置:

wal_level = logical
max_wal_senders = 10
max_replication_slots = 10
max_connections = 600

详情请参见 Write Ahead LogReplication

  1. 配置 PostgreSQL 允许 Proxy 拥有 replication 权限。

pg_hba.conf 示例配置:

host replication repl_acct 0.0.0.0/0 md5

详情请参见 The pg_hba.conf File

完整流程示例 #

前提条件 #

  1. 在 PostgreSQL 中创建好数据库。

示例:

DROP DATABASE IF EXISTS resharding_ds_0;
CREATE DATABASE resharding_ds_0;

DROP DATABASE IF EXISTS resharding_ds_1;
CREATE DATABASE resharding_ds_1;
    
DROP DATABASE IF EXISTS resharding_ds_2;
CREATE DATABASE resharding_ds_2;

操作步骤 #

  1. 在 proxy 新建逻辑数据库并配置好资源和规则,建表并初始化一些数据。
CREATE DATABASE sharding_db;

\c sharding_db;

REGISTER STORAGE UNIT ds_0 (
    URL="jdbc:postgresql://127.0.0.1:5432/resharding_ds_0",
    USER="root",
    PASSWORD="root"
), ds_1 (
    URL="jdbc:postgresql://127.0.0.1:5432/resharding_ds_1",
    USER="root",
    PASSWORD="root"
);
    
CREATE SHARDING TABLE RULE t_order(
STORAGE_UNITS(ds_0,ds_1),
SHARDING_COLUMN=order_id,
TYPE(NAME="hash_mod",PROPERTIES("sharding-count"="4")),
KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME="snowflake"))
);

CREATE TABLE t_order (order_id INT NOT NULL, user_id INT NOT NULL, status VARCHAR(45) NULL, PRIMARY KEY (order_id));

INSERT INTO t_order (order_id, user_id, status) VALUES (1,2,'ok'),(2,4,'ok'),(3,6,'ok'),(4,1,'ok'),(5,3,'ok'),(6,5,'ok');
  1. 在 Proxy 中添加新数据源。

示例:

REGISTER STORAGE UNIT ds_2 (
    URL="jdbc:postgresql://127.0.0.1:5432/resharding_ds_2",
    USER="root",
    PASSWORD="root"
);
  1. 启动扩缩容。

启动扩容前,可结合资源情况对线程进行调整,请参考Resharding 作业定义

新增了 ds_2 数据源,示例:

RESHARD TABLE t_order BY(
    STORAGE_UNITS(ds_0, ds_1, ds_2),
    SHARDING_COLUMN=order_id,
    TYPE(NAME="hash_mod",PROPERTIES("sharding-count"="6")),
    KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME="snowflake"))
);
  1. 查看扩缩容作业列表。
SHOW RESHARDING LIST;

示例结果:

+---------------------------------------+---------+----------------------+--------+---------------------+-----------+
| id                                    | tables  | sharding_total_count | active | create_time         | stop_time |
+---------------------------------------+---------+----------------------+--------+---------------------+-----------+
| j51017f973ac82cb1edea4f5238a258c25e89 | t_order | 2                    | true   | 2022-10-25 10:10:58 | NULL      |
+---------------------------------------+---------+----------------------+--------+---------------------+-----------+
  1. 查看扩缩容详情。
SHOW RESHARDING STATUS 'j51017f973ac82cb1edea4f5238a258c25e89';

示例结果:

+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
| item | data_source | status                   | active | processed_records_count | inventory_finished_percentage | remaining_seconds | incremental_idle_seconds | error_message |
+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
| 0    | ds_0        | EXECUTE_INCREMENTAL_TASK | true   | 3                       | 100                           | 0                 | 92                       |               |
| 1    | ds_1        | EXECUTE_INCREMENTAL_TASK | true   | 3                       | 100                           | 0                 | 92                       |               |
+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
  1. 执行停写(可选)。

该语句会拦截增删改和部分DistSQL,是可选的。

STOP RESHARDING SOURCE WRITING 'j51017f973ac82cb1edea4f5238a258c25e89';
  1. 执行数据一致性校验。
CHECK RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89';

查询数据一致性校验进度:

SHOW RESHARDING CHECK STATUS 'j51017f973ac82cb1edea4f5238a258c25e89';

示例结果:

+---------+--------+---------------------+-------------------+-------------------------+-------------------------+------------------+---------------+
| tables  | result | finished_percentage | remaining_seconds | check_begin_time        | check_end_time          | duration_seconds | error_message |
+---------+--------+---------------------+-------------------+-------------------------+-------------------------+------------------+---------------+
| t_order | true   | 100                 | 0                 | 2022-10-25 10:13:33.220 | 2022-10-25 10:13:35.338 | 2                |               |
+---------+--------+---------------------+-------------------+-------------------------+-------------------------+------------------+---------------+
  1. 切换元数据。
APPLY RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89';

预览生效后的规则:

PREVIEW SELECT * FROM t_order;

示例结果:

+------------------+-----------------------------------------------------------------+
| data_source_name | actual_sql                                                      |
+------------------+-----------------------------------------------------------------+
| ds_0             | select * from v1_t_order_0 UNION ALL select * from v1_t_order_3 |
| ds_1             | select * from v1_t_order_1 UNION ALL select * from v1_t_order_4 |
| ds_2             | select * from v1_t_order_2 UNION ALL select * from v1_t_order_5 |
+------------------+-----------------------------------------------------------------+
  1. 恢复停写(可选)

如果在之前执行了停写,需要进行恢复。

RESTORE RESHARDING SOURCE WRITING 'j51017f973ac82cb1edea4f5238a258c25e89';
  1. 完成扩缩容作业。

示例:

COMMIT RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89';

openGauss 使用手册 #

具体操作命令请参考弹性伸缩 DistSQL

环境要求 #

支持的 openGauss 版本:2.0.1 ~ 3.0.0。

权限要求 #

  1. 调整 WAL 配置。

postgresql.conf 示例配置:

wal_level = logical
max_wal_senders = 10
max_replication_slots = 10
wal_sender_timeout = 0
max_connections = 600

详情请参见 Write Ahead LogReplication

  1. 配置 PostgreSQL 允许 Proxy 拥有 replication 权限。

pg_hba.conf 示例配置:

host replication repl_acct 0.0.0.0/0 md5

详情请参见 Configuring Client Access AuthenticationExample: Logic Replication Code

完整流程示例 #

前提条件 #

  1. 在 openGauss 中创建好数据库。

示例:

DROP DATABASE IF EXISTS resharding_ds_0;
CREATE DATABASE resharding_ds_0;

DROP DATABASE IF EXISTS resharding_ds_1;
CREATE DATABASE resharding_ds_1;
    
DROP DATABASE IF EXISTS resharding_ds_2;
CREATE DATABASE resharding_ds_2;

操作步骤 #

  1. 在 proxy 新建逻辑数据库并配置好资源和规则,建表并初始化一些数据。
CREATE DATABASE sharding_db;

USE sharding_db;

REGISTER STORAGE UNIT ds_0 (
    URL="jdbc:opengauss://127.0.0.1:5432/resharding_ds_0",
    USER="root",
    PASSWORD="root"
), ds_1 (
    URL="jdbc:opengauss://127.0.0.1:5432/resharding_ds_1",
    USER="root",
    PASSWORD="root"
);
    
CREATE SHARDING TABLE RULE t_order(
STORAGE_UNITS(ds_0,ds_1),
SHARDING_COLUMN=order_id,
TYPE(NAME="hash_mod",PROPERTIES("sharding-count"="4")),
KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME="snowflake"))
);

CREATE TABLE t_order (order_id INT NOT NULL, user_id INT NOT NULL, status VARCHAR(45) NULL, PRIMARY KEY (order_id));

INSERT INTO t_order (order_id, user_id, status) VALUES (1,2,'ok'),(2,4,'ok'),(3,6,'ok'),(4,1,'ok'),(5,3,'ok'),(6,5,'ok');
  1. 在 Proxy 中添加新数据源。

示例:

REGISTER STORAGE UNIT ds_2 (
    URL="jdbc:opengauss://127.0.0.1:5432/resharding_ds_2",
    USER="root",
    PASSWORD="root"
);
  1. 启动扩缩容。

启动扩容前,可结合资源情况对线程进行调整,请参考Resharding 作业定义

新增了 ds_2 数据源,示例:

RESHARD TABLE t_order BY(
    STORAGE_UNITS(ds_0, ds_1, ds_2),
    SHARDING_COLUMN=order_id,
    TYPE(NAME="hash_mod",PROPERTIES("sharding-count"="6")),
    KEY_GENERATE_STRATEGY(COLUMN=order_id,TYPE(NAME="snowflake"))
);
  1. 查看扩缩容作业列表。
SHOW RESHARDING LIST;

示例结果:

+---------------------------------------+---------+----------------------+--------+---------------------+-----------+
| id                                    | tables  | sharding_total_count | active | create_time         | stop_time |
+---------------------------------------+---------+----------------------+--------+---------------------+-----------+
| j51017f973ac82cb1edea4f5238a258c25e89 | t_order | 2                    | true   | 2022-10-25 10:10:58 | NULL      |
+---------------------------------------+---------+----------------------+--------+---------------------+-----------+
  1. 查看扩缩容详情。
SHOW RESHARDING STATUS 'j51017f973ac82cb1edea4f5238a258c25e89';

示例结果:

+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
| item | data_source | status                   | active | processed_records_count | inventory_finished_percentage | remaining_seconds | incremental_idle_seconds | error_message |
+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
| 0    | ds_0        | EXECUTE_INCREMENTAL_TASK | true   | 3                       | 100                           | 0                 | 92                       |               |
| 1    | ds_1        | EXECUTE_INCREMENTAL_TASK | true   | 3                       | 100                           | 0                 | 92                       |               |
+------+-------------+--------------------------+--------+-------------------------+-------------------------------+-------------------+--------------------------+---------------+
  1. 执行停写(可选)。

该语句会拦截增删改和部分DistSQL,是可选的。

STOP RESHARDING SOURCE WRITING 'j51017f973ac82cb1edea4f5238a258c25e89';
  1. 执行数据一致性校验。
CHECK RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89';

查询数据一致性校验进度:

SHOW RESHARDING CHECK STATUS 'j51017f973ac82cb1edea4f5238a258c25e89';

示例结果:

+---------+--------+---------------------+-------------------+-------------------------+-------------------------+------------------+---------------+
| tables  | result | finished_percentage | remaining_seconds | check_begin_time        | check_end_time          | duration_seconds | error_message |
+---------+--------+---------------------+-------------------+-------------------------+-------------------------+------------------+---------------+
| t_order | true   | 100                 | 0                 | 2022-10-25 10:13:33.220 | 2022-10-25 10:13:35.338 | 2                |               |
+---------+--------+---------------------+-------------------+-------------------------+-------------------------+------------------+---------------+
  1. 切换元数据。
APPLY RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89';

预览生效后的规则:

PREVIEW SELECT * FROM t_order;

示例结果:

+------------------+-----------------------------------------------------------------+
| data_source_name | actual_sql                                                      |
+------------------+-----------------------------------------------------------------+
| ds_0             | select * from v1_t_order_0 UNION ALL select * from v1_t_order_3 |
| ds_1             | select * from v1_t_order_1 UNION ALL select * from v1_t_order_4 |
| ds_2             | select * from v1_t_order_2 UNION ALL select * from v1_t_order_5 |
+------------------+-----------------------------------------------------------------+
  1. 恢复停写(可选)。

如果在之前执行了停写,需要进行恢复。

RESTORE RESHARDING SOURCE WRITING 'j51017f973ac82cb1edea4f5238a258c25e89';
  1. 完成扩缩容作业。

示例:

COMMIT RESHARDING 'j51017f973ac82cb1edea4f5238a258c25e89';

FAQ #

  1. 在扩缩容中,分片键、分片算法及参数、分片数量及唯一值生成策略是否可以修改?

可以修改,修改后即移动对应的数据。

  1. 如果有多张需要扩容的表,是否可以支持并行扩容?

支持。

  1. 在扩缩容过程中,数据库主从发生切换时对作业有影响吗?

在已经配置数据发现能力的情况下,扩缩容过程可自动适应数据源变化,主从切换对作业无影响。