數(shù)據(jù)庫(kù)分庫(kù)分表架構(gòu)實(shí)踐_第1頁(yè)
數(shù)據(jù)庫(kù)分庫(kù)分表架構(gòu)實(shí)踐_第2頁(yè)
數(shù)據(jù)庫(kù)分庫(kù)分表架構(gòu)實(shí)踐_第3頁(yè)
數(shù)據(jù)庫(kù)分庫(kù)分表架構(gòu)實(shí)踐_第4頁(yè)
數(shù)據(jù)庫(kù)分庫(kù)分表架構(gòu)實(shí)踐_第5頁(yè)
已閱讀5頁(yè),還剩7頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、 數(shù)據(jù)庫(kù)分庫(kù)分表架構(gòu)實(shí)踐1題記“分庫(kù)分表”是談?wù)摂?shù)據(jù)庫(kù)架構(gòu)和優(yōu)化時(shí)經(jīng)常聽(tīng)到的關(guān)鍵詞。那么對(duì)于這些業(yè)務(wù)量正在高速增長(zhǎng)的公司,它有那么容易實(shí)踐嗎?在談?wù)摂?shù)據(jù)庫(kù)架構(gòu)和數(shù)據(jù)庫(kù)優(yōu)化的時(shí)候,我們經(jīng)常會(huì)聽(tīng)到“分庫(kù)分表”、“分片”、“Sharding”這樣的關(guān)鍵詞。讓人感到高興的是,這些朋友所服務(wù)的公司業(yè)務(wù)量正在(或者即將面臨)高速增長(zhǎng),技術(shù)方面也面臨著一些挑戰(zhàn)。讓人感到擔(dān)憂的是,他們系統(tǒng)真的就需要“分庫(kù)分表”了嗎?“分庫(kù)分表”有那么容易實(shí)踐嗎?為此,筆者整理了分庫(kù)分表中可能遇到的一些問(wèn)題,并結(jié)合以往經(jīng)驗(yàn)介紹了對(duì)應(yīng)的解決思路和建議。2垂直分表垂直分表在日常開(kāi)發(fā)和設(shè)計(jì)中比較常見(jiàn),通俗的說(shuō)法叫做“大表拆小表”,拆

2、分是基于關(guān)系型數(shù)據(jù)庫(kù)中的“列”(字段)進(jìn)行的。通常情況,某個(gè)表中的字段比較多,可以新建立一張“擴(kuò)展表”,將不經(jīng)常使用或者長(zhǎng)度較大的字段拆分出去放到“擴(kuò)展表”中,如下圖所示:小結(jié)在字段很多的情況下,拆分開(kāi)確實(shí)更便于開(kāi)發(fā)和維護(hù)(筆者曾見(jiàn)過(guò)某個(gè)遺留系統(tǒng)中,一個(gè)大表中包含100多列的)。某種意義上也能避免“跨頁(yè)”的問(wèn)題(MySQL、MSSQL底層都是通過(guò)“數(shù)據(jù)頁(yè)”來(lái)存儲(chǔ)的,“跨頁(yè)”問(wèn)題可能會(huì)造成額外的性能開(kāi)銷,這里不展開(kāi),感興趣的朋友可以自行查閱相關(guān)資料進(jìn)行研究)。拆分字段的操作建議在數(shù)據(jù)庫(kù)設(shè)計(jì)階段就做好。如果是在發(fā)展過(guò)程中拆分,則需要改寫(xiě)以前的查詢語(yǔ)句,會(huì)額外帶來(lái)一定的成本和風(fēng)險(xiǎn),建議謹(jǐn)慎。3垂直分

3、庫(kù)垂直分庫(kù)在“微服務(wù)”盛行的今天已經(jīng)非常普及了。基本的思路就是按照業(yè)務(wù)模塊來(lái)劃分出不同的數(shù)據(jù)庫(kù),而不是像早期一樣將所有的數(shù)據(jù)表都放到同一個(gè)數(shù)據(jù)庫(kù)中。如下圖:小結(jié)系統(tǒng)層面的“服務(wù)化”拆分操作,能夠解決業(yè)務(wù)系統(tǒng)層面的耦合和性能瓶頸,有利于系統(tǒng)的擴(kuò)展維護(hù)。而數(shù)據(jù)庫(kù)層面的拆分,道理也是相通的。與服務(wù)的“治理”和“降級(jí)”機(jī)制類似,我們也能對(duì)不同業(yè)務(wù)類型的數(shù)據(jù)進(jìn)行“分級(jí)”管理、維護(hù)、監(jiān)控、擴(kuò)展等。眾所周知,數(shù)據(jù)庫(kù)往往最容易成為應(yīng)用系統(tǒng)的瓶頸,而數(shù)據(jù)庫(kù)本身屬于“有狀態(tài)”的,相對(duì)于Web和應(yīng)用服務(wù)器來(lái)講,是比較難實(shí)現(xiàn)“橫向擴(kuò)展”的。數(shù)據(jù)庫(kù)的連接資源比較寶貴且單機(jī)處理能力也有限,在高并發(fā)場(chǎng)景下,垂直分庫(kù)一定程度

