Bootstrap

特性更新!DistSQL 集群治理能力详解

0923e8902ebebd46dfba55acd71914cd.png

江龙滔

SphereEx 中间件研发工程师,Apache ShardingSphere Committer。

主要负责 DistSQL 及安全相关特性的创新与研发。

0227c80395bf3241a575abd9c0f967e9.png

兰城翔

SphereEx 中间件研发工程师,Apache ShardingSphere Committer。

目前专注于 DistSQL 的设计和研发。

背景

从 Apache ShardingSphere 5.0.0-Beta 版本发布以来,DistSQL 迅速走进了用户的视野,因其“动态生效、无需重启”的独有优势和接近标准 SQL 的优美语法,越来越受到开发者和运维人员的喜爱。随着 5.0.0 和 5.1.0 版本的迭代,ShardingSphere 社区再次为 DistSQL 新增了大量语法,带来了众多实用的特性。

本文将从“集群治理”的角度,为大家解读 DistSQL 的最新功能。

ShardingSphere 集群

在典型的由 ShardingSphere-Proxy 构成的集群中,一般包含多个计算节点,多个存储节点,如图:

为了便于交流,在 ShardingSphere 中,我们将 Proxy 称为计算节点,将 Proxy 管理的分布式数据库资源(如 ds_0,ds_1),称为资源存储节点

36a51d02e6c591d96d89559617118e28.png

其中,多个 Proxy 计算节点连接到同一注册中心,共享配置和规则,并互相感知在线状态。与此同时,这些计算节点也共享底层的存储节点,它们可以同时对存储节点进行读写操作。此时,用户的应用程序连接到任一计算节点上,都能进行等效的操作。

通过这种集群架构,在计算资源不足时,用户可以快速的对 Proxy 进行水平扩展,也能够在一定程度上降低单点故障带来的风险,提高系统可用性。

应用程序与计算节点间还可以增加负载均衡的机制,此处不扩展。

计算节点治理

计算节点治理,适用于 Cluster 模式,关于模式的更多信息可参考《ShardingSphere Mode 运行模式详解》。

集群准备

这里以单机模拟三个 Proxy 计算节点为例,使用如下模式配置:

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

分别执行启动命令:

sh %SHARDINGSPHERE_PROXY_HOME%/bin/start.sh 3307
sh %SHARDINGSPHERE_PROXY_HOME%/bin/start.sh 3308
sh %SHARDINGSPHERE_PROXY_HOME%/bin/start.sh 3309

三个 Proxy 实例启动成功后,计算节点集群就准备好了。

SHOW INSTANCE LIST

使用客户端连接到任一计算节点,如 3307:

mysql -h 127.0.0.1 -P 3307 -u root -p

查看实例列表:

mysql> SHOW INSTANCE LIST;
+----------------+-----------+------+---------+
| instance_id    | host      | port | status  |
+----------------+-----------+------+---------+
| 10.7.5.35@3309 | 10.7.5.35 | 3309 | enabled |
| 10.7.5.35@3308 | 10.7.5.35 | 3308 | enabled |
| 10.7.5.35@3307 | 10.7.5.35 | 3307 | enabled |
+----------------+-----------+------+---------+

各字段含义如下:

  • instance_id :实例的 id,目前由 host 和 port 组成;

  • host :主机地址;

  • port : 端口号;

  • status : 实例的状态,enableddisabled分别表示启用和禁用状态。

DISABLE INSTANCE

DISABLE INSTANCE 语句用于将指定计算节点设置为禁用状态。需要注意的是,该指令并不会终止目标实例的进程,只是在逻辑上对其进行停用。DISABLE INSTANCE 支持以下语法形式:

DISABLE INSTANCE 10.7.5.35@3308;
# 或
DISABLE INSTANCE IP=10.7.5.35, PORT=3308;

示例:

mysql> DISABLE INSTANCE 10.7.5.35@3308;
Query OK, 0 rows affected (0.02 sec)

mysql> SHOW INSTANCE LIST;
+----------------+-----------+------+----------+
| instance_id    | host      | port | status   | 
+----------------+-----------+------+----------+
| 10.7.5.35@3309 | 10.7.5.35 | 3309 | enabled  |
| 10.7.5.35@3308 | 10.7.5.35 | 3308 | disabled |
| 10.7.5.35@3307 | 10.7.5.35 | 3307 | enabled  |
+----------------+-----------+------+----------+

