日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

分库分表的几种常见形式以及可能遇到的难题--转

發(fā)布時間:2025/4/5 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分库分表的几种常见形式以及可能遇到的难题--转 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文地址:http://chuansong.me/n/720045751960

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

垂直分表

垂直分表在日常開發(fā)和設(shè)計(jì)中比較常見,通俗的說法叫做“大表拆小表”,拆分是基于關(guān)系型數(shù)據(jù)庫中的“列”(字段)進(jìn)行的。通常情況,某個表中的字段比較多,可以新建立一張“擴(kuò)展表”,將不經(jīng)常使用或者長度較大的字段拆分出去放到“擴(kuò)展表”中,如下圖所示:



小結(jié)

在字段很多的情況下,拆分開確實(shí)更便于開發(fā)和維護(hù)(筆者曾見過某個遺留系統(tǒng)中,一個大表中包含100多列的)。某種意義上也能避免“跨頁”的問題(MySQL、MSSQL底層都是通過“數(shù)據(jù)頁”來存儲的,“跨頁”問題可能會造成額外的性能開銷,這里不展開,感興趣的朋友可以自行查閱相關(guān)資料進(jìn)行研究)。

拆分字段的操作建議在數(shù)據(jù)庫設(shè)計(jì)階段就做好。如果是在發(fā)展過程中拆分,則需要改寫以前的查詢語句,會額外帶來一定的成本和風(fēng)險,建議謹(jǐn)慎。

垂直分庫

垂直分庫在“微服務(wù)”盛行的今天已經(jīng)非常普及了。基本的思路就是按照業(yè)務(wù)模塊來劃分出不同的數(shù)據(jù)庫,而不是像早期一樣將所有的數(shù)據(jù)表都放到同一個數(shù)據(jù)庫中。如下圖:

小結(jié)

系統(tǒng)層面的“服務(wù)化”拆分操作,能夠解決業(yè)務(wù)系統(tǒng)層面的耦合和性能瓶頸,有利于系統(tǒng)的擴(kuò)展維護(hù)。而數(shù)據(jù)庫層面的拆分,道理也是相通的。與服務(wù)的“治理”和“降級”機(jī)制類似,我們也能對不同業(yè)務(wù)類型的數(shù)據(jù)進(jìn)行“分級”管理、維護(hù)、監(jiān)控、擴(kuò)展等。

眾所周知,數(shù)據(jù)庫往往最容易成為應(yīng)用系統(tǒng)的瓶頸,而數(shù)據(jù)庫本身屬于“有狀態(tài)”的,相對于Web和應(yīng)用服務(wù)器來講,是比較難實(shí)現(xiàn)“橫向擴(kuò)展”的。數(shù)據(jù)庫的連接資源比較寶貴且單機(jī)處理能力也有限,在高并發(fā)場景下,垂直分庫一定程度上能夠突破IO、連接數(shù)及單機(jī)硬件資源的瓶頸,是大型分布式系統(tǒng)中優(yōu)化數(shù)據(jù)庫架構(gòu)的重要手段。

然后,很多人并沒有從根本上搞清楚為什么要拆分,也沒有掌握拆分的原則和技巧,只是一味的模仿大廠的做法。導(dǎo)致拆分后遇到很多問題(例如:跨庫join,分布式事務(wù)等)。

水平分表?

水平分表也稱為橫向分表,比較容易理解,就是將表中不同的數(shù)據(jù)行按照一定規(guī)律分布到不同的數(shù)據(jù)庫表中(這些表保存在同一個數(shù)據(jù)庫中),這樣來降低單表數(shù)據(jù)量,優(yōu)化查詢性能。最常見的方式就是通過主鍵或者時間等字段進(jìn)行Hash和取模后拆分。如下圖所示:

小結(jié)

水平分表,能夠降低單表的數(shù)據(jù)量,一定程度上可以緩解查詢性能瓶頸。但本質(zhì)上這些表還保存在同一個庫中,所以庫級別還是會有IO瓶頸。所以,一般不建議采用這種做法。

水平分庫分表

水平分庫分表與上面講到的水平分表的思想相同,唯一不同的就是將這些拆分出來的表保存在不同的數(shù)據(jù)中。這也是很多大型互聯(lián)網(wǎng)公司所選擇的做法。如下圖:

某種意義上來講,有些系統(tǒng)中使用的“冷熱數(shù)據(jù)分離”(將一些使用較少的歷史數(shù)據(jù)遷移到其他的數(shù)據(jù)庫中。而在業(yè)務(wù)功能上,通常默認(rèn)只提供熱點(diǎn)數(shù)據(jù)的查詢),也是類似的實(shí)踐。在高并發(fā)和海量數(shù)據(jù)的場景下,分庫分表能夠有效緩解單機(jī)和單庫的性能瓶頸和壓力,突破IO、連接數(shù)、硬件資源的瓶頸。當(dāng)然,投入的硬件成本也會更高。同時,這也會帶來一些復(fù)雜的技術(shù)問題和挑戰(zhàn)(例如:跨分片的復(fù)雜查詢,跨分片事務(wù)等)

分庫分表的難點(diǎn)

垂直分庫帶來的問題和解決思路:

跨庫join的問題

在拆分之前,系統(tǒng)中很多列表和詳情頁所需的數(shù)據(jù)是可以通過sql join來完成的。而拆分后,數(shù)據(jù)庫可能是分布式在不同實(shí)例和不同的主機(jī)上,join將變得非常麻煩。而且基于架構(gòu)規(guī)范,性能,安全性等方面考慮,一般是禁止跨庫join的。那該怎么辦呢?首先要考慮下垂直分庫的設(shè)計(jì)問題,如果可以調(diào)整,那就優(yōu)先調(diào)整。如果無法調(diào)整的情況,下面筆者將結(jié)合以往的實(shí)際經(jīng)驗(yàn),總結(jié)幾種常見的解決思路,并分析其適用場景。

跨庫Join的幾種解決思路

全局表

所謂全局表,就是有可能系統(tǒng)中所有模塊都可能會依賴到的一些表。比較類似我們理解的“數(shù)據(jù)字典”。為了避免跨庫join查詢,我們可以將這類表在其他每個數(shù)據(jù)庫中均保存一份。同時,這類數(shù)據(jù)通常也很少發(fā)生修改(甚至幾乎不會),所以也不用太擔(dān)心“一致性”問題。

字段冗余

這是一種典型的反范式設(shè)計(jì),在互聯(lián)網(wǎng)行業(yè)中比較常見,通常是為了性能來避免join查詢。

舉個電商業(yè)務(wù)中很簡單的場景:

“訂單表”中保存“賣家Id”的同時,將賣家的“Name”字段也冗余,這樣查詢訂單詳情的時候就不需要再去查詢“賣家用戶表”。

字段冗余能帶來便利,是一種“空間換時間”的體現(xiàn)。但其適用場景也比較有限,比較適合依賴字段較少的情況。最復(fù)雜的還是數(shù)據(jù)一致性問題,這點(diǎn)很難保證,可以借助數(shù)據(jù)庫中的觸發(fā)器或者在業(yè)務(wù)代碼層面去保證。當(dāng)然,也需要結(jié)合實(shí)際業(yè)務(wù)場景來看一致性的要求。就像上面例子,如果賣家修改了Name之后,是否需要在訂單信息中同步更新呢?

數(shù)據(jù)同步

定時A庫中的tab_a表和B庫中tbl_b有關(guān)聯(lián),可以定時將指定的表做同步。當(dāng)然,同步本來會對數(shù)據(jù)庫帶來一定的影響,需要性能影響和數(shù)據(jù)時效性中取得一個平衡。這樣來避免復(fù)雜的跨庫查詢。筆者曾經(jīng)在項(xiàng)目中是通過ETL工具來實(shí)施的。

系統(tǒng)層組裝

在系統(tǒng)層面,通過調(diào)用不同模塊的組件或者服務(wù),獲取到數(shù)據(jù)并進(jìn)行字段拼裝。說起來很容易,但實(shí)踐起來可真沒有這么簡單,尤其是數(shù)據(jù)庫設(shè)計(jì)上存在問題但又無法輕易調(diào)整的時候。

具體情況通常會比較復(fù)雜。下面筆者結(jié)合以往實(shí)際經(jīng)驗(yàn),并通過偽代碼方式來描述。

簡單的列表查詢的情況

?

偽代碼很容易理解,先獲取“我的提問列表”數(shù)據(jù),然后再根據(jù)列表中的UserId去循環(huán)調(diào)用依賴的用戶服務(wù)獲取到用戶的RealName,拼裝結(jié)果并返回。

有經(jīng)驗(yàn)的讀者一眼就能看出上訴偽代碼存在效率問題。循環(huán)調(diào)用服務(wù),可能會有循環(huán)RPC,循環(huán)查詢數(shù)據(jù)庫…不推薦使用。再看看改進(jìn)后的:

這種實(shí)現(xiàn)方式,看起來要優(yōu)雅一點(diǎn),其實(shí)就是把循環(huán)調(diào)用改成一次調(diào)用。當(dāng)然,用戶服務(wù)的數(shù)據(jù)庫查詢中很可能是In查詢,效率方面比上一種方式更高。(坊間流傳In查詢會全表掃描,存在性能問題,傳聞不可全信。其實(shí)查詢優(yōu)化器都是基本成本估算的,經(jīng)過測試,在In語句中條件字段有索引的時候,條件較少的情況是會走索引的。這里不細(xì)展開說明,感興趣的朋友請自行測試)。

小結(jié)

簡單字段組裝的情況下,我們只需要先獲取“主表”數(shù)據(jù),然后再根據(jù)關(guān)聯(lián)關(guān)系,調(diào)用其他模塊的組件或服務(wù)來獲取依賴的其他字段(如例中依賴的用戶信息),最后將數(shù)據(jù)進(jìn)行組裝。

通常,我們都會通過緩存來避免頻繁RPC通信和數(shù)據(jù)庫查詢的開銷。

列表查詢帶條件過濾的情況

在上述例子中,都是簡單的字段組裝,而不存在條件過濾??床鸱智暗腟QL:

這種連接查詢并且還帶條件過濾的情況,想在代碼層面組裝數(shù)據(jù)其實(shí)是非常復(fù)雜的(尤其是左表和右表都帶條件過濾的情況會更復(fù)雜),不能像之前例子中那樣簡單的進(jìn)行組裝了。試想一下,如果像上面那樣簡單的進(jìn)行組裝,造成的結(jié)果就是返回的數(shù)據(jù)不完整,不準(zhǔn)確。?

