国产精品高清一区二区三区不卡-国产精品一区二区三区免费视频-日韩免费高清一级毛片-亚洲欧美一区二区三区国产精品-日韩欧美一区二区三区不卡视频-亚欧免费视频一区二区三区-亚洲欧美日韩一区成人-欧美日韩视频综合一区无弹窗-精品日韩在线视频一区二区三区-国内精品视频一区二区三区

你好,歡迎進(jìn)入江蘇優(yōu)軟數(shù)字科技有限公司官網(wǎng)!

誠信、勤奮、創(chuàng)新、卓越

友好定價(jià)、專業(yè)客服支持、正版軟件一站式服務(wù)提供

13262879759

工作日:9:00-22:00

這四種情況下,才是考慮分庫分表的時(shí)候!

發(fā)布時(shí)間:2023-06-05

瀏覽次數(shù):0

往期熱門文章:

1、往期精選優(yōu)秀博文都在這里了!

2、線上 4 臺(tái)機(jī)器同一時(shí)間全部 OOM,到底發(fā)生了什么?

3、爽啊!Intellij IDEA 神器居然還藏著這些實(shí)用小技巧 !

4、這樣調(diào)優(yōu):讓你的 IDEA 快到飛起來,效率真高!

5、JDK 16 即將發(fā)布,新特性速覽!

來源:https://juejin.im/post/6844903992909103117

數(shù)據(jù)庫困境

不管是IO困境還是CPU困境,數(shù)據(jù)庫的活躍連接數(shù)最終都會(huì)減少,接近甚至達(dá)到數(shù)據(jù)庫能夠承載的活躍連接數(shù)的閾值。 從商業(yè)的角度來看,

即,可用的數(shù)據(jù)庫連接很少或沒有,連接時(shí)可想而知(并發(fā)、吞吐量、崩潰)。

IO困境,CPU困境,橫向分庫

intellij idea 快捷鍵_intellij idea圖標(biāo)_intellij idea 數(shù)據(jù)庫關(guān)系圖

3、場景:系統(tǒng)絕對(duì)并發(fā)增加,分表不能從根本上解決問題,垂直分庫沒有明顯的業(yè)務(wù)歸屬。

4.分析:庫多了,io和cpu的壓力自然可以成倍降低

水平表

3、場景:系統(tǒng)的絕對(duì)并發(fā)沒有增加,但是單表數(shù)據(jù)量過大,影響了SQL效率,增加了CPU負(fù)擔(dān),從而成為進(jìn)退兩難的局面。 可以考慮水平分表。

4、分析:單表數(shù)據(jù)量減少,單條SQL執(zhí)行效率高,自然減輕CPU負(fù)擔(dān)。

垂直分庫

intellij idea 快捷鍵_intellij idea圖標(biāo)_intellij idea 數(shù)據(jù)庫關(guān)系圖

3、場景:系統(tǒng)的絕對(duì)并發(fā)增加,可以可視化一個(gè)單獨(dú)的業(yè)務(wù)模塊。

4、分析:至此,基本可以面向服務(wù)了。 比如:隨著業(yè)務(wù)的發(fā)展,公共配置表、字典表等越來越多,這時(shí)候可以把這類表拆分成一個(gè)單獨(dú)的庫,甚至可以面向服務(wù)。 此外,隨著業(yè)務(wù)的發(fā)展,也孵化出了一套商業(yè)模式。 這時(shí)候可以把相關(guān)的表拆成一個(gè)單獨(dú)的庫,甚至可以服務(wù)化。

垂直表

intellij idea圖標(biāo)_intellij idea 數(shù)據(jù)庫關(guān)系圖_intellij idea 快捷鍵

3.場景:系統(tǒng)絕對(duì)并發(fā)沒有增加,表中記錄不多,數(shù)組多,熱數(shù)據(jù)和非熱數(shù)據(jù)在一起,單行需要的存儲(chǔ)空間數(shù)據(jù)大,使得數(shù)據(jù)庫中緩存的數(shù)據(jù)行減少,查詢時(shí),回家讀取c盤的數(shù)據(jù)形成大量的隨機(jī)讀IO,形成IO困境。

4.分析:可以用列表頁和詳情頁幫助理解。 垂直分表的分表原則是將熱點(diǎn)數(shù)據(jù)(可能被頻繁查詢的數(shù)據(jù))放在一起作為主表,將非熱點(diǎn)數(shù)據(jù)放在一起作為擴(kuò)展表,這樣可以緩存更多的熱點(diǎn)數(shù)據(jù),從而減少隨機(jī)讀IO。 拆解之后,如果要獲取所有的數(shù)據(jù),需要關(guān)聯(lián)兩個(gè)表來獲取數(shù)據(jù)。