执行 DISABLE INSTANCE 语句后,通过再次查询能够看到,端口为 3308 的实例状态已更新为 disabled,表示该计算节点已被禁用。

此时若有连接至 10.7.5.35@3308 的客户端,执行任意 SQL 均会提示异常:

1000 - Circuit break mode is ON.

💡提示:暂不允许禁用当前接受指令的计算节点,如果向 10.7.5.35@3309 发送 DISABLE INSTANCE 10.7.5.35@3309; 将会收到异常提示。

ENABLE INSTANCE

ENABLE INSTANCE 语句用于将指定计算节点设置为启用状态。ENABLE INSTANCE 也支持以下语法形式:

ENABLE INSTANCE 10.7.5.35@3308;
# 或
ENABLE INSTANCE IP=10.7.5.35, PORT=3308;

示例:

mysql> SHOW INSTANCE LIST;
+----------------+-----------+------+----------+
| instance_id    | host      | port | status   | 
+----------------+-----------+------+----------+
| 10.7.5.35@3309 | 10.7.5.35 | 3309 | enabled  |
| 10.7.5.35@3308 | 10.7.5.35 | 3308 | disabled |
| 10.7.5.35@3307 | 10.7.5.35 | 3307 | enabled  |
+----------------+-----------+------+----------+

mysql> ENABLE INSTANCE 10.7.5.35@3308;
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW INSTANCE LIST;
+----------------+-----------+------+----------+
| instance_id    | host      | port | status   | 
+----------------+-----------+------+----------+
| 10.7.5.35@3309 | 10.7.5.35 | 3309 | enabled  |
| 10.7.5.35@3308 | 10.7.5.35 | 3308 | enabled  |
| 10.7.5.35@3307 | 10.7.5.35 | 3307 | enabled  |
+----------------+-----------+------+----------+

执行 ENABLE INSTANCE 语句后,通过再次查询能够看到,端口为 3308 的实例状态已恢复为启用状态。

计算节点参数管理

在此前的文章《SCTL 涅槃重生:投入 RAL 的怀抱》中,我们为读者解读了 SCTL(ShardingSphere Control Language)到 RAL(Resource & Rule Administration Language)的演化,同时带来了全新的 SHOW VARIABLE 和 SET VARIABLE 语法。不过在 5.0.0-Beta 版本中,VARIABLE 类别的 DistSQL RAL 仅仅包含以下三个语句:

SET VARIABLE TRANSACTION_TYPE = xx; (LOCAL, XA, BASE)
SHOW VARIABLE TRANSACTION_TYPE;
SHOW VARIABLE CACHED_CONNECTIONS;

在大量的客户反馈中,我们发现查询和修改 Proxy 的 props 配置(位于 server.yaml 中)也是一项高频操作。于是,从 5.0.0 GA 版本开始,DistSQL RAL 增加了对 props 配置的支持。

SHOW VARIABLE

首先让我们回顾一下 props 配置的内容:

props:
  max-connections-size-per-query: 1
  kernel-executor-size: 16  # Infinite by default.
  proxy-frontend-flush-threshold: 128  # The default value is 128.
  proxy-opentracing-enabled: false
  proxy-hint-enabled: false
  sql-show: false
  check-table-metadata-enabled: false
  show-process-list-enabled: false
    # Proxy backend query fetch size. A larger value may increase the memory usage of ShardingSphere Proxy.
    # The default value is -1, which means set the minimum value for different JDBC drivers.
  proxy-backend-query-fetch-size: -1
  check-duplicate-table-enabled: false
  proxy-frontend-executor-size: 0 # Proxy frontend executor size. The default value is 0, which means let Netty decide.
    # Available options of proxy backend executor suitable: OLAP(default), OLTP. The OLTP option may reduce time cost of writing packets to client, but it may increase the latency of SQL execution
    # and block other clients if client connections are more than `proxy-frontend-executor-size`, especially executing slow SQL.
  proxy-backend-executor-suitable: OLAP
  proxy-frontend-max-connections: 0 # Less than or equal to 0 means no limitation.
  sql-federation-enabled: false
    # Available proxy backend driver type: JDBC (default), ExperimentalVertx
  proxy-backend-driver-type: JDBC

