使用 DistSQL 构建数据分片服务

数据库分片演示了 DistSQL 的附加功能。
77 位读者喜欢这篇文章。
Person standing in front of a giant computer screen with numbers, data

Opensource.com

如果您正在阅读本文,那么您可能熟悉数据查询和编程语言 SQL(结构化查询语言)。它也被用作管理系统访问数据、查询、更新和管理关系数据库系统的标准语言。与标准 SQL 类似,DistSQL 或分布式 SQL 是一种 ShardingSphere 特有的内置 SQL 语言,它提供了超越标准 SQL 的增量功能。DistSQL 利用 ShardingSphere 强大的 SQL 解析引擎,提供了类似于标准 SQL 的语法结构和语法验证系统,使 DistSQL 在保持规律性的同时更加灵活。ShardingSphere 的 Database Plus 概念旨在创建一个开源分布式数据库系统,该系统既功能强大又与实际数据库业务相关。DistSQL 构建于传统数据库之上,提供符合标准且具有 ShardingSphere 功能的 SQL 功能,以增强传统的数据库管理。

DistSQL 的原始设计意图

经过多年的快速发展,ShardingSphere 在数据库中间件领域变得独一无二,因为内核逐渐稳定,核心功能不断完善。作为亚洲开源领域的领导者,ShardingSphere 一直在追求其对分布式数据库生态系统的探索。DistSQL 的设计目标是重新定义中间件和数据库之间的界限,使开发人员能够像使用原生数据库一样使用 Apache ShardingSphere。它也是 ShardingSphere 从面向开发人员的框架和中间件转型为面向运维的基础设施产品的关键组成部分。

DistSQL 语法系统

DistSQL 从一开始就被设计为面向标准的,同时考虑了数据库开发人员和运维人员的习惯。DistSQL 的语法基于标准 SQL 语言,在保持可读性和易用性的同时,最大限度地保留了 ShardingSphere 自身的功能,并为用户应对不同的业务场景提供了尽可能多的自定义选项。

熟悉 SQL 和 ShardingSphere 的开发人员可以快速上手。

标准 SQL 提供了不同类型的语法,例如 DQL、DDL、DML、DCL 等,以定义各种功能性 SQL 语句。DistSQL 也定义了自己的语法系统。

在 ShardingSphere 中,DistSQL 语法目前主要分为三种类型:RDL、RQL 和 RAL。

  • RDL(资源与规则定义语言)- 用于创建、修改和删除资源和规则的资源规则定义语言。
  • RQL(资源与规则查询语言)- 用于查询和展示资源和规则的资源规则查询语言。
  • RAL(资源与规则管理语言)- 用于增量功能操作的资源规则管理语言,例如 hint、事务类型切换和分片执行计划查询。

DistSQL 的语法为 ShardingSphere 向分布式数据库迈进搭建了桥梁。随着更多想法的实现,它仍在不断完善,因此 DistSQL 将变得越来越强大。欢迎有兴趣的开发人员加入 ShardingSphere,为 DistSQL 贡献想法和代码。

有关更详细的语法规则,请参阅官方文档

有关项目社区,请参阅官方 Slack 频道

DistSQL 实践

在了解了 DistSQL 的设计理念和语法系统之后,让我们演示如何基于 ShardingSphere 构建数据分片服务。

环境准备

  • 启动 MySQL 服务
  • 创建用于分片的 MySQL 数据库
  • 启动 Zookeeper 服务
  • 开启分布式治理配置并启动 ShardingSphere-Proxy

实践演示

1. 使用 MySQL 命令行连接到启动的 ShardingSphere-Proxy。

2. 创建并查询分布式数据库 sharding_db

mysql> CREATE DATABASE sharding_db;
Query OK, 0 rows affected (0.04 sec)

mysql> SHOW databases;
+-------------+
| SCHEMA_NAME |
+-------------+
| sharding_db |
+-------------+
1 row in set (0.04 sec)

3. 使用新创建的数据库

mysql> USE sharding_db;
No connection. Trying to reconnect...
Connection id: 2
Current database: *** NONE ***

Database changed

4. 执行 RDL 以配置两个数据源资源 ds_1ds_2 用于分片

mysql> ADD RESOURCE ds_1 (
    -> HOST=127.0.0.1,
    -> PORT=3306,
    -> DB=ds_1,
    -> USER=root,
    -> PASSWORD=root123456
    -> );
Query OK, 0 rows affected (0.53 sec)

mysql>
mysql> ADD RESOURCE ds_2 (
    -> HOST=127.0.0.1,
    -> PORT=3306,
    -> DB=ds_2,
    -> USER=root,
    -> PASSWORD=root123456
    -> );
Query OK, 0 rows affected (0.02 sec)

