Amazon Aurora 讀寫能力擴展之 ShardingSphere-JDBC 篇
文章來源亞馬遜 AWS 官方博客
孫進華,亞馬遜雲科技資深解決方案架構師,負責幫助客户進行上雲架構的設計和諮詢。加入 AWS 前自主創業負責電商平台搭建和車企電商平台整體架構設計。曾就職於全球領先的通訊設備公司,擔任高級工程師,負責 LTE 設備系統的多個子系統的開發與架構設計。在高併發、高可用系統架構設計、微服務架構設計、數據庫、中間件、IOT 等方面有着豐富的經驗。
1. 前言
Amazon Aurora 是亞馬遜雲科技自研的一項關係數據庫服務,它在提供和開源數據庫 MySQL、PostgreSQL 的完好兼容性同時,也能夠提供和商業數據庫媲美的性能和可用性。性能方面,Aurora MySQL 能夠支持到與開源標準 MySQL 同等配置下五倍的吞吐量,Aurora PostgreSQL 能夠支持與開源標準 PostgreSQL 同等配置下三倍的吞吐量的提升。在擴展性的角度,Aurora 在存儲與計算、橫向與縱向方面都進行了功能的增強和創新。
Aurora 的最大數據存儲量現在支持多達 128TB,而且可以支持存儲的動態收縮。計算方面,Aurora 提供多個讀副本的可擴展性配置支持一個區域內多達 15 個讀副本的擴展,提供多主的架構來支持同一個區域內 4 個寫節點的擴展,提供 Serverless 無服務器化的架構實例級別的秒級縱向擴展,提供全球數據庫來實現數據庫的低延遲跨區域擴展。
隨着用户數據量的增長,Aurora 已經提供了很好的擴展性,那是否可以進一步增強更多的數據量、更多的併發訪問能力呢?您可以考慮利用分庫分表的方式,來支持底層多個 Aurora 集羣的配置。基於此,包含這篇博客在內的系列博客會進行相應的介紹,旨在為您進行分庫分表時代理或者 JDBC 的選擇提供參考。
1.1 為什麼要分庫分表
AWS Aurora 提供了關係型數據庫單機,主從,多主,全球數據庫等託管架構形式可以滿足以上各種架構場景,但分庫分表的場景下 Aurora 沒有提供直接的支持,並且分庫分表還衍生出來如垂直與水平多種形態,再進一步提升數據容量的情況下,也帶來一些需要解決的問題,如跨節點數據庫 Join 關聯查詢、分佈式事務、執行的 SQL 排序、翻頁、函數計算、數據庫全局主鍵、容量規劃、分庫分表後二次擴容等問題。
1.2 分庫分表的方式
查詢一次所花的時間業界公認 MySQL 單表容量在 1 千萬以下是最佳狀態,因為這時它的BTREE索引樹高在 3~5 之間。通過對數據的切分可以在降低單表的數據量的同時,將讀寫的壓力分攤到不同的數據節點上,數據切分可以分為:垂直切分和水平切分。
垂直切分的優點
-
解決業務系統層面的耦合,業務清晰;
-
與微服務的治理類似,也能對不同業務的數據進行分級管理、維護、監控、擴展等;
-
高併發場景下,垂直切分一定程度的提升 IO、數據庫連接數、單機硬件資源的瓶頸。
垂直切分的缺點
-
分庫後無法 Join,只能通過接口聚合方式解決,提升了開發的複雜度;
-
分庫後分布式事務處理複雜;
-
依然存在單表數據量過大的問題(需要水平切分)。
水平切分的優點
-
不存在單庫數據量過大、高併發的性能瓶頸,提升系統穩定性和負載能力;
-
應用端改造較小,不需要拆分業務模塊。
水平切分的缺點
-
跨分片的事務一致性難以保證;
-
跨庫的 Join 關聯查詢性能較差;
-
數據多次擴展難度和維護量極大。
結合以上分析,在調研了常見的分庫分表的中間件基礎上,我們選取 ShardingSphere 開源產品結合 Amazon Aurora,介紹這兩種產品的結合是如何滿足各種形式的分庫分表方式和如何解決由分庫分錶帶來的一些問題。
2. Sharding-JDBC 功能測試
2.1 樣例工程説明
下載樣例工程代碼到本地,為保證測試代碼的穩定性我們這裏選擇使 shardingsphere-example-4.0.0 這個 tag 版本。
git clone https://github.com/apache/shardingsphere-example.git
工程項目説明:
shardingsphere-example
├── example-core
│ ├── config-utility
│ ├── example-api
│ ├── example-raw-jdbc
│ ├── example-spring-jpa #spring+jpa集成基礎的entity,repository
│ └── example-spring-mybatis
├── sharding-jdbc-example
│ ├── sharding-example
│ │ ├── sharding-raw-jdbc-example
│ │ ├── sharding-spring-boot-jpa-example #集成基礎的sharding-jdbc的功能
│ │ ├── sharding-spring-boot-mybatis-example
│ │ ├── sharding-spring-namespace-jpa-example
│ │ └── sharding-spring-namespace-mybatis-example
│ ├── orchestration-example
│ │ ├── orchestration-raw-jdbc-example
│ │ ├── orchestration-spring-boot-example #集成基礎的sharding-jdbc的治理的功能
│ │ └── orchestration-spring-namespace-example
│ ├── transaction-example
│ │ ├── transaction-2pc-xa-example #sharding-jdbc分佈式事務兩階段提交的樣例
│ │ └──transaction-base-seata-example #sharding-jdbc分佈式事務seata的樣例
│ ├── other-feature-example
│ │ ├── hint-example
│ │ └── encrypt-example
├── sharding-proxy-example
│ └── sharding-proxy-boot-mybatis-example
└── src/resources
└── manual_schema.sql
配置文件説明:
application-master-slave.properties #讀寫分離配置文件
application-sharding-databases-tables.properties #分庫分表配置文件
application-sharding-databases.properties #僅分庫配置文件
application-sharding-master-slave.properties #分庫分表加讀寫分離的配置文件
application-sharding-tables.properties #分表配置文件
application.properties #spring boot 配置文件
代碼邏輯説明:
Spring Boot 應用的入口類,執行該類就可以運行工程
其中 demo 的執行邏輯如下:
2.2讀寫分離驗證
隨着業務增長,寫和讀請求分離到不同的數據庫節點上能夠有效提高整個數據庫集羣的處理能力。Aurora 通過讀/寫的 endpoint 可以滿足用户寫和強一致性讀的需求,單獨只讀的 endpoint 可以滿足用户非強一致性讀的需求。Aurora 的讀寫延遲通常在毫秒級別,比 MySQL 基於 binlog 的邏輯複製要低得多,所以有很多負載是直接打到只讀 endpoint。
通過一主多從的配置方式,可以將查詢請求均勻的分散到多個數據副本,能夠進一步的提升系統的處理能力。讀寫分離雖然可以提升系統的吞吐量和可用性,但同時也帶來了數據不一致的問題。Aurora 以完全託管的形式提供了主從架構,但上層應用在與 Aurora 交互時,仍然需要管理多個數據源,根據 SQL 語句的讀寫類型和一定的路由策略將 SQL 請求路由到不同的節點上。
Sharding-JDBC 提供的讀寫分離的特性,應用程序與 Sharding-JDBC 集成,將應用程序與數據庫集羣之間複雜配置關係從應用程序中剝離出來,開發者通過配置文件管理 Shard,再結合一些 ORM 框架如 Spring JPA、Mybatis 就可以完全將這些複製的邏輯從代碼中分離。極大的提高代碼的可維護性,降低代碼與數據庫的耦合。
2.2.1 數據庫環境準備
首先創建一套 Aurora MySQL 讀寫分離集羣,機型為 db.r5.2xlarge,每套集羣有一個寫節點 2 個讀節點。如下圖所示
2.2.2 Sharding-JDBC 配置
application.properties spring boot 主配置文件説明
如下圖所屬:綠色標註的部分你需要替換成自己環境上的配置
# jpa自動根據實體創建和drop數據表
spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.show_sql=true
#spring.profiles.active=sharding-databases
#spring.profiles.active=sharding-tables
#spring.profiles.active=sharding-databases-tables
#激活master-slave 配置項,這樣sharding-jdbc將使用master-slave配置文件
spring.profiles.active=master-slave
#spring.profiles.active=sharding-master-slave
application-master-slave.properties sharding-jdbc 配置文件説明
spring.shardingsphere.datasource.names=ds_master,ds_slave_0,ds_slave_1
# 數據源 主庫-master
spring.shardingsphere.datasource.ds_master.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master.password= 您自己的主db密碼
spring.shardingsphere.datasource.ds_master.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master.jdbc-url=您自己的主db數據源url spring.shardingsphere.datasource.ds_master.username=您自己的主db用户名
# 數據源 從庫
spring.shardingsphere.datasource.ds_slave_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_slave_0.password= 您自己的從db密碼
spring.shardingsphere.datasource.ds_slave_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_slave_0.jdbc-url=您自己的從db數據源url
spring.shardingsphere.datasource.ds_slave_0.username= 您自己的從db用户名
# 數據源 從庫
spring.shardingsphere.datasource.ds_slave_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_slave_1.password=您自己的從db密碼
spring.shardingsphere.datasource.ds_slave_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_slave_1.jdbc-url= 您自己的從db數據源url
spring.shardingsphere.datasource.ds_slave_1.username= 您自己的從db用户名
# 路由策略配置
spring.shardingsphere.masterslave.load-balance-algorithm-type=round_robin
spring.shardingsphere.masterslave.name=ds_ms
spring.shardingsphere.masterslave.master-data-source-name=ds_master
spring.shardingsphere.masterslave.slave-data-source-names=ds_slave_0,ds_slave_1
# sharding-jdbc 配置信息存儲方式
spring.shardingsphere.mode.type=Memory
# 開啟shardingsphere 日誌,開啟的情況下從打印中可以看到邏輯SQL到實際SQL的轉換
spring.shardingsphere.props.sql.show=true
2.2.3 測試驗證過程説明
- 測試環境數據初始化:Spring JPA 初始化自動創建用於測試的表
- 在主實例上寫入數據
如下圖 ShardingSphere-SQL log 所示,寫 SQL 在 ds_master 數據源上執行。
- 數據查詢操作在從庫上執行
如下圖 ShardingSphere-SQL log 所示,讀 SQL 按照輪詢的方式在 ds_slave 數據源上執行。
[INFO ] 2022-04-02 19:43:39,376 --main-- [ShardingSphere-SQL] Rule Type: master-slave
[INFO ] 2022-04-02 19:43:39,376 --main-- [ShardingSphere-SQL] SQL: select orderentit0_.order_id as order_id1_1_, orderentit0_.address_id as address_2_1_,
orderentit0_.status as status3_1_, orderentit0_.user_id as user_id4_1_ from t_order orderentit0_ ::: DataSources: ds_slave_0
---------------------------- Print OrderItem Data -------------------
Hibernate: select orderiteme1_.order_item_id as order_it1_2_, orderiteme1_.order_id as order_id2_2_, orderiteme1_.status as status3_2_, orderiteme1_.user_id
as user_id4_2_ from t_order orderentit0_ cross join t_order_item orderiteme1_ where orderentit0_.order_id=orderiteme1_.order_id
[INFO ] 2022-04-02 19:43:40,898 --main-- [ShardingSphere-SQL] Rule Type: master-slave
[INFO ] 2022-04-02 19:43:40,898 --main-- [ShardingSphere-SQL] SQL: select orderiteme1_.order_item_id as order_it1_2_, orderiteme1_.order_id as order_id2_2_, orderiteme1_.status as status3_2_,
orderiteme1_.user_id as user_id4_2_ from t_order orderentit0_ cross join t_order_item orderiteme1_ where orderentit0_.order_id=orderiteme1_.order_id ::: DataSources: ds_slave_1
注意:如下圖所示,如果在一個事務中既有讀也有寫,Sharding-JDBC 將讀寫操作都路由到主庫;如果讀寫請求不在一個事務中,那麼對應讀請求將按照路由策略分發到不同的讀節點上。
@Override
@Transactional // 開啟事務時在該事務中讀寫都走主庫;關閉事務時,讀走從庫,寫走主庫
public void processSuccess() throws SQLException {
System.out.println("-------------- Process Success Begin ---------------");
List<Long> orderIds = insertData();
printData();
deleteData(orderIds);
printData();
System.out.println("-------------- Process Success Finish --------------");
}
2.2.4 Aurora failover 場景驗證
Aurora 數據庫環境採用 2.2.1 中的配置。
2.2.4.1 驗證過程中説明
- 啟動 Spring-Boot 工程
- 在 Aurora 的 console 上執行故障轉移操作
- 執行 Rest API 請求
-
多次執行 POST (http://localhost:8088/save-user) 直到該 API 的調用寫入 Aurora 失敗到最終恢復成功。
-
觀測執行代碼 failover 過程如下圖所示,從 log 可以分析最近一次 SQL 執行寫入操作成功到下次執行再次寫入成功大概需要 37s,也就是應用從 Aurora failover 中可以自動恢復,恢復的時長大概是 37s。
2.3僅分表功能驗證
2.3.1 Sharding-JDBC 配置
application.properties spring boot 主配置文件説明
# jpa 自動根據實體創建和drop數據表
spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.show_sql=true
#spring.profiles.active=sharding-databases
#激活sharding-tables配置項
#spring.profiles.active=sharding-tables
#spring.profiles.active=sharding-databases-tables
# spring.profiles.active=master-slave
#spring.profiles.active=sharding-master-slave
application-sharding-tables.properties sharding-jdbc 配置文件説明
## 主鍵策略配置
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key-generator.props.worker.id=123
spring.shardingsphere.sharding.tables.t_order_item.actual-data-nodes=ds.t_order_item_$->{0..1}
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.sharding-column=order_id
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.algorithm-expression=t_order_item_$->{order_id % 2}
spring.shardingsphere.sharding.tables.t_order_item.key-generator.column=order_item_id
spring.shardingsphere.sharding.tables.t_order_item.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order_item.key-generator.props.worker.id=123
# 配置t_order與 t_order_item的綁定關係
spring.shardingsphere.sharding.binding-tables[0]=t_order,t_order_item
# 配置廣播表
spring.shardingsphere.sharding.broadcast-tables=t_address
# sharding-jdbc的模式
spring.shardingsphere.mode.type=Memory
# 開啟shardingsphere日誌
spring.shardingsphere.props.sql.show=true
2.3.2 測試驗證過程説明
- DDL 操作
如下圖所屬,JPA 自動創建用於測試的表,在配置了 Sharding-JDBC 的路由規則的情況下,client 端執行 DDL,Sharding-JDBC 會自動根據分表規則創建對應的表;如 taddress 是廣播表,由於只有一個主實例,所以創建一個 taddress;torder 按照取模分表,創建 torder 時會創建 torder0, torder1 兩張表物理表。
- 寫操作
如下圖所示 Logic SQL 向 torder 插入一條記錄,Sharding-JDBC 執行的時候會根據分表規則將數據分佈放到 torder0, torder_1 中。
當 t_order 和 t_order_item 配置了綁定關係時,order_item 與 order 有關聯關係的記錄會放到同一個物理分表中。
- 讀操作
綁定表下的 join 查詢操作 order 和 order_item,如下圖所示,會根據綁定關係精確定位對應的物理 shard 上。
非綁定表下的 join 查詢操作 order 和 order_item,如下圖所屬,會遍歷所有的 shard。
2.4 僅分庫功能驗證
2.4.1 數據庫環境準備
如下圖所屬,在 Aurora 上創建兩個實例:ds_0 和 ds_1
啟動 Sharding-spring-boot-jpa-example 工程時會在兩個 Aurora 實例上創建表 t_order, t_order_item,t_address
2.4.2 Sharding-JDBC 配置
application.properties springboot 主配置文件説明
# jpa 自動根據實體創建和drop數據表
spring.jpa.properties.hibernate.hbm2ddl.auto=create
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.show_sql=true
# 激活sharding-databases配置項
spring.profiles.active=sharding-databases
#spring.profiles.active=sharding-tables
#spring.profiles.active=sharding-databases-tables
#spring.profiles.active=master-slave
#spring.profiles.active=sharding-master-slave
application-sharding-databases.properties sharding-jdbc 配置文件説明
spring.shardingsphere.datasource.names=ds_0,ds_1
# ds_0
spring.shardingsphere.datasource.ds_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_0.jdbc-url= spring.shardingsphere.datasource.ds_0.username=
spring.shardingsphere.datasource.ds_0.password=
# ds_1
spring.shardingsphere.datasource.ds_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_1.jdbc-url=
spring.shardingsphere.datasource.ds_1.username=
spring.shardingsphere.datasource.ds_1.password=
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds_$->{user_id % 2}
spring.shardingsphere.sharding.binding-tables=t_order,t_order_item
spring.shardingsphere.sharding.broadcast-tables=t_address
spring.shardingsphere.sharding.default-data-source-name=ds_0
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds_$->{0..1}.t_order
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key-generator.props.worker.id=123
spring.shardingsphere.sharding.tables.t_order_item.actual-data-nodes=ds_$->{0..1}.t_order_item
spring.shardingsphere.sharding.tables.t_order_item.key-generator.column=order_item_id
spring.shardingsphere.sharding.tables.t_order_item.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order_item.key-generator.props.worker.id=123
# sharding-jdbc的模式
spring.shardingsphere.mode.type=Memory
# 開啟shardingsphere日誌
spring.shardingsphere.props.sql.show=true
2.4.3 測試驗證過程説明
- DDL 操作
JPA 自動創建用於測試的表,如下圖所屬,在配置了 Sharding-JDBC 的分庫路由規則的情況下,client 端執行 DDL,Sharding-JDBC 會自動根據分表規則創建對應的表;如 taddress 是廣播表在 ds0 和 ds1 上都會創建物理表 taddress,torder,torderitem 按照取模分庫,這三個表會分別在 ds0 和 ds_1 上創建。
- 寫操作
對於廣播表 taddress,每寫入一條記錄會在 ds0 和 ds1 的 taddress 表上都寫入
對於分庫的表 torder,torder_item,會按照分庫字段和路由策略寫入到對應實例上的表中。
- 讀操作
如下圖所示,查詢 order,根據分庫路由規則路由到對應的 Aurora 實例上。
如下圖所示,查詢 Address,由於 address 是廣播表,會在所用的節點中隨機選擇一個 address 所在的實例查詢。
如下圖所示,綁定表下的 join 查詢操作 order 和 order_item 時,會根據綁定關係精確定位對應的物理 shard 上。
2.5 分庫分表功能驗證
2.5.1 數據庫環境準備
如下圖所示,在 Aurora 上創建兩個實例:ds0和ds1
啟動 sharding-spring-boot-jpa-example 工程時會在兩個 Aurora 實例上創建物理表 t_order_01, t_order_02, t_order_item_01,t_order_item_02 和 t_address 全局表。
2.5.2 Sharding-JDBC 配置
application.properties springboot 主配置文件説明
# jpa 自動根據實體創建和drop數據表
spring.jpa.properties.hibernate.hbm2ddl.auto=create
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.show_sql=true
# 激活sharding-databases-tables配置項
#spring.profiles.active=sharding-databases
#spring.profiles.active=sharding-tables
spring.profiles.active=sharding-databases-tables
#spring.profiles.active=master-slave
#spring.profiles.active=sharding-master-slave
application-sharding-databases.properties sharding-jdbc 配置文件説明
spring.shardingsphere.datasource.names=ds_0,ds_1
# ds_0
spring.shardingsphere.datasource.ds_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_0.jdbc-url= 306/dev?useSSL=false&characterEncoding=utf-8
spring.shardingsphere.datasource.ds_0.username=
spring.shardingsphere.datasource.ds_0.password=
spring.shardingsphere.datasource.ds_0.max-active=16
# ds_1
spring.shardingsphere.datasource.ds_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_1.jdbc-url=
spring.shardingsphere.datasource.ds_1.username=
spring.shardingsphere.datasource.ds_1.password=
spring.shardingsphere.datasource.ds_1.max-active=16
# 默認的分庫策略
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds_$->{user_id % 2}
spring.shardingsphere.sharding.binding-tables=t_order,t_order_item
spring.shardingsphere.sharding.broadcast-tables=t_address
# 不滿足分庫策略的表放在ds_0上
spring.shardingsphere.sharding.default-data-source-name=ds_0
# t_order分表策略
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds_$->{0..1}.t_order_$->{0..1}
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{order_id % 2}
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key-generator.props.worker.id=123
# t_order_item分表策略
spring.shardingsphere.sharding.tables.t_order_item.actual-data-nodes=ds_$->{0..1}.t_order_item_$->{0..1}
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.sharding-column=order_id
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.algorithm-expression=t_order_item_$->{order_id % 2}
spring.shardingsphere.sharding.tables.t_order_item.key-generator.column=order_item_id
spring.shardingsphere.sharding.tables.t_order_item.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order_item.key-generator.props.worker.id=123
# sharding-jdbc的模式
spring.shardingsphere.mode.type=Memory
# 開啟shardingsphere日誌
spring.shardingsphere.props.sql.show=true
2.5.3 測試驗證過程説明
- DDL 操作
JPA 自動創建用於測試的表,如下圖所示,在配置了 Sharding-JDBC 的分庫分表路由規則的情況下,client 端執行 DDL,Sharding-JDBC 會自動根據分表規則創建對應的表;如 taddress 是廣播表在 ds_0 和 ds_1 上都會創建 t_address。t_order,t_order_item 按照取模分庫分表,這三個表會分別在 ds0 和 ds_1 上創建。
- 寫操作
對於廣播表 taddress,每寫入一條記錄會在 ds0 和 ds1 的 taddress 表上都寫入。
對於分庫的表 torder,torder_item,會按照分庫字段和路由策略寫入到對應實例上的表中。
- 讀操作
讀操作與僅分庫功能驗證類似,這裏不再贅述
2.6 分庫分表加讀寫分離功能驗證
2.6.1 數據庫環境準備
創建的數據庫實例於對應的物理表如下圖所示。
2.6.2 Sharding-JDBC 配置
application.properties spring boot 主配置文件説明
# jpa 自動根據實體創建和drop數據表
spring.jpa.properties.hibernate.hbm2ddl.auto=create
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.show_sql=true
# 激活sharding-databases-tables配置項
#spring.profiles.active=sharding-databases
#spring.profiles.active=sharding-tables
#spring.profiles.active=sharding-databases-tables
#spring.profiles.active=master-slave
spring.profiles.active=sharding-master-slave
application-sharding-master-slave.properties sharding-jdbc 配置文件説明
其中數據庫的 url、name、password 需要修改成你自己的數據庫的參數。
spring.shardingsphere.datasource.names=ds_master_0,ds_master_1,ds_master_0_slave_0,ds_master_0_slave_1,ds_master_1_slave_0,ds_master_1_slave_1
spring.shardingsphere.datasource.ds_master_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_0.jdbc-url= spring.shardingsphere.datasource.ds_master_0.username=
spring.shardingsphere.datasource.ds_master_0.password=
spring.shardingsphere.datasource.ds_master_0.max-active=16
spring.shardingsphere.datasource.ds_master_0_slave_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_0_slave_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_0_slave_0.jdbc-url= spring.shardingsphere.datasource.ds_master_0_slave_0.username=
spring.shardingsphere.datasource.ds_master_0_slave_0.password=
spring.shardingsphere.datasource.ds_master_0_slave_0.max-active=16
spring.shardingsphere.datasource.ds_master_0_slave_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_0_slave_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_0_slave_1.jdbc-url= spring.shardingsphere.datasource.ds_master_0_slave_1.username=
spring.shardingsphere.datasource.ds_master_0_slave_1.password=
spring.shardingsphere.datasource.ds_master_0_slave_1.max-active=16
spring.shardingsphere.datasource.ds_master_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_1.jdbc-url=
spring.shardingsphere.datasource.ds_master_1.username=
spring.shardingsphere.datasource.ds_master_1.password=
spring.shardingsphere.datasource.ds_master_1.max-active=16
spring.shardingsphere.datasource.ds_master_1_slave_0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_1_slave_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_1_slave_0.jdbc-url=
spring.shardingsphere.datasource.ds_master_1_slave_0.username=
spring.shardingsphere.datasource.ds_master_1_slave_0.password=
spring.shardingsphere.datasource.ds_master_1_slave_0.max-active=16
spring.shardingsphere.datasource.ds_master_1_slave_1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master_1_slave_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds_master_1_slave_1.jdbc-url= spring.shardingsphere.datasource.ds_master_1_slave_1.username=admin
spring.shardingsphere.datasource.ds_master_1_slave_1.password=
spring.shardingsphere.datasource.ds_master_1_slave_1.max-active=16
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds_$->{user_id % 2}
spring.shardingsphere.sharding.binding-tables=t_order,t_order_item
spring.shardingsphere.sharding.broadcast-tables=t_address
spring.shardingsphere.sharding.default-data-source-name=ds_master_0
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds_$->{0..1}.t_order_$->{0..1}
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{order_id % 2}
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key-generator.props.worker.id=123
spring.shardingsphere.sharding.tables.t_order_item.actual-data-nodes=ds_$->{0..1}.t_order_item_$->{0..1}
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.sharding-column=order_id
spring.shardingsphere.sharding.tables.t_order_item.table-strategy.inline.algorithm-expression=t_order_item_$->{order_id % 2}
spring.shardingsphere.sharding.tables.t_order_item.key-generator.column=order_item_id
spring.shardingsphere.sharding.tables.t_order_item.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order_item.key-generator.props.worker.id=123
# 主從數據源,分庫數據源配置
spring.shardingsphere.sharding.master-slave-rules.ds_0.master-data-source-name=ds_master_0
spring.shardingsphere.sharding.master-slave-rules.ds_0.slave-data-source-names=ds_master_0_slave_0, ds_master_0_slave_1
spring.shardingsphere.sharding.master-slave-rules.ds_1.master-data-source-name=ds_master_1
spring.shardingsphere.sharding.master-slave-rules.ds_1.slave-data-source-names=ds_master_1_slave_0, ds_master_1_slave_1
# sharding-jdbc的模式
spring.shardingsphere.mode.type=Memory
# 開啟shardingsphere日誌
spring.shardingsphere.props.sql.show=true
2.6.3 測試驗證過程説明
- DDL 操作所屬
JPA 自動創建用於測試的表,如下圖,在配置了 Sharding-JDBC 的分庫路由規則的情況下,client 端執行 DDL,Sharding-JDBC 會自動根據分表規則創建對應的表;如 taddress 是廣播表在 ds0 和 ds1 上都會創建, t_address,t_order,t_order_item 按照取模分庫,這三個表會分別在 ds0 和 ds_1 上創建。
- 寫操作
對於廣播表 taddress,每寫入一條記錄會在 ds0 和 ds1 的 taddress 表上都寫入
對於分庫的表 torder,torder_item,會按照分庫字段和路由策略寫入到對應實例上的表中。
- 讀操作
綁定表下的 join 查詢操作 order 和 order_item,如下圖所示。
3. 結語
ShardingSphere 作為一款專注於數據庫增強的開源產品,從社區活躍度、產品成熟度、文檔豐富程度上來看都是比較好的。其中的 Sharding-JDBC 是基於客户端的分庫分表方案,它支持了所有的分庫分表的場景,並且無需引入 Proxy 這樣的中間層,所以降低了運維的複雜性,相比 Proxy 這種方式由於少了中間層所以時延理論上會比 Proxy 低,其次 Sharding-JDBC 可以支持各種基於 SQL 標準的關係型數據庫如 MySQL/PostgreSQL/Oracle/SQL Server 等。但由於 Sharding-JDBC 與應用程序集成,目前支持的語言僅限於 Java,對應用程序有一定的耦合性,但 Sharding-JDBC 將所以分庫分表的配置從應用程序中分離,這樣面臨切換其他的中間件時由此帶來的變更相對較小。綜上所述如果您不希望引入中間層,且使用基於 Java 語言開發的系統,且需要對接不同的關係型數據庫,Sharding-JDBC 將會是一個不錯的選擇。
歡迎點擊鏈接,瞭解更多內容:
Apache ShardingSphere 官網:https://shardingsphere.apache.org/
Apache ShardingSphere GitHub 地址:https://github.com/apache/shardingsphere
SphereEx 官網:https://www.sphere-ex.com
歡迎添加社區經理微信(ss_assistant_1)加入交流羣,與眾多 ShardingSphere 愛好者一同交流。
- DistSQL 深度解析:打造動態化的分佈式數據庫
- 終於可以一行代碼也不用改了!ShardingSphere 原生驅動問世
- ShardingSphere-Proxy 前端協議問題排查方法及案例
- 開源人張亮的 17 年成長路線,熱愛才能堅持
- Apache ShardingSphere 5.1.2 發佈|全新驅動 API 雲原生部署,打造高性能數據網關
- 數據庫治理的雲原生之道 —— Database Mesh 2.0
- 覆蓋 70% 核心業務,ShardingSphere 如何成為喜馬拉雅架構演進的催化劑
- Amazon Aurora 讀寫能力擴展之 ShardingSphere-JDBC 篇
- 我們在講的 Database Plus,到底能解決什麼樣的問題?
- 中商惠⺠交易中台架構演進:對 Apache ShardingSphere 的應⽤
- Amazon Aurora 的讀寫能力擴展之 ShardingSphere-Proxy 篇
- Apache ShardingSphere 如何實現分佈式事務
- 16 台服務器達成 1000 萬 tpmC!挑戰分佈式數據庫性能極限
- ICDE 2022|Apache ShardingSphere:一個功能全面和可插拔的數據分片平台
- 特性更新!DistSQL 集羣治理能力詳解
- Apache ShardingSphere 首篇論文被 ICDE 收錄,全球數據庫發展迎來新局面
- 詳探 Apache ShardingSphere SQL Parse Format 功能
- ShardingSphere Mode 模式新起航:運行模式詳解
- 全鏈路在線生產數據庫壓測利器:Apache ShardingSphere 影子庫特性升級
- 打造基於 PostgreSQL/openGauss 的分佈式數據庫解決方案