现在,用户可以通过如下语法进行交互式查询:

SHOW VARIABLE PROXY_PROPERTY_NAME;

例如:

mysql> SHOW VARIABLE MAX_CONNECTIONS_SIZE_PER_QUERY;
+--------------------------------+
| max_connections_size_per_query |
+--------------------------------+
| 1                              |
+--------------------------------+
1 row in set (0.00 sec)

mysql> SHOW VARIABLE SQL_SHOW;
+----------+
| sql_show |
+----------+
| false    |
+----------+
1 row in set (0.00 sec)
……

💡提示:DistSQL 语法中,参数名称使用下划线分隔,与文件中不同。

SHOW ALL VARIABLES

由于 Proxy 中的参数众多,用户也可以通过 SHOW ALL VARIABLES 的方式查询全部参数值:

mysql> SHOW ALL VARIABLES;
+---------------------------------------+----------------+
| variable_name                         | variable_value |
+---------------------------------------+----------------+
| sql_show                              | false          |
| sql_simple                            | false          |
| kernel_executor_size                  | 0              |
| max_connections_size_per_query        | 1              |
| check_table_metadata_enabled          | false          |
| proxy_frontend_database_protocol_type |                |
| proxy_frontend_flush_threshold        | 128            |
| proxy_opentracing_enabled             | false          |
| proxy_hint_enabled                    | false          |
| show_process_list_enabled             | false          |
| lock_wait_timeout_milliseconds        | 50000          |
| proxy_backend_query_fetch_size        | -1             |
| check_duplicate_table_enabled         | false          |
| proxy_frontend_executor_size          | 0              |
| proxy_backend_executor_suitable       | OLAP           |
| proxy_frontend_max_connections        | 0              |
| sql_federation_enabled                | false          |
| proxy_backend_driver_type             | JDBC           |
| agent_plugins_enabled                 | false          |
| cached_connections                    | 0              |
| transaction_type                      | LOCAL          |
+---------------------------------------+----------------+
21 rows in set (0.01 sec)

SET VARIABLE

动态管理资源和规则,是 DistSQL 独有的优势。现在,使用 SET VARIABLE 语句也可以动态地更新 props 参数了。例如:

# 开启 SQL 日志输出
SET VARIABLE SQL_SHOW = true;
# 开启 hint 功能
SET VARIABLE PROXY_HINT_ENABLED = true;
# 开启联邦查询
SET VARIABLE SQL_FEDERATION_ENABLED = true;
……

💡提示:

  • 以下参数可以通过 SET VARIABLE 语句进行修改,但新值仅在 Proxy 重启后生效:

    • kernel_executor_size

    • proxy_frontend_executor_size

    • proxy_backend_driver_type

  • 以下参数为只读,不可修改:

    • cached_connections

  • 其他未说明的参数,修改后立即生效。

存储节点管理

在 ShardingSphere 中,存储节点并不是直接与计算节点绑定的。由于同一个存储节点可能在不同逻辑库(schema)中同时扮演不同的角色,用于实现不同的业务逻辑,因此,存储节点始终是关联在某个逻辑库中的。

在 DistSQL 中,通过 RESOURCE 相关语句来进行存储节点的管理,包括:

  • ADD RESOURCE;

  • ALTER RESOURCE;

  • DROP RESOURCE;

  • SHOW SCHEMA RESOURCES。

逻辑库准备

RESOURCE 相关语句仅作用于逻辑库,因此在操作之前,需要先创建并使用 USE 命令成功选择一个逻辑库:

DROP DATABASE IF EXISTS sharding_db;

CREATE DATABASE sharding_db;

USE sharding_db;

ADD RESOURCE

ADD RESOURCE 语法支持以下形式:

  • 指定 HOST、PORT、DB

ADD RESOURCE resource_0 (
    HOST=127.0.0.1,
    PORT=3306,
    DB=db0,
    USER=root,
    PASSWORD=root
);
  • 指定 URL

