1. 程式人生 > 其它 >SCTL 涅槃重生:投入 RAL 的懷抱

SCTL 涅槃重生:投入 RAL 的懷抱

《DistSQL:像資料庫一樣使用 Apache ShardingSphere》一文中,PMC 孟浩然為大家介紹了 DistSQL 的設計初衷和語法體系,並通過實戰操作展示了一條 SQL 建立分散式資料庫表的強大能力,展現了 Apache ShardingSphere 在新形態下的互動體驗。
近期,ShardingSphere 社群對 SCTL 語法和執行引擎進行了重構,使 SCTL 完全投入 DistSQL 語法體系的懷抱,將原 SCTL 功能融入到 RAL 語法中,使 ShardingSphere 管理語言更加統一。本文將帶領讀者深入瞭解這次重構的意義,並通過例項一一解析新的 RAL 語句,感受 ShardingSphere 讓使用者體驗更加美好的追求態度。

作者簡介

江龍滔 SphereEx 中介軟體研發工程師,Apache ShardingSphere Committer。 目前主要負責 DistSQL 及許可權相關特性的設計和研發。 蘭城翔 SphereEx 中介軟體研發工程師,Apache ShardingSphere Contributor。 目前專注於 DistSQL 的設計和研發。

前情回顧:什麼是 RAL

RAL 是 DistSQL 語法的一個分類,DistSQL 包含了 RDL、RQL 和 RAL 這三種具體型別。
  • RDL(Resource & Rule Definition Language)負責資源和規則的建立、修改和刪除;
  • RQL(Resource & Rule Query Language)負責資源和規則的查詢和展現;
  • RAL(Resource & Rule Administration Language)提供對資源和規則的高階控制能力。

什麼是 SCTL

SCTL(ShardingSphere Control Language)是 Apache ShardingSphere 的控制語言,負責 Hint、事務型別切換、分片執行計劃查詢等增量功能的操作。 SCTL 包含以下語法:
語句 說明
sctl:set transaction_type=XX 修改當前連線的事務型別, 支援 LOCAL,XA,BASE。例:sctl:set transaction_type=XA
sctl:show transaction_type 查詢當前連線的事務型別
sctl:show cached_connections 查詢當前連線中快取的物理資料庫連線個數
sctl:explain SQL 檢視邏輯 SQL 的執行計劃,例:sctl:explain select * from t_order;
sctl:hint set PRIMARY_ONLY=true 針對當前連線,是否將資料庫操作強制路由到主庫
sctl:hint set DatabaseShardingValue=yy 針對當前連線,設定 hint 僅對資料庫分片有效,並新增分片值,yy:資料庫分片值
sctl:hint addDatabaseShardingValue xx=yy 針對當前連線,為表 xx 新增分片值 yy,xx:邏輯表名稱,yy:資料庫分片值
sctl:hint addTableShardingValue xx=yy 針對當前連線,為表 xx 新增分片值 yy,xx:邏輯表名稱,yy:表分片值
sctl:hint clear 針對當前連線,清除 hint 所有設定
sctl:hint show status 針對當前連線,查詢 hint 狀態,primary_only:true/false,sharding_type:databases_only/databases_tables
sctl:hint show table status 針對當前連線,查詢邏輯表的 hint 分片值

為何重構

1、SCTL 功能實現於 v3.1.0 時期[1],彼時 ShardingSphere 還沒有提出 DistSQL 的概念。如今,DistSQL 提供了功能更加豐富、概念更加統一的新 API,將 SCTL 的功能融入到 RAL 中,可以降低使用者的理解成本,避免為使用者帶來困惑。 2、SCTL 語法使用了特殊的字首字元 sctl: 作為標識,在 SQL 執行時沒有經過 Parser 引擎,而是通過字串字首匹配的方式進行解析的。現在 DistSQL 已經實現了完整的解析流程,可以使用規範的語法解析器來處理輸入語句,減少特殊程式碼。 3、尤其重要的是,原來的 SCTL 語法,有點不像真正的 SQL 語句。隨著 5.0.0 版本的釋出,ShardingSphere 已經推出了 DistSQL 這樣一套完整的資源和規則管理方式,ShardingSphere 控制語句也可以變得更像 SQL,因此,社群將 SCTL 語法重構提上了日程。

重構解析

經過 ShardingSphere 社群的精心設計和細緻討論,SCTL 語法將由新的 RAL 語法代替[2],前後變化如下表所示:
調整前 調整後
sctl:set transaction_type=XX set variable transaction_type=XX
sctl:show transaction_type show variable transaction_type
sctl:show cached_connections show variable cached_connections
sctl:explain SQL preview SQL
sctl:hint set PRIMARY_ONLY=true set readwrite_splitting hint source = [auto / write]
sctl:hint set DatabaseShardingValue=yy set sharding hint database_value = yy;
sctl:hint addDatabaseShardingValue xx=yy add sharding hint database_value xx= yy;
sctl:hint addTableShardingValue xx=yy add sharding hint table_value xx = yy
sctl:hint clear clear [hint / sharding hint / readwrite_splitting hint]
sctl:hint show status show [sharding / readwrite_splitting] hint status
sctl:hint show table status 歸入 【show sharding hint status】
下面讓我們對這些語句一一進行解析:
show variable transaction_type
查詢當前連線的事務型別
  • 輸入命令