5. 执行 RQL 以查询新添加的数据源资源

    mysql> SHOW RESOURCES FROM sharding_db;
    +------+-------+-----------+------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | name | type  | host      | port | db   | attribute                                                                                                                                                   |
    +------+-------+-----------+------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | ds_1 | MySQL | 127.0.0.1 | 3306 | ds_1 | {"maxLifetimeMilliseconds":1800000,"readOnly":false,"minPoolSize":1,"idleTimeoutMilliseconds":60000,"maxPoolSize":50,"connectionTimeoutMilliseconds":30000} |
    | ds_2 | MySQL | 127.0.0.1 | 3306 | ds_2 | {"maxLifetimeMilliseconds":1800000,"readOnly":false,"minPoolSize":1,"idleTimeoutMilliseconds":60000,"maxPoolSize":50,"connectionTimeoutMilliseconds":30000} |
    +------+-------+-----------+------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
    2 rows in set (0.13 sec)

6. 执行 RDL 以创建 t_order 表的分片规则

mysql> CREATE SHARDING TABLE RULE t_order(
    -> RESOURCES(ds_1,ds_2),
    -> SHARDING_COLUMN=order_id,
    -> TYPE(NAME=hash_mod,PROPERTIES("sharding-count"=4)),
    -> GENERATED_KEY(COLUMN=order_id,TYPE(NAME=snowflake,PROPERTIES("worker-id"=123)))
    -> );
Query OK, 0 rows affected (0.06 sec)

7. 执行 RQL 以查询分片规则

    mysql> SHOW SHARDING TABLE RULES FROM sharding_db;
    +---------+-----------------+-------------------+----------------------+------------------------+-------------------------------+--------------------------------+-------------------+---------------------+----------------------------+-----------------------------+-------------------+------------------+-------------------+
    | table   | actualDataNodes | actualDataSources | databaseStrategyType | databaseShardingColumn | databaseShardingAlgorithmType | databaseShardingAlgorithmProps | tableStrategyType | tableShardingColumn | tableShardingAlgorithmType | tableShardingAlgorithmProps | keyGenerateColumn | keyGeneratorType | keyGeneratorProps |
    +---------+-----------------+-------------------+----------------------+------------------------+-------------------------------+--------------------------------+-------------------+---------------------+----------------------------+-----------------------------+-------------------+------------------+-------------------+
    | t_order |                 | ds_1,ds_2         |                      |                        |                               |                                | hash_mod          | order_id            | hash_mod                   | sharding-count=4            | order_id          | snowflake        | worker-id=123     |
    +---------+-----------------+-------------------+----------------------+------------------------+-------------------------------+--------------------------------+-------------------+---------------------+----------------------------+-----------------------------+-------------------+------------------+-------------------+
    1 row in set (0.01 sec)

除了查询当前数据库下的所有分片规则外,RQL 还可以使用以下语句查询单个表的分片规则

SHOW SHARDING TABLE RULE t_order FROM sharding_db

创建和查询 t_order 分片表

mysql> CREATE TABLE `t_order`(
    -> `order_id` int not null,
    -> `user_id` int not null,
    -> `status` varchar(45) DEFAULT NULL,
    -> PRIMARY KEY (`order_id`)
    -> )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.28 sec)

mysql> show tables;
+-----------------------+
| Tables_in_sharding_db |
+-----------------------+
| t_order               |
+-----------------------+
1 row in set (0.01 sec)

在 ShardingSphere-Proxy 端成功创建分片表 t_order 后,ShardingSphere 会通过客户端连接到底层数据库 ds_1ds_2,根据 t_order 表的分片规则自动创建分片表。

mysql> use ds_1;
Database changed
mysql> show tables;
+----------------+
| Tables_in_ds_1 |
+----------------+
| t_order_0      |
| t_order_2      |
+----------------+
2 rows in set (0.01 sec)
mysql> use ds_2;
Database changed
mysql> show tables;
+----------------+
| Tables_in_ds_2 |
+----------------+
| t_order_1      |
| t_order_3      |
+----------------+
2 rows in set (0.00 sec)

创建分片表后,继续在 ShardingSphere-Proxy 端执行 SQL 语句以插入数据

mysql> INSERT INTO t_order values(1, 1, 'ok');
Query OK, 1 row affected (0.06 sec)

mysql> INSERT INTO t_order values(2, 2, 'disabled');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO t_order values(3, 3, 'locked');
Query OK, 1 row affected (0.01 sec)

mysql> select * from t_order;
+----------+---------+----------+
| order_id | user_id | status   |
+----------+---------+----------+
|        1 |       1 | ok       |
|        2 |       2 | disabled |
|        3 |       3 | locked   |
+----------+---------+----------+
3 rows in set (0.06 sec)