4、上能夠突破IO、連接數(shù)及單機(jī)硬件資源的瓶頸,是大型分布式系統(tǒng)中優(yōu)化數(shù)據(jù)庫(kù)架構(gòu)的重要手段。然后,很多人并沒(méi)有從根本上搞清楚為什么要拆分,也沒(méi)有掌握拆分的原則和技巧,只是一味的模仿大廠的做法。導(dǎo)致拆分后遇到很多問(wèn)題(例如:跨庫(kù)join,分布式事務(wù)等)。4水平分表水平分表也稱為橫向分表,比較容易理解,就是將表中不同的數(shù)據(jù)行按照一定規(guī)律分布到不同的數(shù)據(jù)庫(kù)表中(這些表保存在同一個(gè)數(shù)據(jù)庫(kù)中),這樣來(lái)降低單表數(shù)據(jù)量,優(yōu)化查詢性能。最常見(jiàn)的方式就是通過(guò)主鍵或者時(shí)間等字段進(jìn)行Hash和取模后拆分。如下圖所示:小結(jié)水平分表,能夠降低單表的數(shù)據(jù)量,一定程度上可以緩解查詢性能瓶頸。但本質(zhì)上這些表還保存在同一個(gè)庫(kù)中,所

5、以庫(kù)級(jí)別還是會(huì)有IO瓶頸。所以,一般不建議采用這種做法。5水平分庫(kù)分表水平分庫(kù)分表與上面講到的水平分表的思想相同,唯一不同的就是將這些拆分出來(lái)的表保存在不同的數(shù)據(jù)中。這也是很多大型互聯(lián)網(wǎng)公司所選擇的做法。如下圖:某種意義上來(lái)講,有些系統(tǒng)中使用的“冷熱數(shù)據(jù)分離”(將一些使用較少的歷史數(shù)據(jù)遷移到其他的數(shù)據(jù)庫(kù)中。而在業(yè)務(wù)功能上,通常默認(rèn)只提供熱點(diǎn)數(shù)據(jù)的查詢),也是類似的實(shí)踐。在高并發(fā)和海量數(shù)據(jù)的場(chǎng)景下,分庫(kù)分表能夠有效緩解單機(jī)和單庫(kù)的性能瓶頸和壓力,突破IO、連接數(shù)、硬件資源的瓶頸。當(dāng)然,投入的硬件成本也會(huì)更高。同時(shí),這也會(huì)帶來(lái)一些復(fù)雜的技術(shù)問(wèn)題和挑戰(zhàn)(例如:跨分片的復(fù)雜查詢,跨分片事務(wù)等)6分庫(kù)分

6、表的難點(diǎn)垂直分庫(kù)帶來(lái)的問(wèn)題和解決思路:跨庫(kù)join的問(wèn)題在拆分之前,系統(tǒng)中很多列表和詳情頁(yè)所需的數(shù)據(jù)是可以通過(guò)sql join來(lái)完成的。而拆分后,數(shù)據(jù)庫(kù)可能是分布式在不同實(shí)例和不同的主機(jī)上,join將變得非常麻煩。而且基于架構(gòu)規(guī)范,性能,安全性等方面考慮,一般是禁止跨庫(kù)join的。那該怎么辦呢?首先要考慮下垂直分庫(kù)的設(shè)計(jì)問(wèn)題,如果可以調(diào)整,那就優(yōu)先調(diào)整。如果無(wú)法調(diào)整的情況,下面筆者將結(jié)合以往的實(shí)際經(jīng)驗(yàn),總結(jié)幾種常見(jiàn)的解決思路,并分析其適用場(chǎng)景。跨庫(kù)Join的幾種解決思路全局表所謂全局表,就是有可能系統(tǒng)中所有模塊都可能會(huì)依賴到的一些表。比較類似我們理解的“數(shù)據(jù)字典”。為了避免跨庫(kù)join查詢,我