mysql> show variable transaction_type;  
  • 輸出效果
+------------------+
| TRANSACTION_TYPE |
+------------------+
| LOCAL            |
+------------------+
set variable transaction_type
修改當前連線的事務型別,支援的型別有:LOCAL, XA, BASE(不區分大小寫)。
  • 輸入命令
mysql> set variable transaction_type=XA;
  • 輸出效果
a. 設定成功,響應 Query OK, 0 rows affected; b. 再次執行 show variable transaction_type; 顯示事務型別已經改變為 XA;
show variable cached_connection
查詢當前連線中快取的物理資料庫連線個數。
  • 輸入命令
mysql> show variable cached_connections;
  • 輸出效果
+--------------------+
| CACHED_CONNECTIONS |
+--------------------+
| 0                  |
+--------------------+
preview SQL
預覽實際 SQL。此處以讀寫分離場景為例,preview 語法支援任意 SQL 語句。
  • 輸入命令
mysql> preview select * from t_order;
  • 輸出效果
+-----------------+----------------------------------------------+
| datasource_name | sql                                          |
+-----------------+----------------------------------------------+
| read_ds_0       | select * from t_order ORDER BY order_id ASC  |
| read_ds_1       | select * from t_order ORDER BY order_id ASC  |
+-----------------+----------------------------------------------+
*注:以下為讀寫分離場景 Hint 示例,示例中使用了讀寫分離 + 分片的規則配置,配置如下:
rules:
- !READWRITE_SPLITTING
  dataSources:
    ds_0:
      writeDataSourceName: write_ds_0
      readDataSourceNames: 
        - read_ds_0
    ds_1:
      writeDataSourceName: write_ds_1
      readDataSourceNames: 
        - read_ds_1
- !SHARDING
  tables:
    t_order:
      actualDataNodes: ds_${0..1}.t_order
  defaultDatabaseStrategy:
    standard:
      shardingColumn: user_id
      shardingAlgorithmName: database_inline
  defaultTableStrategy:
    none:
  shardingAlgorithms:
    database_inline:
      type: INLINE
      props:
        algorithm-expression: ds_${user_id % 2}
show readwrite_splitting hint status
針對當前連線,查詢 readwrite_splitting 的 hint 狀態。
  • 輸入命令
mysql> show readwrite_splitting hint status;
  • 輸出效果
+--------+
| source |
+--------+
| auto   |
+--------+
set readwrite_splitting hint source
針對當前連線,設定讀寫分離的路由策略(自動路由或強制到寫庫)。 source 支援的型別有:AUTO , WRITE(不區分大小寫)
  • AUTO:讀寫分離自動路由
  • WRITE:強制路由到主庫
  • 輸入命令
mysql> set readwrite_splitting hint source=write;
  • 輸出效果
a. 設定成功,響應 Query OK, 0 rows affected; b. 再次執行 show readwrite_splitting hint status; 顯示 source 值已經改變為 write; c. 執行 preview select * from t_order; 能夠看到查詢 SQL 將會路由到主庫:
mysql> preview select * from t_order;
+-----------------+----------------------------------------------+
| datasource_name | sql                                          |
+-----------------+----------------------------------------------+
| write_ds_0      | select * from t_order ORDER BY order_id ASC  |
| write_ds_1      | select * from t_order ORDER BY order_id ASC  |
+-----------------+----------------------------------------------+
clear readwrite_splitting hint
針對當前連線,清除 readwrite_splitting 的 hint 設定。
  • 輸入命令
mysql> clear readwrite_splitting hint;
  • 輸出效果
a. 清除成功,響應 Query OK, 0 rows affected b. 將 readwrite_splitting hint 的所有設定恢復到初始狀態,可通過 show readwrite_splitting hint status; 命令檢視 clear 的結果。 *注:以下為分片場景 Hint 示例,分庫和分表均使用了 Hint 演算法,使用的分片配置如下:
rules:
- !SHARDING
  tables:
    t_order_item:
      actualDataNodes: ds_${0..1}.t_order_item_${0..1}
      databaseStrategy:
        hint:
          shardingAlgorithmName: database_inline
      tableStrategy:
        hint:
          shardingAlgorithmName: table_inline
  shardingAlgorithms:
    database_inline:
      type: HINT_INLINE
      props:
        algorithm-expression: ds_${Integer.valueOf(value) % 2}
    table_inline:
      type: HINT_INLINE
      props:
        algorithm-expression: t_order_item_${Integer.valueOf(value) % 2}