但是切記不要使用join,因?yàn)镴oin會(huì)減少CPU負(fù)擔(dān)但是會(huì)將兩個(gè)表耦合在一起(必須在一個(gè)數(shù)據(jù)庫實(shí)例上)。 關(guān)聯(lián)數(shù)據(jù)要在層進(jìn)行,分別獲取主表和擴(kuò)展表的數(shù)據(jù),然后使用關(guān)聯(lián)數(shù)組將所有數(shù)據(jù)關(guān)聯(lián)起來。

分庫分表工具分庫分表引起的問題

分庫分表可以有效緩解單機(jī)單表帶來的性能困境和壓力,突破網(wǎng)絡(luò)IO、硬件資源、連接數(shù)的困境。 同時(shí),也帶來了一些問題。 下面將描述此類問題和解決方法。

事務(wù)一致性問題

分布式事務(wù)

當(dāng)更新內(nèi)容同時(shí)存在于不同庫中時(shí)intellij idea 數(shù)據(jù)庫關(guān)系圖,必然會(huì)造成跨庫事務(wù)問題。 跨分片交易也是分布式交易,沒有簡單的解決方案。 通??梢允褂谩癤A契約”和“兩階段提交”進(jìn)行處理。

分布式事務(wù)可以最大化數(shù)據(jù)庫操作的原子性。 但是,提交事務(wù)時(shí)需要多個(gè)節(jié)點(diǎn)協(xié)調(diào),延誤了提交事務(wù)的時(shí)間點(diǎn),延長了事務(wù)的執(zhí)行時(shí)間,增加了事務(wù)訪問共享資源時(shí)發(fā)生沖突或死鎖的概率。 隨著數(shù)據(jù)庫節(jié)點(diǎn)的增加,這些趨勢會(huì)越來越嚴(yán)重,從而成為系統(tǒng)在數(shù)據(jù)庫層面水平擴(kuò)展的桎梏。

最終一致性

對(duì)于性能要求高但一致性要求低的系統(tǒng),系統(tǒng)的實(shí)時(shí)一致性往往不是很關(guān)鍵,只要在允許的時(shí)間段內(nèi)達(dá)到最終一致性即可,可以采用事務(wù)補(bǔ)償?shù)姆绞健?不同于事務(wù)執(zhí)行過程中發(fā)生錯(cuò)誤時(shí)立即回滾的形式,事務(wù)補(bǔ)償是一種事后檢測和修復(fù)的措施。 一些常見的實(shí)現(xiàn)方式包括:數(shù)據(jù)的對(duì)賬檢測、基于日志的比對(duì)、定期與標(biāo)準(zhǔn)數(shù)據(jù)源同步比對(duì)等。

跨節(jié)點(diǎn)關(guān)聯(lián)查詢加入問題

拆分前,系統(tǒng)中很多列表、明細(xì)表的數(shù)據(jù)可以通過join完成,拆分后,數(shù)據(jù)可能分布在不同的節(jié)點(diǎn)上。 這時(shí)候join帶來的問題就比較麻煩了。 考慮到性能,盡量避免使用 Join 查詢。 一些技巧來解決:

全局表

全局表,也可以看作是“數(shù)據(jù)字典表”,是系統(tǒng)中所有模塊都可能依賴的一些表。 為了防止 join查詢,可以在每個(gè)數(shù)據(jù)庫中保存一份這樣的表。 這種數(shù)據(jù)一般很少改動(dòng),不用怕一致性問題。

陣列冗余

典型的反范式設(shè)計(jì)使用空間換取時(shí)間并避免連接查詢以提高性能。 比如保存訂單表的時(shí)候,也會(huì)保存一份冗余的副本,這樣就可以通過順表查詢訂單明細(xì)找到用戶名,而不用去查詢賣家的用戶表。 但是這些技術(shù)適用的場景也比較有限,比較適合依賴數(shù)組比較少,冗余數(shù)組的一致性很難保證的情況。

數(shù)據(jù)組裝

在系統(tǒng)業(yè)務(wù)層面,查詢分為兩次。 第一次查詢的結(jié)果集找到關(guān)聯(lián)數(shù)據(jù)id,然后第二次根據(jù)id發(fā)起者請(qǐng)求關(guān)聯(lián)數(shù)據(jù),最后將得到的結(jié)果組裝成一個(gè)數(shù)組。 這是一種比較常用的技術(shù)。

ER碎片

