ShardingSphere數(shù)據(jù)分片算法及測試實戰(zhàn)
前言
堅持是一件比較難的事,堅持并不是自欺欺人的一種自我麻痹和安慰,也不是做給被人的,我覺得,堅持的本質(zhì)并沒有帶著過多的功利主義,如果滿是功利主義,那么這個堅持并不會長久,也不會有好的收獲,堅持應(yīng)該帶著熱愛,帶著思想,把它當(dāng)成習(xí)慣,但是并不是內(nèi)卷,而是一種發(fā)自內(nèi)心的喜歡和平實!希望我們都有自己的堅持,堅持寫一篇文章,堅持愛一個人,堅持讀一本書,堅持走向遠方!
上一篇我們說了ShardingSphere的讀寫分離,使用讀寫分離能夠減輕單庫的讀寫操作,從而提升數(shù)據(jù)庫的吞吐量,但是當(dāng)數(shù)據(jù)庫中表的數(shù)據(jù)量到達一定數(shù)量時,我們可能就會需要進行分片了, 分片又分為垂直分片和水平分片,下面我們對二者進行簡單的分析。
垂直分片
我們的一個數(shù)據(jù)庫中通常是有很多數(shù)據(jù)表的,不過可能由于我們的分類不到位,就會出現(xiàn)澇的澇死旱的旱死
的局面,比如某些數(shù)據(jù)表的讀寫操作十分頻繁,而我的這個庫中大量的集中了這種 讀寫操作頻繁的表,那么整體的吞吐量就會降低,而某個庫中又集中了讀寫不頻繁的表,吞吐量十分的高(但是好像沒什么卵用),所以我們應(yīng)該合理的分配,以保證整理的吞吐量達到最大值, 下圖將數(shù)據(jù)表各分到了一個數(shù)據(jù)庫中。
不過垂直分片不能從根本上解決讀寫瓶頸,因為不管你再怎么分,所有的數(shù)據(jù)始終都集中在一張表里面,就算數(shù)據(jù)庫的性能再好,也解決不了這個問題。所以我們需要進行 更加細粒度的劃分,下面我們來講解水平分片。
水平分片
水平分片又可以叫做橫向拆分
,就是將一張大表拆分為若干張小表,比如我一張表中有1億條數(shù)據(jù),那么我拆分為10張表,每張表中存1000萬條數(shù)據(jù),那么效率就會變高, 還有些數(shù)據(jù)需要進行分類和歸檔,那么我們也需要進行分表,之前我們系統(tǒng)中一個表用來存儲文檔信息,有十多年因為數(shù)據(jù)量十分龐大,在業(yè)務(wù)中需要對文檔進行排序等操作,本來查詢就比較 耗時了,再加上需要進行邏輯上的處理,所以就更加耗時,于是就進行了分表,將每一年的數(shù)據(jù)存進一個表,這樣就提高了查詢效率,并且更加容易對數(shù)據(jù)進行追蹤和管理,如下就是水平 分片的圖例。
ShardingSphere數(shù)據(jù)分片實戰(zhàn)
使用ShardingSphere數(shù)據(jù)分片,我們只需通過簡單的配置就能實現(xiàn),ShardingSphere幫我們屏蔽了底層邏輯,我們也可通過ShardingSphere預(yù)留的 接口和SPI進行擴展我們的需求,比如可以實現(xiàn)我們自己的分片算法,主鍵生成策略等等。
下面演示將文檔按照年份進行分表,將文檔數(shù)據(jù)分表至2013年至2022年來存,一般我們的配置文件都是配置在nacos上面,所以能夠靈活的進行配置, 當(dāng)?shù)搅?023年,我們可以添加一個2023年的表,改下nacos的配置,當(dāng)然,一般會先預(yù)留出數(shù)據(jù)表,nacos上面也留出空間,我們的是預(yù)留到2032年, 留出了10年。
yml文件
我們重點關(guān)注下面的一些配置,actual-data-nodes
代表進行分片的表,使用表達式,document.document_$->{2013..2022}
代表document數(shù)據(jù)庫 下面的document_前綴的表進行分片,如document_2022
,document_2021
,{2013..2022}
代表2013到2022這個區(qū)間,sharding-column
是分片列, 是我們數(shù)據(jù)表中的某個字段,就是根據(jù)它來進行分片,sharding-algorithms
是分片算法,我們可以通過SPI來實現(xiàn)自己的分片算法,接口是StandardShardingAlgorithm
, 如下我們使用的是INLINE
基于行表達式的分片算法,algorithm-expression
是分片表達式,ShardingSphere底層會進行解析表達式,然后分片到對應(yīng)的數(shù)據(jù)表上面, 我們的表達式是document_$->{year}
,也就是根據(jù)年進行分片,當(dāng)然,我們可以根據(jù)自己的需求去寫表達式,比如根據(jù)主鍵取模進行分片等,需要根據(jù)我們的實際場景去做, key-generate-strategy
是主鍵生成策略,ShardingSphere支持自定義主鍵生成策略,我們只需要通過SPI就可以實現(xiàn),接口是KeyGenerateAlgorithm
,已經(jīng) 實現(xiàn)了UUID
和snowflake雪花算法
等主鍵生成策略。
spring: shardingsphere: mode: type: Standalone repository: type: File overwrite: true datasource: names: document document: jdbc-url: jdbc:mysql://localhost:3306/document?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8 type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.jdbc.Driver username: root password: qwer123@ rules: sharding: tables: document: actual-data-nodes: document.document_$->{2013..2022} table-strategy: standard: sharding-column: year #分片列 sharding-algorithm-name: document-inline # 分片算法名稱 key-generate-strategy: column: id # 主鍵列 key-generator-name: timestamp #主鍵生成算法 sharding-algorithms: #分片算法 document-inline: type: INLINE props: algorithm-expression: document_$->{year} key-generators: timestamp: type: SNOWFLAKE
測試數(shù)據(jù)數(shù)據(jù)分片
虛幻插入十次,每次都插入2013年到2022年的數(shù)據(jù)。
void addDocSliceYear(){ for (int i = 0; i < 10; i++) { for (int year = 2013; year <= 2022; year++) { Document document = new Document() .setDocumentName("document year【" + year + "】") .setDocumentDetail("year【" + year + "】") .setYear(year); documentService.save(document); } } }
我們可以看出,數(shù)據(jù)分片成功,我們看一下分片的數(shù)據(jù)怎么查詢的(此處只是單表查詢),我們看一下ShardingSphere-SQL
輸出的sql語句
SELECT id,document_name,document_detail,year FROM document_2013 UNION ALL SELECT id,document_name,document_detail,year FROM document_2014 UNION ALL SELECT id,document_name,document_detail,year FROM document_2015 UNION ALL SELECT id,document_name,document_detail,year FROM document_2016 UNION ALL SELECT id,document_name,document_detail,year FROM document_2017 UNION ALL SELECT id,document_name,document_detail,year FROM document_2018 UNION ALL SELECT id,document_name,document_detail,year FROM document_2019 UNION ALL SELECT id,document_name,document_detail,year FROM document_2020 UNION ALL SELECT id,document_name,document_detail,year FROM document_2021 UNION ALL SELECT id,document_name,document_detail,year FROM document_2022
從控制臺打印的SQL語句中看出,ShardingSphere分片查詢使用的是UNION ALL
,UNION ALL實現(xiàn)把前后兩個SELECT集合的數(shù)據(jù)聯(lián)合起來,組成一個結(jié)果集查詢輸出, 聯(lián)合查詢需要每個表中的的字段相同,字段類型相同,數(shù)量相同,這也是分片的基本要求。
上面我們只演示了單表的數(shù)據(jù)分片查詢,如果是多表查詢,我們需要配置binding-tables
綁定表,這樣能夠減少查詢的笛卡爾積,從而提升查詢效率,我們就不做 詳細的介紹,可去官網(wǎng)自己查看。
分片算法
ShardingSphere的分片算法有多種,我們也可以自己實現(xiàn)一套分片算法,通過SPI,分片算法的頂層接口是ShardingAlgorithm
,目前實現(xiàn)了多種算法。
BoundaryBasedRangeShardingAlgorithm: 基于分片邊界的范圍分片算法
VolumeBasedRangeShardingAlgorithm: 基于分片容量的范圍分片算法
ComplexInlineShardingAlgorithm: 基于行表達式的復(fù)合分片算法
AutoIntervalShardingAlgorithm: 基于可變時間范圍的分片算法
ClassBasedShardingAlgorithm: 基于自定義類的分片算法
HintInlineShardingAlgorithm: 基于行表達式的 Hint 分片算法
IntervalShardingAlgorithm: 基于固定時間范圍的分片算法
HashModShardingAlgorithm: 基于哈希取模的分片算法
InlineShardingAlgorithm: 基于行表達式的分片算法
ModShardingAlgorithm: 基于取模的分片算法
CosIdModShardingAlgorithm: 基于 CosId 的取模分片算法
CosIdIntervalShardingAlgorithm: 基于 CosId 的固定時間范圍的分片算法
CosIdSnowflakeIntervalShardingAlgorithm: 基于 CosId 的雪花ID固定時間范圍的分片算法
分布式主鍵生成算法
ShardingSphere也可以自定義實現(xiàn)主鍵生成策略,通過SPI,頂層接口為KeyGenerateAlgorithm
,目前實現(xiàn)的算法有。
SnowflakeKeyGenerateAlgorithm 基于雪花算法的分布式主鍵生成算法
UUIDKeyGenerateAlgorithm: 基于 UUID 的分布式主鍵生成算法
CosIdKeyGenerateAlgorithm: 基于 CosId 的分布式主鍵生成算法
CosIdSnowflakeKeyGenerateAlgorithm: 基于 CosId 的雪花算法分布式主鍵生成算法
NanoIdKeyGenerateAlgorithm: 基于 NanoId 的分布式主鍵生成算法
總結(jié)
ShardingSphere能夠方便的實現(xiàn)數(shù)據(jù)分片,但是數(shù)據(jù)分片本身就是一件迫不得已的事情,它會是我們的業(yè)務(wù)變得更加的復(fù)雜,在設(shè)計的時候需要經(jīng)過嚴(yán)格的考量后再進行數(shù)據(jù)分片,防止出現(xiàn)一些不必要的麻煩。
關(guān)于ShardingSphere的數(shù)據(jù)分片,我們就說到這里,更多關(guān)于ShardingSphere數(shù)據(jù)分片的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決MyEclipse出現(xiàn)the user operation is waiting的問題
今天做項目的時候每次修改代碼保存后都會跳出一個框框,然后就有兩個進度條,上面寫the user operation is wating...小編去網(wǎng)上查了查解決了這個問題,下面跟大家分享一下。2018-04-04IntelliJ IDEA使用maven實現(xiàn)tomcat的熱部署
這篇文章主要介紹了IntelliJ IDEA使用maven實現(xiàn)tomcat的熱部署,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07springboot項目中的bootstrap.yml配置不生效的原因及解決(沒有自動提示)
新創(chuàng)建一個 springboot項目,添加了 bootstrap.yml 文件,發(fā)現(xiàn)文件并沒有如預(yù)期變成綠色葉子,編寫的時候也沒有自動提示,啟動的時候,發(fā)現(xiàn)端口是8080,由此發(fā)現(xiàn)配置并沒有生效,所以本文給大家講解了springboot項目中的bootstrap.yml配置不生效的原因及解決2024-01-01