有如下幾種解決思路:

  • 查出所有的問答數(shù)據(jù),然后調(diào)用用戶服務(wù)進(jìn)行拼裝數(shù)據(jù),再根據(jù)過濾字段state字段進(jìn)行過濾,最后進(jìn)行排序和分頁并返回。

    這種方式能夠保證數(shù)據(jù)的準(zhǔn)確性和完整性,但是性能影響非常大,不建議使用。

  • 查詢出state字段符合/不符合的UserId,在查詢問答數(shù)據(jù)的時候使用in/not in進(jìn)行過濾,排序,分頁等。過濾出有效的問答數(shù)據(jù)后,再調(diào)用用戶服務(wù)獲取數(shù)據(jù)進(jìn)行組裝。

    這種方式明顯更優(yōu)雅點(diǎn)。筆者之前在某個項(xiàng)目的特殊場景中就是采用過這種方式實(shí)現(xiàn)。

  • 跨庫事務(wù)(分布式事務(wù))的問題

    按業(yè)務(wù)拆分?jǐn)?shù)據(jù)庫之后,不可避免的就是“分布式事務(wù)”的問題。以往在代碼中通過spring注解簡單配置就能實(shí)現(xiàn)事務(wù)的,現(xiàn)在則需要花很大的成本去保證一致性。這里不展開介紹,?
    感興趣的讀者可以自行參考《分布式事務(wù)一致性解決方案》,鏈接地址:?
    http://www.infoq.com/cn/articles/solution-of-distributed-system-transaction-consistency

    垂直分庫總結(jié)和實(shí)踐建議

    本篇中主要描述了幾種常見的拆分方式,并著重介紹了垂直分庫帶來的一些問題和解決思路。讀者朋友可能還有些問題和疑惑。

    1. 我們目前的數(shù)據(jù)庫是否需要進(jìn)行垂直分庫?

    根據(jù)系統(tǒng)架構(gòu)和公司實(shí)際情況來,如果你們的系統(tǒng)還是個簡單的單體應(yīng)用,并且沒有什么訪問量和數(shù)據(jù)量,那就別著急折騰“垂直分庫”了,否則沒有任何收益,也很難有好結(jié)果。

    切記,“過度設(shè)計(jì)”和“過早優(yōu)化”是很多架構(gòu)師和技術(shù)人員常犯的毛病。?

    2. 垂直拆分有沒有原則或者技巧?

    沒有什么黃金法則和標(biāo)準(zhǔn)答案。一般是參考系統(tǒng)的業(yè)務(wù)模塊拆分來進(jìn)行數(shù)據(jù)庫的拆分。比如“用戶服務(wù)”,對應(yīng)的可能就是“用戶數(shù)據(jù)庫”。但是也不一定嚴(yán)格一一對應(yīng)。有些情況下,數(shù)據(jù)庫拆分的粒度可能會比系統(tǒng)拆分的粒度更粗。筆者也確實(shí)見過有些系統(tǒng)中的某些表原本應(yīng)該放A庫中的,卻放在了B庫中。有些庫和表原本是可以合并的,卻單獨(dú)保存著。還有些表,看起來放在A庫中也OK,放在B庫中也合理。

    如何設(shè)計(jì)和權(quán)衡,這個就看實(shí)際情況和架構(gòu)師/開發(fā)人員的水平了。?

    3. 上面舉例的都太簡單了,我們的后臺報表系統(tǒng)中join的表都有n個了,?
    分庫后該怎么查?

    有很多朋友跟我提過類似的問題。其實(shí)互聯(lián)網(wǎng)的業(yè)務(wù)系統(tǒng)中,本來就應(yīng)該盡量避免join的,如果有多個join的,要么是設(shè)計(jì)不合理,要么是技術(shù)選型有誤。請自行科普下OLAP和OLTP,報表類的系統(tǒng)在傳統(tǒng)BI時代都是通過OLAP數(shù)據(jù)倉庫去實(shí)現(xiàn)的(現(xiàn)在則更多是借助離線分析、流式計(jì)算等手段實(shí)現(xiàn)),而不該向上面描述的那樣直接在業(yè)務(wù)庫中執(zhí)行大量join和統(tǒng)計(jì)。

    由于篇幅關(guān)系,下篇中我們再繼續(xù)細(xì)聊“水平分庫分表”相關(guān)的話題。

    轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/articles/6544587.html

    總結(jié)

    以上是生活随笔為你收集整理的分库分表的几种常见形式以及可能遇到的难题--转的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 性做久久久久久久久 | 伊人国产女 | 精品在线观看视频 | 四虎tv | 国产αv| 精久久久 | 欧美日韩人妻精品一区二区三区 | 久久国产99| 激情综合网av | 欧美挤奶吃奶水xxxxx | 日韩成人免费在线视频 | 免费91视频 | 麻豆av剧情| 人禽l交视频在线播放 视频 | 少妇久久精品 | 黄色网址大全免费 | 91麻豆精品国产91 | 猛男被粗大男男1069 | 97在线播放 | 农民工hdxxxx性中国 | 一个人在线观看免费视频www | 在线一区二区观看 | 精品国产乱码久久久久久郑州公司 | www,xxx69 japan| 亚洲一区二区麻豆 | 成人一区二区电影 | 婷婷午夜激情 | 国产精品主播 | 日本少妇videos高潮 | 蜜桃传媒一区二区亚洲av | 免费看黄色三级三级 | av直接看 | 亚洲日本一区二区三区 | 中文字幕免费高清在线观看 | 中文字幕av无码一区二区三区 | 欧美aa| 国产乱码精品一区二区三区亚洲人 | 欧美成人吸奶水做爰 | 国产极品视频 | 九九热免费在线视频 | 久久2018| 91亚洲视频在线 | 色先锋影院 | xxxx黄色| 久久久天堂国产精品女人 | 在线观看中文字幕一区二区 | 日韩成人午夜影院 | 亚洲av无码成人精品区 | 免费成人美女女 | 91超碰免费在线 | 国产成a人亚洲精v品在线观看 | 日韩精品成人一区二区在线 | 天天操狠狠操夜夜操 | 奇米影视色 | 精品一区在线观看视频 | 91久久视频 | 国产成人片 | 毛片一二三区 | 中文字幕乱码在线 | 亚洲永久免费 | 天天射,天天干 | 日韩欧美自拍偷拍 | 国产精品美乳在线观看 | 制服丝袜在线一区 | 成人看片网 | 国产精品69久久久 | 精品资源成人 | 九九九国产 | 欧美中文在线观看 | 国产一级理论片 | 男生女生操操操 | 成人av亚洲 | 午夜福利一区二区三区 | 日韩在线视频播放 | 国产精品一区二区久久久 | 欧美精品在线观看一区二区 | 窝窝视频在线 | 蜜桃成熟时李丽珍在线观看 | 中日韩午夜理伦电影免费 | 国产精品日日夜夜 | 草逼视频网站 | 五号特工组之偷天换月 | 亚洲乱论 | 日韩伦理一区 | 免费一级片网址 | 青青国产在线观看 | 青春草国产视频 | 69久久久久 | 高清成人免费视频 | 欧美日韩看片 | 色男人的天堂 | 久久福利网 | 黄网在线免费观看 | 伊伊成人网 | 久久综合久| 冲田杏梨 在线 | 日韩精品字幕 | 日本成人免费网站 | 国产熟女一区二区 |