在關(guān)系型數(shù)據(jù)庫中,如果表之間的關(guān)系(比如訂單表和訂單明細(xì)表)已經(jīng)確定,并且這些相關(guān)的表記錄存儲(chǔ)在同一個(gè)分片上,這樣可以更好的避免跨分片的分片問題joinintellij idea 數(shù)據(jù)庫關(guān)系圖,join可以在一個(gè)slice內(nèi)進(jìn)行。 在1:1或者1:n的情況下,一般會(huì)根據(jù)主表的ID進(jìn)行字段切分。

跨節(jié)點(diǎn)分頁、排序、功能問題

跨節(jié)點(diǎn)、多數(shù)據(jù)庫查詢時(shí),會(huì)出現(xiàn)limit分頁、排序等問題。 分頁需要按照指定的數(shù)組進(jìn)行排序。 當(dāng)排序后的數(shù)組作為分頁的主鍵時(shí),更容易通過分片規(guī)則定位到指定的分片; 當(dāng)排序數(shù)組不是分片數(shù)組時(shí),它更復(fù)雜。

需要先對(duì)不同分片節(jié)點(diǎn)上的數(shù)據(jù)進(jìn)行排序返回,然后對(duì)不同分片返回的結(jié)果集進(jìn)行匯總重新排序,最后返回給用戶如右圖所示:

intellij idea 快捷鍵_intellij idea 數(shù)據(jù)庫關(guān)系圖_intellij idea圖標(biāo)

上圖只取了首頁的數(shù)據(jù),對(duì)性能影響不是太大。 而如果獲取的page數(shù)量很大,情況就復(fù)雜很多,因?yàn)槊總€(gè)shard節(jié)點(diǎn)的數(shù)據(jù)可能是隨機(jī)的。 為了排序的準(zhǔn)確性,需要對(duì)所有節(jié)點(diǎn)的前N頁的數(shù)據(jù)進(jìn)行排序合并,最后再進(jìn)行整體排序。 這樣的操作會(huì)消耗大量的CPU和顯存資源,所以頁數(shù)越大,系統(tǒng)性能就越差。

在使用Max、Min、Sum、Count等函數(shù)進(jìn)行估算時(shí),也需要先在每個(gè)分片上執(zhí)行相應(yīng)的函數(shù),然后再匯總每個(gè)分片的結(jié)果集進(jìn)行重新估算。

全局場回避問題

在分庫分表環(huán)境下,由于表中的數(shù)據(jù)同時(shí)存在于不同的數(shù)據(jù)庫中,通常使用的自減字段值將無用,難以保證全局唯一性分區(qū)數(shù)據(jù)庫的自生成 ID。 所以需要單獨(dú)設(shè)計(jì)全局字段,防止跨庫字段重復(fù)。 以下是一些策略:

UUID

UUID標(biāo)準(zhǔn)方法為32個(gè)16位補(bǔ)碼,分為5段,方法為8-4-4-4-12的36個(gè)字符。

UUID 是最簡單的解決方案。 本地生成,性能高,無網(wǎng)絡(luò)時(shí)長。 但是,它也有明顯的缺點(diǎn),占用大量的存儲(chǔ)空間。 此外,將索引構(gòu)建為字段并根據(jù)索引進(jìn)行查詢也存在性能問題,尤其是在引擎下。 順序性會(huì)導(dǎo)致索引位置頻繁變化,造成分頁。

結(jié)合數(shù)據(jù)庫維護(hù)字段ID表

在數(shù)據(jù)庫中建表:

????CREATE?TABLE?`sequence`?(??
??????`id`?bigint(20)?unsigned?NOT?NULL?auto_increment,??
??????`stub`?char(1)?NOT?NULL?default?'',??
??????PRIMARY?KEY??(`id`),??
??????UNIQUE?KEY?`stub`?(`stub`)??
????)?ENGINE=MyISAM;

存根數(shù)組設(shè)置為唯一索引,同一個(gè)存根值在表中只有一條記錄,可以同時(shí)作為多個(gè)表的全局ID。 通過改用引擎實(shí)現(xiàn)了更高的性能。 使用了表鎖,表的讀寫是串行的,在并發(fā)時(shí)不用害怕讀取同一個(gè)ID兩次。 當(dāng)需要全局唯一標(biāo)識(shí)時(shí),執(zhí)行:

????REPLACE?INTO?sequence?(stub)?VALUES?('a');??
????SELECT?1561439;??

這種方案比較簡單,但是缺點(diǎn)比較顯著:存在單點(diǎn)問題,對(duì)DB的依賴性強(qiáng)。 當(dāng)DB異常時(shí),整個(gè)系統(tǒng)不可用。 配置主從會(huì)降低可用性。 另外,性能困境僅限于單個(gè)Mysql的讀寫性能。

