大型互聯(lián)網(wǎng)系統(tǒng)數(shù)據(jù)庫(kù)切換方案
前言
互聯(lián)網(wǎng)公司中,有不少大型系統(tǒng),如商城的價(jià)格系統(tǒng),優(yōu)惠券系統(tǒng),等等。這些系統(tǒng)在一年又一年的運(yùn)營(yíng)之后,數(shù)據(jù)存儲(chǔ)量將相當(dāng)龐大,我們最終會(huì)做一些數(shù)據(jù)庫(kù)方面的升級(jí),簡(jiǎn)單粗暴的方法就是切庫(kù),以滿足更多的數(shù)據(jù)庫(kù)存儲(chǔ)空間、更好的數(shù)據(jù)讀取性能。
然而切庫(kù)的操作,對(duì)于系統(tǒng)而言,無(wú)異于換血操作,是一件相當(dāng)危險(xiǎn)的操作,那么如何平穩(wěn),或者說(shuō)損失最小的情況下,將系統(tǒng)的數(shù)據(jù)庫(kù)進(jìn)行切換呢?這就是本文要分享的內(nèi)容了。
需求
很多情況下,我們可以通過(guò)對(duì)系統(tǒng)進(jìn)行優(yōu)化就能滿足系統(tǒng)的性能要求的情況下,我們是不會(huì)選擇切庫(kù)這個(gè)方案的。筆者經(jīng)歷的切庫(kù)情況,有以下兩種:
數(shù)據(jù)庫(kù)中間件
- 原先的數(shù)據(jù)庫(kù)使用的是通過(guò)Docker安裝的MySQL,切換為公司內(nèi)部的數(shù)據(jù)庫(kù)中間件(也稱分布式數(shù)據(jù)庫(kù),類(lèi)似阿里云的RDS),項(xiàng)目中的代碼程序不用做過(guò)多的分庫(kù)分表改造,由數(shù)據(jù)庫(kù)中間件幫我們做了這個(gè)事情,我們的數(shù)據(jù)存儲(chǔ)很自然地變?yōu)?strong>多分片存儲(chǔ)了;
- 原先的數(shù)據(jù)庫(kù)為公司內(nèi)部的數(shù)據(jù)庫(kù)中間件,由于分片過(guò)少,需要擴(kuò)容分片。而數(shù)據(jù)庫(kù)中間件不能很好地擴(kuò)縮容分片,進(jìn)行少分片數(shù)據(jù)庫(kù)中間件切多分片數(shù)據(jù)庫(kù)中間件切換;
方案
有了以上的共識(shí),最后還是選擇切庫(kù)方案的話,通常我們會(huì)選擇在夜深人靜時(shí)分,即系統(tǒng)訪問(wèn)量最少的情況下,像電商一般是半夜3點(diǎn)半左右,進(jìn)行切庫(kù)操作,避免切庫(kù)過(guò)程造成過(guò)多的臟數(shù)據(jù)。
當(dāng)然,我們的系統(tǒng),需要提前開(kāi)發(fā)好切庫(kù)相關(guān)的代碼,如新庫(kù)SQL適配、切庫(kù)過(guò)程的開(kāi)關(guān)引入,等等。
至于具體的將數(shù)據(jù)庫(kù)從A切換到B的步驟,有以下幾點(diǎn):
切庫(kù)流程
1.將A庫(kù)中的數(shù)據(jù),全量同步到B庫(kù)中,同時(shí)保持增量同步。
這樣我們?nèi)绻麑?shù)據(jù)庫(kù)連接從A改為B時(shí),讀取的數(shù)據(jù),是一樣的,當(dāng)然期間的數(shù)據(jù)庫(kù)同步延遲是不可避免的。而數(shù)據(jù)的同步,可以使用阿里巴巴開(kāi)源的中間件canal。
2.將A庫(kù)進(jìn)行停寫(xiě)。
一旦A庫(kù)進(jìn)行停寫(xiě)了,那么B庫(kù)在很短的時(shí)間延遲之后,將獲得同A一樣的全量數(shù)據(jù)了,然后我們就可以把數(shù)據(jù)庫(kù)同步斷開(kāi)。
3.將系統(tǒng)的數(shù)據(jù)庫(kù)鏈接切換到B庫(kù)。
我們的系統(tǒng)需要事先鏈接兩套數(shù)據(jù)庫(kù),通過(guò)開(kāi)關(guān)控制數(shù)據(jù)庫(kù)鏈接,如此我們就可以通過(guò)極短的時(shí)間內(nèi),將系統(tǒng)的數(shù)據(jù)庫(kù)鏈接進(jìn)行切換。