1.基本介紹 1.1.概念 高層模塊不能依賴於一個“具體化、細節化”的低層模塊,而是通過一個抽象的“規範/標準”建立兩者之間的依賴關係,簡言之就是:不依賴於實現,而是依賴於抽象。這裡“實現”一詞有的地方也稱為“細節”,在編碼中主要體現的是我們根據業務模型具體自定義的普通類,比如:員工類、商品類等。而 ...
背景
在軟體系統演進過程中,隨著業務規模的增長 (TPS/存儲容量),我們需要通過集群化部署來分攤計算、存儲壓力。
應用服務的無狀態設計使其具備了伸縮性。在使用 Kubernetes 部署時我們只需要一行命令即可完成服務伸縮
(kubectl scale --replicas=5 deployment/order-service
)。
但對於有狀態的資料庫就不那麼容易了,此時資料庫變成系統的性能瓶頸是顯而易見的。
分庫分表
從微服務的角度來理解垂直拆分其實就是微服務拆分。以限界上下文來定義服務邊界將大服務/單體應用拆分成多個自治的粒度更小的服務,因為自治性規範要求,資料庫也需要進行業務拆分。
但垂直拆分後的單個微服務依然會面臨 TPS/存儲容量 的挑戰,所以這裡我們重點討論水平拆分的方式。
資料庫分庫分表方案是邏輯統一,物理分區自治的方案。其核心設計在於中間層映射方案的設計 (上圖 Mapping),即分片演算法的設計。
幾乎所有編程語言都內置實現了散列表(java:HashMap
/csharp:Dictionary
/python:dict
/go:map
...)。分片演算法跟散列表高度相似(hashCode
),都得通過 key
/shardingValue
映射到對應的槽位(slot
)。
那麼 shardingValue
從哪裡來呢?CosId!!!
CosId:分散式 ID 生成器
CosId 旨在提供通用、靈活、高性能的分散式 ID 生成器。CosId 目前提供了以下三種演算法:
SnowflakeId
: 單機 TPS 性能:409W/s , 主要解決 時鐘回撥問題 、機器號分配問題 並且提供更加友好、靈活的使用體驗。SegmentId
: 每次獲取一段 (Step
) ID,來降低號段分發器的網路IO請求頻次提升性能,提供多種存儲後端:關係型資料庫、Redis、Zookeeper 供用戶選擇。SegmentChainId
(推薦):SegmentChainId
(lock-free) 是對SegmentId
的增強。性能可達到近似AtomicLong
的 TPS 性能:12743W+/s。
shardingValue
問題解決了,但這就夠了嗎?ShardingSphere!!!
摘自 CosId 官網:https://github.com/Ahoo-Wang/CosId
ShardingSphere
Apache ShardingSphere 是一款開源分散式資料庫生態項目,由 JDBC、Proxy 和 Sidecar(規劃中) 3 款產品組成。其核心採用可插拔架構,通過組件擴展功能。對上以資料庫協議及 SQL 方式提供諸多增強功能,包括數據分片、訪問路由、數據安全等;對下原生支持 MySQL、PostgreSQL、SQL Server、Oracle 等多種數據存儲引擎。Apache ShardingSphere 項目理念,是提供資料庫增強計算服務平臺,進而圍繞其上構建生態。充分利用現有資料庫的計算與存儲能力,通過插件化方式增強其核心能力,為企業解決在數字化轉型中面臨的諸多使用難點,為加速數字化應用賦能。
摘自 Apache ShardingSphere 官網:https://shardingsphere.apache.org/index_zh.html
接下來進入本文的主要內容:如何基於 ShardingSphere 可插拔架構(SPI)來集成 CosId,以及應用配置指南。
安裝
以 Spring-Boot 應用 為例
- ShardingSphere v5.1.0+
因為
ShardingSphere v5.1.0
PR,已經合併了 cosid-shardingsphere 模塊,所以只需要引用ShardingSphere
依賴即可。
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.1.1</version>
</dependency>
- ShardingSphere v5.0.0
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>me.ahoo.cosid</groupId>
<artifactId>cosid-shardingsphere</artifactId>
<version>1.8.15</version>
</dependency>
分散式 ID
KeyGenerateAlgorithm
UML Class Diagram
上圖展示了目前所有
ShardingSphere
內置的KeyGenerateAlgorithm
實現,這裡我們只講CosIdKeyGenerateAlgorithm
,其他實現請閱讀https://shardingsphere.apache.org/document/current/cn/features/sharding/concept/key-generator/。
CosIdKeyGenerateAlgorithm
配置
type: COSID
名稱 | 數據類型 | 說明 | 預設值 |
---|---|---|---|
id-name | String |
IdGenerator 的名稱(在 IdGeneratorProvider 中已註冊) |
__share__ |
as-string | String |
是否生成字元串類型的ID | fasle |
spring:
shardingsphere:
rules:
sharding:
key-generators:
cosid:
type: COSID
props:
id-name: __share__
分片演算法
ShardingAlgorithm
UML Class Diagram
CosIdModShardingAlgorithm
CosId取模分片演算法
演算法說明
單值分片鍵(
PreciseShardingValue
)演算法複雜度:O(1)
。範圍值分片鍵(
RangeShardingValue
)演算法複雜度:O(N)
,其中N
為範圍值個數。
性能基準測試
精確值/單值(PreciseShardingValue) | 範圍值/多值(RangeShardingValue) |
---|---|
配置
type: COSID_MOD
名稱 | 數據類型 | 說明 | 預設值 |
---|---|---|---|
logic-name-prefix | String |
邏輯表/數據源名首碼 | |
mod | int |
除數 |
spring:
shardingsphere:
rules:
sharding:
sharding-algorithms:
alg-name:
type: COSID_MOD
props:
mod: 4
logic-name-prefix: t_table_
CosIdIntervalShardingAlgorithm
基於間隔的時間範圍分片演算法。
演算法說明
精確值/單值分片鍵(
PreciseShardingValue
)演算法複雜度:O(1)
。範圍值分片鍵(
RangeShardingValue
)演算法複雜度:O(N)
,其中N
為範圍值單位時間個數。
性能基準測試
精確值/單值(PreciseShardingValue) | 範圍值/多值(RangeShardingValue) |
---|---|
配置
type: COSID_INTERVAL
名稱 | 數據類型 | 說明 | 預設值 |
---|---|---|---|
logic-name-prefix | String |
邏輯表/數據源名首碼 | |
datetime-lower | String |
時間分片下界值,時間戳格式:yyyy-MM-dd HH:mm:ss |
|
datetime-upper | String |
時間分片上界值,時間戳格式:yyyy-MM-dd HH:mm:ss |
|
sharding-suffix-pattern | String |
分片真實表/數據源尾碼格式 | |
datetime-interval-unit | ChronoUnit |
分片鍵時間間隔單位 | |
datetime-interval-amount | int |
分片鍵時間間隔 | |
ts-unit | String |
時間戳單位:SECOND /MILLISECOND |
MILLISECOND |
zone-id | String |
分片鍵時區 | ZoneId.systemDefault().getId() |
spring:
shardingsphere:
rules:
sharding:
sharding-algorithms:
alg-name:
type: COSID_INTERVAL
props:
logic-name-prefix: logic-name-prefix
datetime-lower: 2021-12-08 22:00:00
datetime-upper: 2022-12-01 00:00:00
sharding-suffix-pattern: yyyyMM
datetime-interval-unit: MONTHS
datetime-interval-amount: 1
CosIdSnowflakeIntervalShardingAlgorithm
演算法說明
我們知道 SnowflakeId 的位分區方式,SnowflakeId 可以解析出時間戳,即 SnowflakeId 可以作為時間,所以 SnowflakeId 可以作為 INTERVAL 的分片演算法的分片值。
(當沒有CreateTime
可用作分片時[這是一個非常極端的情況],或者對性能有非常極端的要求時, 分散式ID主鍵 作為查詢範圍可能是持久層性能更好的選擇。 )
配置
type: COSID_INTERVAL_SNOWFLAKE
名稱 | 數據類型 | 說明 | 預設值 |
---|---|---|---|
logic-name-prefix | String |
邏輯表/數據源名首碼 | |
datetime-lower | String |
時間分片下界值,時間戳格式:yyyy-MM-dd HH:mm:ss |
|
datetime-upper | String |
時間分片上界值,時間戳格式:yyyy-MM-dd HH:mm:ss |
|
sharding-suffix-pattern | String |
分片真實表/數據源尾碼格式 | |
datetime-interval-unit | ChronoUnit |
分片鍵時間間隔單位 | |
datetime-interval-amount | int |
分片鍵時間間隔 | |
id-name | String |
IdGenerator 的名稱(在 IdGeneratorProvider 中已註冊) |
__share__ |
spring:
shardingsphere:
rules:
sharding:
sharding-algorithms:
alg-name:
type: COSID_INTERVAL_SNOWFLAKE
props:
logic-name-prefix: logic-name-prefix
datetime-lower: 2021-12-08 22:00:00
datetime-upper: 2022-12-01 00:00:00
sharding-suffix-pattern: yyyyMM
datetime-interval-unit: MONTHS
datetime-interval-amount: 1
id-name: cosid-name
總結
本文主要討論了分庫分表產生的背景以及如何基於 ShardingSphere 可插拔架構集成 CosId 的應用實戰。
ShardingSphere 採用可插拔架構,使得開發者非常方便的自定義滿足自身應用場景的功能擴展,如果你也對參與 ShardingSphere 社區貢獻感興趣請參考 https://shardingsphere.apache.org/community/cn/contribute/contributor/ 。
閱讀源碼的小技巧之類圖
相信很多小伙伴在閱讀源碼過程中總是難以自拔的遍歷式以方法為單位一行行查看源碼的實現細節,以至於迷失在細節中(如果你還能堅持下來,那真是佩服你的毅力之堅韌!)。這樣的閱讀方式是非常糟糕的、低效的。
閱讀源碼跟閱讀書籍一樣有非常多的相似之處:先建立一個概覽圖(索引),然後再逐層往下精進。(自上而下的方式更有利於閱讀過程中不迷失在具體細節中)
推薦大家使用IDEA的插件 Diagrams 用於生成源碼級別的概覽圖:UML類圖。
- IntelliJ IDEA: https://www.jetbrains.com/help/idea/class-diagram.html
引用說明
- ShardingSphere 官方文檔:https://shardingsphere.apache.org/document/current/cn/overview/
- IntelliJ IDEA: https://www.jetbrains.com/help/idea/class-diagram.html
- CosId-ShardingSphere: https://cosid.ahoo.me/guide/cosid-shardingsphere.html
作者:Ahoo Wang (阿虎)
Github: https://github.com/Ahoo-Wang/
SmartSql(高性能、高生產力,超輕量級的ORM!): https://github.com/Ahoo-Wang/SmartSql
SmartCode(不只是代碼生成器!): https://github.com/Ahoo-Wang/SmartCode
CoSky 高性能、低成本微服務治理平臺 : https://github.com/Ahoo-Wang/CoSky
CosId 通用、靈活、高性能的分散式 ID 生成器 : https://github.com/Ahoo-Wang/CosId
Govern EventBus 歷經多年生產環境驗證的事件驅動架構框架: https://github.com/Ahoo-Wang/govern-eventbus
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。