7、們可以將這類表在其他每個(gè)數(shù)據(jù)庫(kù)中均保存一份。同時(shí),這類數(shù)據(jù)通常也很少發(fā)生修改(甚至幾乎不會(huì)),所以也不用太擔(dān)心“一致性”問(wèn)題。字段冗余這是一種典型的反范式設(shè)計(jì),在互聯(lián)網(wǎng)行業(yè)中比較常見(jiàn),通常是為了性能來(lái)避免join查詢。舉個(gè)電商業(yè)務(wù)中很簡(jiǎn)單的場(chǎng)景:“訂單表”中保存“賣家Id”的同時(shí),將賣家的“Name”字段也冗余,這樣查詢訂單詳情的時(shí)候就不需要再去查詢“賣家用戶表”。字段冗余能帶來(lái)便利,是一種“空間換時(shí)間”的體現(xiàn)。但其適用場(chǎng)景也比較有限,比較適合依賴字段較少的情況。最復(fù)雜的還是數(shù)據(jù)一致性問(wèn)題,這點(diǎn)很難保證,可以借助數(shù)據(jù)庫(kù)中的觸發(fā)器或者在業(yè)務(wù)代碼層面去保證。當(dāng)然,也需要結(jié)合實(shí)際業(yè)務(wù)場(chǎng)景來(lái)看一致性的

8、要求。就像上面例子,如果賣家修改了Name之后,是否需要在訂單信息中同步更新呢?數(shù)據(jù)同步定時(shí)A庫(kù)中的tab_a表和B庫(kù)中tbl_b有關(guān)聯(lián),可以定時(shí)將指定的表做同步。當(dāng)然,同步本來(lái)會(huì)對(duì)數(shù)據(jù)庫(kù)帶來(lái)一定的影響,需要性能影響和數(shù)據(jù)時(shí)效性中取得一個(gè)平衡。這樣來(lái)避免復(fù)雜的跨庫(kù)查詢。筆者曾經(jīng)在項(xiàng)目中是通過(guò)ETL工具來(lái)實(shí)施的。系統(tǒng)層組裝在系統(tǒng)層面,通過(guò)調(diào)用不同模塊的組件或者服務(wù),獲取到數(shù)據(jù)并進(jìn)行字段拼裝。說(shuō)起來(lái)很容易,但實(shí)踐起來(lái)可真沒(méi)有這么簡(jiǎn)單,尤其是數(shù)據(jù)庫(kù)設(shè)計(jì)上存在問(wèn)題但又無(wú)法輕易調(diào)整的時(shí)候。具體情況通常會(huì)比較復(fù)雜。下面筆者結(jié)合以往實(shí)際經(jīng)驗(yàn),并通過(guò)偽代碼方式來(lái)描述。簡(jiǎn)單的列表查詢的情況偽代碼很容易理解,先獲

9、取“我的提問(wèn)列表”數(shù)據(jù),然后再根據(jù)列表中的UserId去循環(huán)調(diào)用依賴的用戶服務(wù)獲取到用戶的RealName,拼裝結(jié)果并返回。有經(jīng)驗(yàn)的讀者一眼就能看出上訴偽代碼存在效率問(wèn)題。循環(huán)調(diào)用服務(wù),可能會(huì)有循環(huán)RPC,循環(huán)查詢數(shù)據(jù)庫(kù)不推薦使用。再看看改進(jìn)后的:這種實(shí)現(xiàn)方式,看起來(lái)要優(yōu)雅一點(diǎn),其實(shí)就是把循環(huán)調(diào)用改成一次調(diào)用。當(dāng)然,用戶服務(wù)的數(shù)據(jù)庫(kù)查詢中很可能是In查詢,效率方面比上一種方式更高。(坊間流傳In查詢會(huì)全表掃描,存在性能問(wèn)題,傳聞不可全信。其實(shí)查詢優(yōu)化器都是基本成本估算的,經(jīng)過(guò)測(cè)試,在In語(yǔ)句中條件字段有索引的時(shí)候,條件較少的情況是會(huì)走索引的。這里不細(xì)展開(kāi)說(shuō)明,感興趣的朋友請(qǐng)自行測(cè)試)。小結(jié)簡(jiǎn)單