show sharding hint status
針對當前連線,查詢 sharding 的 hint 狀態。
  • 輸入命令
mysql> show sharding hint status;
  • 輸出效果
以下是初始狀態的輸出值:
  • 驗證查詢路由,輸入命令
preview select * from t_order_item;
  • 輸出效果
此時沒有 hint 值,查詢使用全路由
set sharding hint database_value;
針對當前連線,設定 hint 僅對資料庫分片有效,並新增分片值 1。
  • 輸入命令
mysql> set sharding hint database_value = 1;
  • 輸出效果
a. 設定成功,響應 Query OK, 0 rows affected; b. 執行 show sharding hint status; 顯示 t_order_item 表對應的 database_sharding_values 值為 '1', 且 sharding_type 值更新為 'databases_only'; c. 執行 preview select * from t_order_item; SQL 全部路由到 ds_1: 說明:根據 YAML 配置中的分片規則,當 database_value 設定為奇數時路由到 ds_1,設定為偶數時路由到 ds_0。
add sharding hint database_value;
針對當前連線,為表 t_order_item 新增分片值。
  • 輸入命令
mysql> add sharding hint database_value t_order_item = 5;
  • 輸出效果
a. 設定成功,響應 Query OK, 0 rows affected; b. 執行 show sharding hint status; 顯示 t_order_item 表對應的 database_sharding_values 值為 '5',且 sharding_type 值更新為 'databases_tables'; c. 執行 preview select * from t_order_item; SQL 全部路由到 ds_1:
  • 再次輸入 add 命令,新增一個偶數值
mysql> add sharding hint database_value t_order_item = 10;
  • 輸出效果:
a. 新增成功,響應 Query OK, 0 rows affected; b. 執行 show sharding hint status; 顯示 t_order_item 表對應的 database_sharding_values 值為 '5,10': c. 執行 preview select * from t_order_item; SQL 路由包含了 ds_0 和 ds_1:(因為 hint 值包含奇數和偶數,將目標資料來源全部包含在內)
add sharding hint table_value;
針對當前連線,為表 t_order_item 新增分片值。
  • 輸入命令
mysql> add sharding hint table_value t_order_item = 0;
  • 輸出效果
a. 設定成功,響應 Query OK, 0 rows affected; b. 執行 show sharding hint status; 顯示 t_order_item 表對應的 database_sharding_values 值為 '5,10',table_sharding_values 的值為 '0': c. 執行 preview select * from t_order_item; 路由情況如下圖,每個庫只查詢 t_order_item_0: 說明:根據 YAML 配置中的分片規則,當 table_value 設定為奇數時路由到 t_order_item_1,設定為偶數時路由到 t_order_item_0。 add sharding hint database_value 類似,add sharding hint database_value 也可以設定多個 hint 值,以覆蓋更多的分片。
clear sharding hint
針對當前連線,清除 sharding 的 hint 設定。
  • 輸入命令
mysql> clear sharding hint;
輸出效果 a. 清除成功,響應 Query OK, 0 rows affected b. 將 sharding hint 的所有設定恢復到初始狀態,可通過 show sharding hint status; 命令檢視 clear 的結果。初始狀態如下:
clear hint
這是一個特殊的指令,包含 clear readwrite_splitting hintclear sharding hint 的能力,將讀寫分離和分片的 hint 值全部清除,迴歸初始狀態。
  • 任意設定 hint 值,再執行命令
mysql> clear hint;
  • 輸出效果
a. 清除成功,響應 Query OK, 0 rows affected b. 將 readwrite_splitting hint 和 sharding hint 的所有設定恢復到初始狀態,可通過 show readwrite_splitting hint status;show sharding hint status; 命令檢視 clear 的結果。 *注:特別說明:若需使用 Hint 相關 DistSQL 功能,需要啟用 ShardingSphere-Proxy 的配置項 `proxy-hint-enabled`,說明資訊請參考: https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-proxy/props/

更多 RAL 語句

除了包含原有 SCTL 語句的功能,RAL 語句還提供彈性伸縮、例項熔斷、讀寫分離讀庫禁用這樣的實用管理功能,歡迎讀者前往官網閱讀詳細文件,瞭解 RAL 的更多使用場景: https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-proxy/distsql/syntax/ral/

結語

以上就是本次分享的全部內容,如果讀者對 Apache ShardingSphere 有任何疑問或建議,歡迎在 GitHub issue 列表提出,也可提交 Pull Request 參與到開源社群,也歡迎在中文社群中討論。 GitHub issue:https://github.com/apache/shardingsphere/issues 貢獻指南:https://shardingsphere.apache.org/community/cn/contribute/ 中文社群:https://community.sphere-ex.com/ 參考資訊 [1] https://github.com/apache/shardingsphere/pull/1586 [2] https://github.com/apache/shardingsphere/issues/11677 歡迎關注公眾號第一時間瞭解諮訊