還有一種字段生成策略,類似表方案,更好的解決了單點(diǎn)和性能困境的問題。 本方案的總體思路是:搭建2臺(tái)以上的服務(wù)器進(jìn)行全局ID的生成,每臺(tái)服務(wù)器上只部署一個(gè)數(shù)據(jù)庫,每個(gè)數(shù)據(jù)庫都有一張表用于記錄當(dāng)前的全局ID。

表中遞減步長為庫數(shù),起始值依次錯(cuò)開,這樣ID生成可以hash到每個(gè)庫

intellij idea圖標(biāo)_intellij idea 快捷鍵_intellij idea 數(shù)據(jù)庫關(guān)系圖

這些方案在兩臺(tái)機(jī)器上平均分配ID生成的壓力,并提供系統(tǒng)容錯(cuò)。 如果第一臺(tái)機(jī)器出現(xiàn)錯(cuò)誤,可以手動(dòng)切換到第二臺(tái)機(jī)器獲取ID。 但是也有幾個(gè)缺點(diǎn):系統(tǒng)增加機(jī)器,橫向擴(kuò)展比較復(fù)雜; 每獲取一個(gè)ID,都要讀取一次DB,對(duì)DB的壓力還是很大的,只能通過堆機(jī)來提升性能。

分布式自增ID算法

該算法解決分布式系統(tǒng)生成全局ID的需求,生成64位Long數(shù)。 這些組件是:

數(shù)據(jù)遷移和擴(kuò)容問題

當(dāng)業(yè)務(wù)快速發(fā)展,面臨性能和存儲(chǔ)困難時(shí),就會(huì)考慮分片設(shè)計(jì)。 這時(shí)候就不可避免地要考慮歷史數(shù)據(jù)的遷移。 通常的做法是先讀取歷史數(shù)據(jù),然后按照指定的分片規(guī)則將數(shù)據(jù)寫入各個(gè)分片節(jié)點(diǎn)。 據(jù)悉,還需要根據(jù)當(dāng)前數(shù)據(jù)量、QPS、業(yè)務(wù)發(fā)展速度進(jìn)行容量規(guī)劃,預(yù)估大概需要的分片數(shù)量(一般建議單表數(shù)據(jù)量在一個(gè)單個(gè)分片不超過1000W)。

什么時(shí)候考慮分庫分表

不是所有的表都需要分片,主要看數(shù)據(jù)縮減的速度。 分割在一定程度上增加了業(yè)務(wù)的復(fù)雜性。 除非萬不得已,不要使用分庫分表的“大招”,杜絕“過度設(shè)計(jì)”和“過早優(yōu)化”。 分庫分表前盡量優(yōu)化:升級(jí)硬件、升級(jí)網(wǎng)絡(luò)、讀寫分離、索引優(yōu)化等。當(dāng)數(shù)據(jù)量達(dá)到單表困境時(shí),考慮分庫分表。

這里的運(yùn)維是指:數(shù)據(jù)庫備份,如果單表太大,備份需要大量的c盤IO和網(wǎng)絡(luò)IO。 在對(duì)大表做DDL時(shí),MYSQL會(huì)鎖住整張表,時(shí)間會(huì)很長,而且這段時(shí)間業(yè)務(wù)不能訪問這張表,影響很大。

大表被頻繁訪問和更新,更容易出現(xiàn)鎖等待。

這里我就不舉例了。 實(shí)際業(yè)務(wù)中可能會(huì)遇到,一些不經(jīng)常訪問或不經(jīng)常更新的數(shù)組要從大表中分離出來。

隨著業(yè)務(wù)的快速發(fā)展,單表的數(shù)據(jù)量會(huì)不斷減少。 當(dāng)性能接近困境時(shí),就要考慮水平切分,做分庫分表。

往期熱門文章:

1、歷史文章分類導(dǎo)讀列表!精選優(yōu)秀博文都在這里了!》

2、萬億級(jí)數(shù)據(jù)應(yīng)該怎么遷移?
3、從應(yīng)用到底層 36張圖帶你進(jìn)入Redis世界
4、寫代碼有這16個(gè)好習(xí)慣,可以減少80%非業(yè)務(wù)的bug
5、順豐快遞:請(qǐng)簽收MySQL靈魂十連

6一個(gè)基于SpringBoot + MyBatis + Vue的代碼生成器
7、Redis 分布式鎖使用不當(dāng),超賣了100瓶飛天茅臺(tái)?。?!

8、如何設(shè)計(jì)訂單系統(tǒng)?這篇寫得太好了!
9、如果MySQL磁盤滿了,會(huì)發(fā)生什么?還真被我遇到了!
10、阿里開源的27個(gè)項(xiàng)目,值得收藏!

如有侵權(quán)請(qǐng)聯(lián)系刪除!

13262879759

微信二維碼