10、字段組裝的情況下,我們只需要先獲取“主表”數(shù)據(jù),然后再根據(jù)關(guān)聯(lián)關(guān)系,調(diào)用其他模塊的組件或服務(wù)來(lái)獲取依賴的其他字段(如例中依賴的用戶信息),最后將數(shù)據(jù)進(jìn)行組裝。通常,我們都會(huì)通過(guò)緩存來(lái)避免頻繁RPC通信和數(shù)據(jù)庫(kù)查詢的開(kāi)銷。列表查詢帶條件過(guò)濾的情況在上述例子中,都是簡(jiǎn)單的字段組裝,而不存在條件過(guò)濾??床鸱智暗腟QL:這種連接查詢并且還帶條件過(guò)濾的情況,想在代碼層面組裝數(shù)據(jù)其實(shí)是非常復(fù)雜的(尤其是左表和右表都帶條件過(guò)濾的情況會(huì)更復(fù)雜),不能像之前例子中那樣簡(jiǎn)單的進(jìn)行組裝了。試想一下,如果像上面那樣簡(jiǎn)單的進(jìn)行組裝,造成的結(jié)果就是返回的數(shù)據(jù)不完整,不準(zhǔn)確。有如下幾種解決思路:查出所有的問(wèn)答數(shù)據(jù),然后調(diào)用

11、用戶服務(wù)進(jìn)行拼裝數(shù)據(jù),再根據(jù)過(guò)濾字段state字段進(jìn)行過(guò)濾,最后進(jìn)行排序和分頁(yè)并返回。這種方式能夠保證數(shù)據(jù)的準(zhǔn)確性和完整性,但是性能影響非常大,不建議使用。查詢出state字段符合/不符合的UserId,在查詢問(wèn)答數(shù)據(jù)的時(shí)候使用in/not in進(jìn)行過(guò)濾,排序,分頁(yè)等。過(guò)濾出有效的問(wèn)答數(shù)據(jù)后,再調(diào)用用戶服務(wù)獲取數(shù)據(jù)進(jìn)行組裝。這種方式明顯更優(yōu)雅點(diǎn)。筆者之前在某個(gè)項(xiàng)目的特殊場(chǎng)景中就是采用過(guò)這種方式實(shí)現(xiàn)??鐜?kù)事務(wù)(分布式事務(wù))的問(wèn)題按業(yè)務(wù)拆分?jǐn)?shù)據(jù)庫(kù)之后,不可避免的就是“分布式事務(wù)”的問(wèn)題。以往在代碼中通過(guò)spring注解簡(jiǎn)單配置就能實(shí)現(xiàn)事務(wù)的,現(xiàn)在則需要花很大的成本去保證一致性。7垂直分庫(kù)總結(jié)和實(shí)踐

12、建議本篇中主要描述了幾種常見(jiàn)的拆分方式,并著重介紹了垂直分庫(kù)帶來(lái)的一些問(wèn)題和解決思路。讀者朋友可能還有些問(wèn)題和疑惑。1. 我們目前的數(shù)據(jù)庫(kù)是否需要進(jìn)行垂直分庫(kù)?根據(jù)系統(tǒng)架構(gòu)和公司實(shí)際情況來(lái),如果你們的系統(tǒng)還是個(gè)簡(jiǎn)單的單體應(yīng)用,并且沒(méi)有什么訪問(wèn)量和數(shù)據(jù)量,那就別著急折騰“垂直分庫(kù)”了,否則沒(méi)有任何收益,也很難有好結(jié)果。切記,“過(guò)度設(shè)計(jì)”和“過(guò)早優(yōu)化”是很多架構(gòu)師和技術(shù)人員常犯的毛病。2. 垂直拆分有沒(méi)有原則或者技巧?沒(méi)有什么黃金法則和標(biāo)準(zhǔn)答案。一般是參考系統(tǒng)的業(yè)務(wù)模塊拆分來(lái)進(jìn)行數(shù)據(jù)庫(kù)的拆分。比如“用戶服務(wù)”,對(duì)應(yīng)的可能就是“用戶數(shù)據(jù)庫(kù)”。但是也不一定嚴(yán)格一一對(duì)應(yīng)。有些情況下,數(shù)據(jù)庫(kù)拆分的粒度可能會(huì)比系統(tǒng)拆分的粒度更粗。筆者也確實(shí)見(jiàn)過(guò)有些系統(tǒng)中的某些表原本應(yīng)該放A庫(kù)中的,卻放在了B庫(kù)中。有些庫(kù)和表原本是可以合并的,卻單獨(dú)保存著。還有些表,看起來(lái)放在A庫(kù)中也OK,放在B庫(kù)中也合理。如何設(shè)計(jì)和權(quán)衡,這個(gè)就看實(shí)際情況和架構(gòu)師/開(kāi)發(fā)人員的水平了。3. 上面舉例的都太簡(jiǎn)單了,我們的后臺(tái)報(bào)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論