網(wǎng)站標(biāo)簽名詞搜索排名優(yōu)化軟件
引用
在現(xiàn)代互聯(lián)網(wǎng)業(yè)務(wù)高速擴(kuò)張的背景下,單機(jī)數(shù)據(jù)庫的性能瓶頸與擴(kuò)展性缺陷日益凸顯。分庫分表方案雖能有效解決數(shù)據(jù)存儲壓力,但手動實(shí)現(xiàn)分片路由、跨節(jié)點(diǎn)查詢及分布式事務(wù)管理等復(fù)雜邏輯,往往導(dǎo)致開發(fā)成本劇增且難以維護(hù)。Apache ShardingSphere作為一款輕量級的分布式數(shù)據(jù)庫中間件,通過透明化數(shù)據(jù)分片、讀寫分離和分布式事務(wù)支持,為開發(fā)者提供了開箱即用的企業(yè)級解決方案。
ShardingSphere以“可插拔架構(gòu)”為核心設(shè)計(jì)理念,提供Sharding-JDBC(嵌入式SDK)與Sharding-Proxy(獨(dú)立數(shù)據(jù)庫代理)兩種接入形態(tài),兼顧高性能與多語言兼容性。其標(biāo)準(zhǔn)分片、行表達(dá)式、復(fù)合分片及Hint強(qiáng)制路由等策略,支持從簡單取模分片到多字段聯(lián)合分片的復(fù)雜場景。針對分布式事務(wù)難題,ShardingSphere整合XA強(qiáng)一致性事務(wù)與Seata AT柔性事務(wù)模型,覆蓋金融級一致性需求與高吞吐量業(yè)務(wù)場景。然而,嵌套子查詢、跨庫關(guān)聯(lián)等復(fù)雜SQL的解析限制,仍需開發(fā)者在表結(jié)構(gòu)設(shè)計(jì)階段規(guī)避。
ShardingSphere分布式數(shù)據(jù)庫組件
ShardingSphere并非分布式數(shù)據(jù)庫,只是一個(gè)分布式數(shù)據(jù)庫組件,已代理的形式幫助單體數(shù)據(jù)庫支持分片、分布式事務(wù)、跨節(jié)點(diǎn)查詢。
Sharding-JDBC和Sharding-Proxy對比
Sharding-JDBC適用場景
- 應(yīng)用程序是 Java 編寫的。
- 需要高性能,沒有額外的網(wǎng)絡(luò)開銷。
- 希望有更多的靈活性和自定義能力。
- 需要一個(gè)輕量級的嵌入式解決方案。
- 消耗數(shù)據(jù)庫連接數(shù)更多。
Sharding-Proxy適用場景
- 應(yīng)用程序使用多種編程語言。
- 不希望修改現(xiàn)有的應(yīng)用程序代碼。
- 需要集中管理分片和讀寫分離策略。
- 希望獨(dú)立部署和維護(hù)數(shù)據(jù)庫代理層。
- 消耗數(shù)據(jù)庫連接數(shù)更少。
數(shù)據(jù)庫消耗連接數(shù)對比
Sharding-JDBC消耗數(shù)據(jù)庫連接數(shù) = 應(yīng)用實(shí)例數(shù) * 分片數(shù)據(jù)庫數(shù)。
Sharding-Proxy消耗數(shù)據(jù)庫連接數(shù) = 分片數(shù)據(jù)庫數(shù)。
分布式事務(wù)
本地事務(wù)(默認(rèn))
完全支持非跨庫事務(wù)。例如:僅分表,或分庫但是路由的結(jié)果在單庫中。
完全支持因邏輯異常導(dǎo)致的跨庫事務(wù)。例如:同一事務(wù)中,跨兩個(gè)庫更新。更新完畢后,拋出空指針,則兩個(gè)庫的內(nèi)容都能回滾。
不支持因網(wǎng)絡(luò)、硬件異常導(dǎo)致的跨庫事務(wù)。例如:同一事務(wù)中,跨兩個(gè)庫更新,更新完畢后、未提交之前,第一個(gè)庫宕機(jī),則只有第二個(gè)庫數(shù)據(jù)提交。
XA事務(wù)
ShardingSphere整合Atomikos對XA分布式事務(wù)的支持。執(zhí)行的過程中需要對所需資源進(jìn)行鎖定,它更加適用于執(zhí)行時(shí)間確定的短事務(wù)。對于長事務(wù)來說,整個(gè)事務(wù)進(jìn)行期間對數(shù)據(jù)的獨(dú)占,將會對并發(fā)場景下的性能產(chǎn)生一定的影響。
Base事務(wù)(柔性事務(wù))
BASE事務(wù),屬于柔性事務(wù),數(shù)據(jù)最終一致性。ShardingSphere是基于Seata的AT模式進(jìn)行二階段提交來實(shí)現(xiàn)事務(wù)管理的。
分片策略
標(biāo)準(zhǔn)分片策略
標(biāo)準(zhǔn)分片策略(standard
)適用于具有單一分片鍵的標(biāo)準(zhǔn)分片場景。該策略支持精確分片,即在SQL中包含=
、in
操作符,以及范圍分片,包括BETWEEN AND
、>
、<
、>=
、<=
等范圍操作符。
通過實(shí)現(xiàn)PreciseShardingAlgorithm設(shè)置精準(zhǔn)分片策略,實(shí)現(xiàn)RangeShardingAlgorithm設(shè)置范圍分片策略。
spring:shardingsphere:sharding:#唯一庫數(shù)據(jù),當(dāng)某些查詢沒有明確的分片規(guī)則,#或在某些情況下無法確定數(shù)據(jù)應(yīng)該存儲在哪個(gè)分片中的時(shí)候 #ShardingSphere會將這些操作路由到默認(rèn)的數(shù)據(jù)源default-data-source-name: db0#分庫default-database-strategy:standard:# 添加數(shù)據(jù)分庫字段(根據(jù)字段插入數(shù)據(jù)到那個(gè)表)sharding-column: id#精確分片precise-algorithm-class-name: com.example.sharding_test.strategy.database.DatabasePreciseAlgorithm#范圍分片range-algorithm-class-name: com.example.sharding_test.strategy.database.DatabaseRangeAlgorithm #分表tables:#表名db_user:actual-data-nodes: db$->{0..1}.db_user_$->{0..2}key-generator:column: id # 主鍵IDtype: SNOWFLAKE # 生成策略雪花idtable-strategy:standard:sharding-column: id#精確分片precise-algorithm-class-name: com.example.sharding_test.strategy.table.TablePreciseAlgorithm#范圍分片range-algorithm-class-name: com.example.sharding_test.strategy.table.TableRangeAlgorithm
行表達(dá)式分片策略
行表達(dá)式分片策略(inline
)適用于具有單一分片鍵的簡單分片場景,支持SQL語句中=
和in
操作符。它的配置相當(dāng)簡潔,該分片策略支持在配置屬性algorithm-expression
中書寫Groovy
表達(dá)式,用來定義對分片健的運(yùn)算邏輯,無需單獨(dú)定義分片算法了。
spring:shardingsphere:sharding:#唯一庫數(shù)據(jù)default-data-source-name: db0#分庫default-database-strategy:inline:# 添加數(shù)據(jù)分表字段(根據(jù)字段插入數(shù)據(jù)到那個(gè)表)sharding-column: id# 分片算法表達(dá)式 => 通過id取余algorithm-expression: db$->{id % 2}#分表tables:#表名db_user:actual-data-nodes: db$->{0..1}.db_user_$->{0..2}key-generator:column: id # 主鍵IDtype: SNOWFLAKE # 生成策略雪花idinline:# 添加數(shù)據(jù)分表字段(根據(jù)字段插入數(shù)據(jù)到那個(gè)表)sharding-column: id# 分片算法表達(dá)式 => 通過id取余algorithm-expression: db_user_$->{id % 3}
復(fù)合分片策略
復(fù)合分片策略(complex)適用于多個(gè)分片鍵的復(fù)雜分片場景,屬性sharding-columns中多個(gè)分片鍵以逗號分隔。支持 SQL 語句中有>、>=、<=、<、=、IN 和 BETWEEN AND 等操作符。
比如:我們希望通過user_id和order_id等多個(gè)字段共同運(yùn)算得出數(shù)據(jù)路由到具體哪個(gè)分片中,就可以應(yīng)用該策略。
通過實(shí)現(xiàn)ComplexKeysShardingAlgorithm自定義分庫、分表策略。
spring:shardingsphere:sharding:#唯一庫數(shù)據(jù)default-data-source-name: db0#分庫default-database-strategy:#復(fù)合分片complex:sharding-columns: id,agealgorithm-class-name: com.example.sharding_test.strategy.database.DatabaseComplexAlgorithm#分表tables:#表名db_user:actual-data-nodes: db$->{0..1}.db_user_$->{0..2}key-generator:column: id # 主鍵IDtype: SNOWFLAKE # 生成策略雪花idtable-strategy:#復(fù)合分片complex:sharding-columns: id,agealgorithm-class-name: com.example.sharding_test.strategy.table.TableComplexAlgorithm
Hint分片策略
該策略無需配置分片健,由外部指定分庫和分表的信息,可以讓SQL在指定的分庫、分表中執(zhí)行。
通過實(shí)現(xiàn)HintShardingAlgorithm自定義分片策略。
spring:shardingsphere:sharding:#唯一庫數(shù)據(jù)default-data-source-name: db0#分庫default-database-strategy:#行分片inline:# 添加數(shù)據(jù)分表字段(根據(jù)字段插入數(shù)據(jù)到那個(gè)表)sharding-column: id# 分片算法表達(dá)式 => 通過id取余algorithm-expression: db$->{id % 2}#分表tables:#表名db_user:actual-data-nodes: db$->{0..1}.db_user_$->{0..2}key-generator:column: id # 主鍵IDtype: SNOWFLAKE # 生成策略雪花idtable-strategy:#強(qiáng)制分片hint:algorithm-class-name: com.example.sharding_test.strategy.table.TableHintAlgorithm
package com.example.sharding_test.strategy.table;import org.apache.shardingsphere.api.sharding.hint.HintShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.hint.HintShardingValue;
import java.util.Arrays;
import java.util.Collection;public class TableHintAlgorithm implements HintShardingAlgorithm<Integer> {@Overridepublic Collection<String> doSharding(Collection<String> collection, HintShardingValue<Integer> hintShardingValue) {String logicTableName = hintShardingValue.getLogicTableName();// 取代碼中通過addTableShardingValue設(shè)置表序號String dbName = logicTableName + "_" + hintShardingValue.getValues().toArray()[0];return Arrays.asList(dbName);}
}// 測試用例,代碼中通過addTableShardingValue設(shè)置表序號
@Test
void selectHintData(){HintManager manager = HintManager.getInstance();manager.addTableShardingValue("db_user",2);LambdaQueryWrapper<DbUser> wrapper = Wrappers.lambdaQuery();wrapper.eq(DbUser::getAge,34);List<DbUser> dbUsers = dbUserMapper.selectList(wrapper);dbUsers.forEach(System.out::println);
}
不支持語句
- VALUES語句不支持運(yùn)算表達(dá)式
INSERT INTO tbl_name (col1, col2, …) VALUES(1+2, ?, …)
- INSERT … SELECT
INSERT INTO tbl_name (col1, col2, …) SELECT col1, col2, … FROM tbl_name WHERE col3 = ?
- HAVING
SELECT COUNT(col1) as count_alias FROM tbl_name GROUP BY col1 HAVING count_alias > ?
- UNION
SELECT * FROM tbl_name1 UNION SELECT * FROM tbl_name2
- UNION ALL
SELECT * FROM tbl_name1 UNION ALL SELECT * FROM tbl_name2
- 包含schema
SELECT * FROM ds.tbl_name1
- 同時(shí)使用普通聚合函數(shù)和DISTINCT聚合函數(shù)
SELECT SUM(DISTINCT col1), SUM(col1) FROM tbl_name
- 只支持解析一層子查詢,不支持多層嵌套的子查詢
SELECT COUNT(*) FROM (SELECT * FROM t_order o WHERE o.id IN (SELECT id FROM t_order WHERE status = ?))
- 跨庫關(guān)聯(lián)查詢不被支持
感謝您的閱讀!如果文章中有任何問題或不足之處,歡迎及時(shí)指出,您的反饋將幫助我不斷改進(jìn)與完善。期待與您共同探討技術(shù),共同進(jìn)步!