打造基於 PostgreSQL/openGauss 的分散式資料庫解決方案

SphereEx發表於2021-12-03

在 MySQL ShardingSphere-Proxy 逐漸成熟並被廣泛採用的同時,ShardingSphere 團隊也在 PostgreSQL ShardingSphere-Proxy 上持續發力。相比前期的 alpha 與 beta,5.0.0 正式版對 PostgreSQL 的協議實現、SQL 支援度、許可權控制等方面進行了大量的完善,為後續全面對接 PostgreSQL 生態打下基礎。ShardingSphere-Proxy 與 PostgreSQL 的生態對接,讓使用者能夠在 PostgreSQL 資料庫的基礎上獲得如資料分片、讀寫分離、影子庫、資料加密/脫敏、分散式治理等透明化的增量能力。

除了 PostgreSQL 方面,由華為開源的國產資料庫 openGauss 的熱度持續攀升。openGauss 具備優秀的單機效能,配合 ShardingSphere 的能力和生態,能夠打造出覆蓋更多場景的國產分散式資料庫解決方案。

ShardingSphere PostgreSQL/openGauss Proxy 目前能夠支援資料分片、讀寫分離、影子庫、資料加密/脫敏、分散式治理等 Apache ShardingSphere 生態中大部分能力,在完善程度上逐漸對齊 ShardingSphere MySQL Proxy。

本文將給大家介紹 ShardingSphere-Proxy 5.0.0 在 PostgreSQL 上所做的提升以及與 openGauss 的生態對接。

作者介紹

吳偉傑

Apache ShardingSphere Committer,SphereEx 中介軟體工程師。目前專注於 Apache ShardingSphere 及其子專案 ElasticJob 的研發。

ShardingSphere-Proxy 介紹

ShardingSphere-Proxy 是 ShardingSphere 生態中的一個接入端,定位為對客戶端透明的資料庫代理。ShardingSphere Proxy 不侷限於 Java,其實現了 MySQL、PostgreSQL 資料庫協議,可以使用各種相容 MySQL / PostgreSQL 協議的客戶端連線並運算元據。

ShardingSphere-JDBC ShardingSphere-Proxy
資料庫 任意 基於 MySQL / PostgreSQL 協議的資料庫
連線消耗數
異構語言 支援 Java 等基於 JVM 語言 任意
效能 損耗低 損耗略高
無中心化
靜態入口

在做了分庫分表或其他規則的情況下,資料會分散到多個資料庫例項上,在管理上難免會有一些不便;或者使用非 Java 語言的開發者,需要 ShardingSphere 所提供的能力…… 以上這些情況,正是 ShardingSphere-Proxy 力所能及之處。

ShardingSphere-Proxy 隱藏了後端實際資料庫,對於客戶端來說就是在使用一個資料庫,不需要關心 ShardingSphere 如何協調背後的資料庫,對於使用非 Java 語言的開發者或 DBA 更友好。

在協議方面,ShardingSphere PostgreSQL Proxy 實現了 Simple Query 與大部分 Extended Query 協議,支援異構語言通過 PostgreSQL/openGauss 驅動連線 Proxy。ShardingSphere openGauss Proxy 在複用 PostgreSQL 協議的基礎上,還支援 openGauss 特有的批量插入協議。

不過,由於 ShardingSphere-Proxy 相比 ShardingSphere-JDBC 增加了一層網路互動,SQL 執行的延時會有所增加,損耗相比 ShardingSphere-JDBC 略高。

ShardingSphere-Proxy 與 PostgreSQL 的生態對接

相容 PostgreSQL Simple Query 與 Extended Query

Simple Query 與 Extended Query 是大多數使用者在使用 PostgreSQL 時最常用的協議。

比如,使用如下命令列工具 psql 連線 PostgreSQL 資料庫進行 CRUD 操作時,主要使用 Simple Query 協議與資料庫互動。

$ psql -h 127.0.0.1 -U postgres
psql (14.0 (Debian 14.0-1.pgdg110+1))
Type "help" for help.
postgres=# select id, name from person where age < 35;
 id | name 
----+------
  1 | Foo
(1 row)

Simple Query 的協議互動示意圖如下:

當使用者使用 PostgreSQL JDBC Driver 等驅動時,可能會如下程式碼使用 PreparedStatement,預設情況下對應著 Extended Query 協議。

String sql = "select id, name from person where age > ?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1, 35);
ResultSet resultSet = ps.executeQuery();

Extended Query 的協議互動示意圖如下:

