終于有大佬把分庫分表的最佳實踐講清楚了
發(fā)布日期:2022/5/23 12:01:55 瀏覽量:
Part1 什么情況下需要考慮庫表拆分呢?
實際上,是沒有一個非常量化的指標來判定庫表瓶頸的,因為每個系統(tǒng)的業(yè)務(wù)場景,查詢復(fù)雜度都有不同。 但力有窮盡時,我們雖然可以盡量地從加從庫讀寫分離、優(yōu)化 sql、優(yōu)化索引、復(fù)用連接等等方面進行優(yōu)化,但總會有到達極限的時候的時候,量變引發(fā)質(zhì)變。甚至,在真實生產(chǎn)環(huán)境,要更加未雨綢繆,不能等到崩了才去考慮。那么,應(yīng)該怎么去判斷已經(jīng)到了庫表拆分的時機呢:
- 硬件性能瓶頸,如果是讀操作多,其實可以加多個從庫分擔主庫讀壓力;但如果是寫操作多,會因為主庫磁盤 IO 增大,拖慢處理速度;另外,如果單表數(shù)據(jù)量過大,導(dǎo)致索引層級增多,掃描行增多,CPU 效率降低,影響 sql 執(zhí)行效率,拖慢處理速度。而處理速度慢最終會導(dǎo)致連接數(shù)增加直至無連接可用。
- 日常運維投入,就如蘇寧拼購的情況,如果一個月就要搞一次數(shù)據(jù)遷移,這個人力的投入產(chǎn)出比,應(yīng)該是完全不匹配的,那就不如一次性搞定它。
- 業(yè)務(wù)發(fā)展可支持程度、難度和風(fēng)險,當數(shù)據(jù)增長到一定程度,雖然沒有達到極限,還能湊活,但是遇到活動型流量脈沖,無法完全支持業(yè)務(wù)需求;而業(yè)務(wù)需要進行迭代增加模式時,修改數(shù)據(jù)表帶來的風(fēng)險又比較大。就可以考慮重構(gòu)數(shù)據(jù)模型,拆分庫表了。
2.1 業(yè)務(wù)數(shù)據(jù)解耦 - 垂直拆分
把不同的業(yè)務(wù)數(shù)據(jù)拆分到各自的數(shù)據(jù)庫中獨立維護,那么最底層的原因是什么呢?
是微服務(wù)下的上層服務(wù)拆分。為了滿足快速迭代、安全發(fā)布、鏈路降級、主次業(yè)務(wù)解耦等問題,去解決代碼大量沖突、小功能排隊等待大版本發(fā)布等等問題,將業(yè)務(wù)按照一定邏輯進行拆解,形成一個個功能完備,獨立運行的服務(wù),然而,如果數(shù)據(jù)庫層面不配合,就無法解決根本問題。當上層服務(wù)實例拆分后可以被大量橫向擴展,以應(yīng)對高并發(fā)的流量沖擊,會導(dǎo)致底層數(shù)據(jù)庫的承載壓力和連接數(shù)急劇增加。
所以,通過垂直拆分將業(yè)務(wù)數(shù)據(jù)解耦,各管一事,以滿足微服務(wù)的效能最大化。
2.2 解決容量和性能壓力 - 水平拆分
對某一業(yè)務(wù)庫,當數(shù)據(jù)增量達到了庫瓶頸,或者表瓶頸,就要進行庫表的水平拆分了。
我之前遇到的很多情況,總是先分表,解決單表的容量和讀寫性能問題,隨著業(yè)務(wù)發(fā)展,單庫也遇到瓶頸了再考慮分庫。為啥不一步到位?
就像之前在阿里,新應(yīng)用上來搞個百庫百表?一來是因為一些用戶規(guī)模和一些路由規(guī)則的問題;更重要的,不是所有公司其實不是所有的公司都和阿里一樣有錢,有限的資源要用在更重要的生存問題上。如果你作為一個初創(chuàng)公司的架構(gòu),給出了一套可能撐 10 年的存儲方案,感覺會被同事在心里懟,公司能活 3 年么就這么浪費?但肯定沒有人說這話,因為我們還是希望所有公司都能蓬勃發(fā)展,蒸蒸日上的?。
所以,拆分方法就很有講究了,怎么分能讓后續(xù)迭代發(fā)展的代價最小呢?
2.3 分多少合適?
表主要看容量,很多經(jīng)驗表明 上千萬后性能會有顯著下降,因此,我們可以把表容量定在一半多一點,600w。
庫主要看的是連接數(shù),我們以阿里對外售賣的云存儲來大致估計,單庫的連接數(shù)定在 4000 左右。抽象一個實際的評估案例來看:假如目前平臺每天產(chǎn)生 10w 訂單,峰值并發(fā)數(shù) 8000QPS,然后考慮業(yè)務(wù)擴展和增長的速率:
比如,業(yè)務(wù)是和銀行合作擴展業(yè)務(wù),將大小銀行量級平均一下,估計每合作一家可以帶來多大的增長量,這里假設(shè)是 5000 單 / 天 / 家,如果業(yè)務(wù)計劃是每年度合作 10 家,那就是 5w,5 年以后每天的單量,理論上可能會到 25w / 天。加上現(xiàn)有的 10w, 峰值 35w。如果我們計劃系統(tǒng)的容量需要支撐 3 年,或者說,3 年之后的該業(yè)務(wù)擴展會趨于平緩,那么我們可以大致的估計為:
表:(3 年 * 365 天 * 35w=3.8 億 )/600w = 63 約 64 張表 庫:10000 并發(fā) / 4000 = 2.5 , 可按 4 個庫來處理
2.4 怎么分適合
- Hash 取模
- range 劃分
- 分區(qū)鍵的選取
-
- 分區(qū)鍵要足夠的均勻,比如,用戶表用 UID,訂單表可以用 UID,也可以用訂單 ID,商戶表用商戶 ID,問題表用會話 ID 等等,總之,一定可以找到業(yè)務(wù)上的唯一 ID。當然還有一些特殊的分區(qū),比如,日表,月表,則要按時間來分,等等。
- 全局唯一主鍵 ID
-
- 這個其實可以理解為分布式 ID 的生成問題
- 如何實現(xiàn)平滑數(shù)據(jù)遷移?
-
- 好處是簡單,風(fēng)險??;缺點是業(yè)務(wù)有損。那就看這個損能不能接受了
- 事務(wù)問題
-
- 之前由于數(shù)據(jù)都在一個庫中,所以,只要保證一個本地事務(wù)就可以辦到?,F(xiàn)在數(shù)據(jù)被分到了多個庫,那么事務(wù)如何保證,分布式事務(wù)的方式有很多:TCC、本地事務(wù)表 + 事務(wù)消息、最大努力通知,saga 等等。
- 查詢問題
-
- 之前一個庫就能搞定的 join、count 等各種聯(lián)合查詢,將不復(fù)存在,老老實實在接口代碼層面實現(xiàn)吧。
4.1 大眾點評分庫分表的數(shù)據(jù)遷移
- 階段一:數(shù)據(jù)雙寫,以老數(shù)據(jù)為準。通過對賬補平差異
- 階段二:導(dǎo)入歷史數(shù)據(jù),繼續(xù)雙寫,讀切到新數(shù)據(jù)。
- 階段三:停掉雙寫,刪除老數(shù)據(jù)完成遷移
4.2 淘寶萬億級交易訂單的存儲引擎
淘寶超級量級下的交易單是怎么解決存儲性能等問題的:
以上就是本篇文章的索引內(nèi)容,如有遺漏和錯誤,歡迎補充和指正。
作者:jacklin 鏈接:https://juejin.cn/post/7099322743522328583
馬上咨詢: 如果您有業(yè)務(wù)方面的問題或者需求,歡迎您咨詢!我們帶來的不僅僅是技術(shù),還有行業(yè)經(jīng)驗積累。
QQ: 39764417/308460098 Phone: 13 9800 1 9844 / 135 6887 9550 聯(lián)系人:石先生/雷先生