ADD RESOURCE resource_1 (
    URL="jdbc:mysql://127.0.0.1:3306/db1?serverTimezone=UTC&useSSL=false",
    USER=root,
    PASSWORD=root
);

同时,以上两种语法形式,都支持扩展参数 PROPERTIES。该参数用于指定 Proxy 与存储节点间连接池的属性配置,例如:

ADD RESOURCE resource_2 (
    HOST=127.0.0.1,
    PORT=3306,
    DB=db2,
    USER=root,
    PASSWORD=root,
    PROPERTIES("maximumPoolSize"=10)
),resource_3 (
    URL="jdbc:mysql://127.0.0.1:3306/db3?serverTimezone=UTC&useSSL=false",
    USER=root,
    PASSWORD=root,
    PROPERTIES("maximumPoolSize"=10,"idleTimeout"="30000")
);

💡提示:仅 URL 形式支持指定 JDBC 连接参数,如 useSSL。

ALTER RESOURCE

ALTER RESOURCE 用于修改已有存储节点的连接信息,如改变连接池大小、修改 JDBC 连接参数等。

在语法形式上,ALTER RESOURCE 与 ADD RESOURCE 完全一致,例如:

ALTER RESOURCE resource_2 (
    HOST=127.0.0.1,
    PORT=3306,
    DB=db2,
    USER=root,
    PROPERTIES("maximumPoolSize"=50)
),resource_3 (
    URL="jdbc:mysql://127.0.0.1:3306/db3?serverTimezone=GMT&useSSL=false",
    USER=root,
    PASSWORD=root,
    PROPERTIES("maximumPoolSize"=50,"idleTimeout"="30000")
);

💡提示:由于修改存储节点可能导致元数据变更或应用数据异常,ALTER RESOURCE 不能修改连接的目标 DB,仅可修改以下内容:

  • 用户名

  • 用户密码

  • PROPERTIES 连接池参数

  • JDBC 参数

DROP RESOURCE

DROP RESOURCE 用于从逻辑库中删除存储节点,不会删除存储节点中的任何数据。语法示例如下:

DROP RESOURCE resource_0, resource_1;

💡提示:为保护数据正确,被规则引用的存储节点是无法删除的。

例如 t_order 为分片表,它的实际表分布于 resource_0 和 resource_1 中,那么 resource_0 和 resource_1 即被 t_order 的分片规则引用,不能删除。

SHOW SCHEMA RESOURCES

SHOW SCHEMA RESOURCES 用于查询逻辑库中的存储节点,支持以下语法形式:

# 查询当前 use 的逻辑库中的存储节点
SHOW SCHEMA RESOURCES;
# 查询指定逻辑库中的存储节点
SHOW SCHEMA RESOURCES FROM sharding_db;

示例:在通过前述的 ADD RESOURCE 命令添加 4 个存储节点后,执行查询操作:

9fef641e3ac7d17c039aea0b6814b90a.png

由于查询结果列数较多,只截取部分。

以上就是通过 DistSQL 动态管理存储节点的方式,与修改 YAML 文件相比,DistSQL 的执行是实时的,无需重启 Proxy 计算节点,让在线业务更安全。

同时,通过 DistSQL 执行的变更会通过注册中心实时同步到集群内的其他计算节点,而连接到任一计算节点的客户端,也能即时查询到存储节点的变化。

这,就是集群治理的魅力。

结语

以上就是本次分享的全部内容,如果读者对 Apache ShardingSphere 有任何疑问或建议,欢迎在 GitHub issue 列表提出,或可前往中文社区交流讨论。

GitHub issue:

https://github.com/apache/shardingsphere/issues

贡献指南:

https://shardingsphere.apache.org/community/cn/contribute/

中文社区:

https://community.sphere-ex.com/

*参考信息:

1.ShardingSphere-Proxy 快速入门:https://shardingsphere.apache.org/document/5.1.0/cn/quick-start/shardingsphere-proxy-quick-start/

2.DistSQL RDL:https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-proxy/distsql/syntax/rdl/resource-definition/

3.DistSQL RQL:https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-proxy/distsql/syntax/rql/resource-query/

4.DistSQL RAL:https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-proxy/distsql/syntax/ral/ 

;