通过 RAL 查询执行计划

mysql> preview select * from t_order;
+-----------------+------------------------------------------------+
| datasource_name | sql                                            |
+-----------------+------------------------------------------------+
| ds_1            | select * from t_order_0 ORDER BY order_id ASC  |
| ds_1            | select * from t_order_2 ORDER BY order_id ASC  |
| ds_2            | select * from t_order_1 ORDER BY order_id ASC  |
| ds_2            | select * from t_order_3 ORDER BY order_id ASC  |
+-----------------+------------------------------------------------+
4 rows in set (0.02 sec)

至此,使用 DistSQL 完成 ShardingSphere 数据分片服务。与之前版本基于配置文件的 ShardingSphere 代理相比,DistSQL 在管理资源和规则方面对开发人员更友好、更灵活。此外,SQL 驱动的方法实现了 DistSQL 和标准 SQL 之间的无缝对接。

schemaName: sharding_db
dataSources:
  ds_0:
    url: jdbc:mysql://127.0.0.1:3306/ds_1?serverTimezone=UTC&useSSL=false
    username: root
    password: root123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  ds_1:
    url: jdbc:mysql://127.0.0.1:3306/ds_2?serverTimezone=UTC&useSSL=false
    username: root
    password: root123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
rules:
- !SHARDING
  tables:
    t_order:
      actualDataNodes: ds_${0..1}.t_order_${0..1}
      tableStrategy:
        standard:
          shardingColumn: order_id
          shardingAlgorithmName: t_order_inline
      keyGenerateStrategy:
        column: order_id
        keyGeneratorName: snowflake
    t_order_item:
      actualDataNodes: ds_${0..1}.t_order_item_${0..1}
      tableStrategy:
        standard:
          shardingColumn: order_id
          shardingAlgorithmName: t_order_item_inline
      keyGenerateStrategy:
        column: order_item_id
        keyGeneratorName: snowflake
  bindingTables:
    - t_order,t_order_item
  defaultDatabaseStrategy:
    standard:
      shardingColumn: user_id
      shardingAlgorithmName: database_inline
  defaultTableStrategy:
    none:

  shardingAlgorithms:
    database_inline:
      type: INLINE
      props:
        algorithm-expression: ds_${user_id % 2}
    t_order_inline:
      type: INLINE
      props:
        algorithm-expression: t_order_${order_id % 2}
    t_order_item_inline:
      type: INLINE
      props:
        algorithm-expression: t_order_item_${order_id % 2}
  keyGenerators:
    snowflake:
      type: SNOWFLAKE
      props:
        worker-id: 123
1. Create a distributed database
CREATE DATABASE sharding_db;

2. Add data resources
ADD RESOURCE ds_1 (
HOST=127.0.0.1,
PORT=3306,
DB=ds_1,
USER=root,
PASSWORD=root123456
);
ADD RESOURCE ds_2 (
HOST=127.0.0.1,
PORT=3306,
DB=ds_2,
USER=root,
PASSWORD=root123456
);

3. Create sharding rules
CREATE SHARDING TABLE RULE t_order(
RESOURCES(ds_1,ds_2),
SHARDING_COLUMN=order_id,
TYPE(NAME=hash_mod,PROPERTIES("sharding-count"=4)),
GENERATED_KEY(COLUMN=order_id,TYPE(NAME=snowflake,PROPERTIES("worker-id"=123)))
);

在上面的示例中,仅演示了 DistSQL 语法的一小部分。除了通过 CREATESHOW 语句创建和查询资源和规则外,DistSQL 还提供诸如 ALTRE DROP 之类的附加操作,并支持数据分片核心功能、读写分离、数据加密和数据库发现的配置控制。

结论

作为 Apache ShardingSphere 5.0.0-beta 版本中发布的新功能之一,DistSQL 将继续在此版本的基础上进行构建,以改进语法和增强功能。DistSQL 为 ShardingSphere 探索分布式数据库领域开辟了无限的可能性。未来,DistSQL 将被用作连接更多功能的链接,并提供一键式操作。

例如,它将允许一键分析数据库的整体状态,连接弹性迁移,提供一键数据扩展和收缩,并与控制连接以实现一键主从切换和更改数据库状态。热烈欢迎开源和 JavaScript 爱好者加入 Slack 社区或查看项目的 GitHub 页面,以了解有关 ShardingSphere 最新开发的更多信息。


本文改编自作者的原始出版物

接下来阅读什么
标签
User profile image.
孟浩然 SphereEx 资深 Java 工程师,Apache ShardingSphere Committer。曾负责京东科技数据库产品研发,对开源和数据库生态系统充满热情。目前专注于 ShardingSphere 数据库中间件生态系统的开发和开源社区建设。

评论已关闭。

© . All rights reserved.