目前,ShardingSphere PostgreSQL Proxy 實現了 Simple Query 與大部分 Extended Query 協議,不過,因為資料庫客戶端與驅動已經封裝好 API 供使用者使用,一般使用者並不需要關心資料庫協議層面的事情。

ShardingSphere-Proxy 相容 PostgreSQL 的 Simple Query 與 Extended Query 意味著:使用者可以使用常見的 PostgreSQL 客戶端或驅動連線 ShardingSphere-Proxy 進行 CRUD 操作,利用 ShardingSphere 在資料庫上層提供的增量能力。

ShardingSphere-Proxy 與 openGauss 的生態對接

支援 openGauss JDBC Driver

openGauss 資料庫有對應的 JDBC 驅動,JDBC URL 的字首jdbc:opengauss。雖然用 PostgreSQL 的 JDBC 驅動也能夠連線 openGauss 資料庫,但這樣就無法完全利用 openGauss 特有的批量插入等特性。ShardingSphere 增加了 openGauss 資料庫型別,能夠識別 openGauss JDBC Driver,開發者在使用 ShardingSphere 的時候可以直接使用 openGauss 的 JDBC 驅動。

支援 openGauss 批量插入協議

舉一個例子,當我們 prepare 一個 insert 語句如下

insert into person (id, name, age) values (?, ?, ?)

以 JDBC 為例,我們可能會使用如下方法執行批量插入:

String sql = "insert into person (id, name, age) values (?, ?, ?)";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setLong(1, 1);
ps.setString(2, "Foo");
ps.setInt(3, 18);
ps.addBatch();
ps.setLong(1, 2);
ps.setString(2, "Bar");
ps.setInt(3, 36);
ps.addBatch();
ps.setLong(1, 3);
ps.setString(2, "Tom");
ps.setInt(3, 54);
ps.addBatch();
ps.executeBatch();

在 PostgreSQL 協議層面,Bind 訊息每次能夠傳遞一組引數形成 Portal,Execute 每次能夠執行一個 Portal。執行批量插入可以通過反覆執行 BindExecute 實現。協議互動示意圖如下:

Batch Bind 是 openGauss 特有的訊息型別,相比原本的 BindBatch Bind 一次能夠傳遞多組引數,使用 Batch Bind 執行批量插入的協議互動示意如下:

ShardingSphere-Proxy openGauss 實現了對 Batch Bind 協議的支援,也就是說,客戶端能夠直接用 openGauss 的客戶端或驅動對 ShardingSphere Proxy 執行批量插入。

ShardingSphere-Proxy 後續要做的事情

支援 ShardingSphere PostgreSQL Proxy 邏輯 MetaData 查詢

ShardingSphere-Proxy 作為透明資料庫代理,使用者無需關心 Proxy 如何協調背後的資料庫。

以下圖為例,在 ShardingSphere-Proxy 中配置邏輯庫 sharding_db 和邏輯表 person,Proxy背後實際對應了 2 個資料庫共 4 個表。

目前在 ShardingSphere MySQL Proxy 中分別執行 show schemasshow tables 語句,查詢的結果能夠正常的列出邏輯庫 sharding_db 和邏輯表 person

使用 psql 連線 PostgreSQL 時可以通過 \l\d 等命令查詢庫、表。但與 MySQL 不同的是,show tables是 MySQL 所支援的語句,而在 psql 中所使用的 \d 實際上對應了一條比較複雜的 SQL,目前使用 ShardingSphere PostgreSQL Proxy 暫時無法查詢出邏輯庫或邏輯表。

支援 Extended Query 的 Describe Prepared Statement

PostgreSQL 協議的 Describe 訊息有兩種變體,分別是 Describe Portal 和 Describe Prepared Statement。目前 ShardingSphere Proxy 僅支援 Describe Portal,暫時不支援 Describe Prepared Statement。

Describe Prepared Statement 的實際應用舉例:在 PreparedStatement 執行之前獲取結果集的 MetaData。

PreparedStatement preparedStatement = connection.prepareStatement("select * from t_order limit ?");
ResultSetMetaData metaData = preparedStatement.getMetaData();

ShardingSphere 與 PostgreSQL/openGauss 生態對接的過程仍在進行,後續需要做的事情還有很多。如果您對我們所做的事情感興趣,歡迎通過 GitHub 或郵件列表參與 ShardingSphere 社群。

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


參考資料

歡迎新增社群經理微信(ss_assistant_1),進入微信交流群和更多 ShardingSphere 愛好者一同交流

相關文章