數(shù)據(jù)遷移怎么做?
隨著企業(yè)數(shù)字化的深入,系統(tǒng)上云或者國(guó)產(chǎn)化改造的需求也是越來(lái)越多,數(shù)據(jù)遷移作為其中的重點(diǎn)中的重點(diǎn),絕對(duì)是不可繞開的一個(gè)關(guān)鍵環(huán)節(jié)??赡苡腥藭?huì)覺得數(shù)據(jù)遷移不是很簡(jiǎn)單嗎,用binlog把數(shù)據(jù)同步到新庫(kù)不就完了嗎?這就把問題想簡(jiǎn)單了,事實(shí)上數(shù)據(jù)遷移架構(gòu)可能會(huì)非常復(fù)雜,而且每個(gè)企業(yè)可能都面臨著不同的現(xiàn)狀與歷史情況。比如不是所有的系統(tǒng)數(shù)據(jù)庫(kù)都是Mysql,像金融等大型企業(yè)的系統(tǒng)早期大量使用了Oracle或其它的一些商業(yè)數(shù)據(jù)庫(kù),甚至在某些限制的情況下DBA團(tuán)隊(duì)都不提供7*24小時(shí)的主備同步的功能。這時(shí)你的架構(gòu)應(yīng)該怎么設(shè)計(jì)?

一般來(lái)說系統(tǒng)按服務(wù)對(duì)象可以分為ToC、ToB、ToG,對(duì)于后兩類系統(tǒng)或者規(guī)模較小的ToC類系統(tǒng),通??梢杂型C(jī)發(fā)布窗口,有停機(jī)窗口的系統(tǒng)數(shù)據(jù)遷移比無(wú)停機(jī)窗口7*24小時(shí)提供在線服務(wù)的系統(tǒng)相對(duì)來(lái)說會(huì)簡(jiǎn)單不少
對(duì)于小型系統(tǒng)來(lái)說,系統(tǒng)的割接可能比較簡(jiǎn)單,通常會(huì)在新系統(tǒng)中驗(yàn)證通過后觀察一段時(shí)間,確認(rèn)不存在回切風(fēng)險(xiǎn)后逐步下線舊系統(tǒng)即可。而對(duì)于大型系統(tǒng)來(lái)說,系統(tǒng)割接的時(shí)間可能持續(xù)幾個(gè)月甚至數(shù)年的時(shí)間,就像在飛行的飛機(jī)上換發(fā)動(dòng)機(jī)一樣。對(duì)于高并發(fā)系統(tǒng),數(shù)據(jù)的遷移除了數(shù)據(jù)庫(kù)的遷移外還需要考慮緩存的數(shù)據(jù)遷移或預(yù)熱以防止新系統(tǒng)在切入流量后發(fā)生緩存擊穿而雪崩。下面是一些常用的策略和對(duì)限制性條件下的思考:
最簡(jiǎn)單的數(shù)據(jù)遷移策略
先來(lái)看一下最簡(jiǎn)單的數(shù)據(jù)遷移策略:即可停機(jī)的一次性遷移。也就是說在停機(jī)發(fā)布窗口內(nèi),完成數(shù)據(jù)遷移并完成新環(huán)境的功能驗(yàn)證測(cè)試,等恢復(fù)后用戶訪問到的系統(tǒng)已經(jīng)更新為新系統(tǒng)。這種方式的優(yōu)點(diǎn)是方案簡(jiǎn)單,缺點(diǎn)是當(dāng)正常提供服務(wù)時(shí)間發(fā)現(xiàn)新環(huán)境存在重大問題時(shí),由于新環(huán)境的數(shù)據(jù)庫(kù)通常已經(jīng)寫入了新數(shù)據(jù),已經(jīng)沒辦法切回到舊環(huán)境的舊系統(tǒng),所以這種策略適用于小規(guī)模系統(tǒng)。
具體的做法是在停機(jī)維護(hù)開始后先在舊數(shù)據(jù)庫(kù)中執(zhí)行mysqldump,再在新數(shù)據(jù)庫(kù)中導(dǎo)入dump文件,這種方式甚至都不要求新舊環(huán)境之間的網(wǎng)絡(luò)互通。在dump文件導(dǎo)入成功后,先進(jìn)行數(shù)據(jù)驗(yàn)證,通過后數(shù)據(jù)遷移工作即基本完成。再對(duì)新環(huán)境的應(yīng)用程序進(jìn)行功能驗(yàn)證測(cè)試,通過后切換流量入口讓新環(huán)境接替舊環(huán)境對(duì)外提供服務(wù)。見下圖:

可回切的遷移策略
再來(lái)看一下稍微復(fù)雜一點(diǎn)的數(shù)據(jù)遷移策略:可回切的遷移策略。為了降低遷移的風(fēng)險(xiǎn),企業(yè)通常會(huì)考慮在遷移完成并開始對(duì)外提供服務(wù)出現(xiàn)問題時(shí)進(jìn)行回切。為了滿足回切的需求,我們通常會(huì)讓新舊兩套數(shù)據(jù)庫(kù)之間進(jìn)行數(shù)據(jù)同步,新環(huán)境數(shù)據(jù)庫(kù)為主庫(kù),舊環(huán)境數(shù)據(jù)庫(kù)為從庫(kù),在回切時(shí)進(jìn)行手工的主從倒換。這種方式也要求新舊環(huán)境間的網(wǎng)絡(luò)是互通的。

如上圖,剛開始,舊環(huán)境數(shù)據(jù)庫(kù)作為主庫(kù),新環(huán)境數(shù)據(jù)庫(kù)作為從庫(kù)。為了進(jìn)一步減少數(shù)據(jù)遷移的時(shí)間,可先把新環(huán)境的應(yīng)用程序部署等各類工作提前做好,先不切入流量入口即可。

如上圖,在停機(jī)發(fā)布窗口到來(lái)時(shí),先停止舊環(huán)境流量,確認(rèn)主從數(shù)據(jù)庫(kù)數(shù)據(jù)同步完成后,手工執(zhí)行主從倒換將舊環(huán)境數(shù)據(jù)庫(kù)轉(zhuǎn)換為從庫(kù),新環(huán)境數(shù)據(jù)庫(kù)轉(zhuǎn)換為主庫(kù)。在對(duì)外提供服務(wù)后,由于寫入新數(shù)據(jù)庫(kù)的數(shù)據(jù)也會(huì)同步到舊數(shù)據(jù)庫(kù),只要新舊庫(kù)之間的數(shù)據(jù)一致,舊服務(wù)就具備了回切的條件。
當(dāng)發(fā)現(xiàn)新環(huán)境服務(wù)存在嚴(yán)重問題需要回切時(shí),先停止新環(huán)境流量,確認(rèn)數(shù)據(jù)同步完成后手工執(zhí)行主從倒換并將流量入口切回舊環(huán)境。由于主從間的同步可以在數(shù)據(jù)遷移前就持續(xù)進(jìn)行,真正遷移時(shí)只需要確認(rèn)從庫(kù)的數(shù)據(jù)追上了主庫(kù)的數(shù)據(jù)后進(jìn)行手工主從倒換,所以在這種方式也適用于很短停機(jī)窗口的系統(tǒng)。
雙寫的遷移策略
接下來(lái)我們來(lái)看一下更為復(fù)雜的異構(gòu)數(shù)據(jù)庫(kù)遷移策略:雙寫策略。前面介紹的兩種策略都適用于同構(gòu)數(shù)據(jù)庫(kù)的數(shù)據(jù)遷移,但是對(duì)于異構(gòu)數(shù)據(jù)庫(kù)之間的數(shù)據(jù)遷移,我們應(yīng)該如何設(shè)計(jì)呢?畢竟國(guó)產(chǎn)化改造多數(shù)情況是從一些商業(yè)數(shù)據(jù)庫(kù)往國(guó)產(chǎn)或開源的數(shù)據(jù)庫(kù)上進(jìn)行遷移居多。
有一些商業(yè)的異構(gòu)數(shù)據(jù)遷移工具號(hào)稱可以支持7*24小時(shí)的異構(gòu)數(shù)據(jù)庫(kù)同步,但由于不同商業(yè)數(shù)據(jù)庫(kù)擁有各自豐富的特性,很難覆蓋所有方面。因此,我認(rèn)為可以使用這類商業(yè)工具來(lái)進(jìn)行存量數(shù)據(jù)的輔助遷移和驗(yàn)證,但對(duì)于實(shí)時(shí)產(chǎn)生的增量數(shù)據(jù),主要還是依靠應(yīng)用程序的雙寫機(jī)制來(lái)處理。
關(guān)于雙寫的實(shí)現(xiàn)方法,有多種選擇,每種方法都有其優(yōu)缺點(diǎn)和適用環(huán)境。根據(jù)增量數(shù)據(jù)的來(lái)源不同,主要有增量日志訂閱方案和應(yīng)用層雙寫方案。
增量日志訂閱方案中,最常見的是使用開源工具Canal來(lái)訂閱主庫(kù)的Mysql binlog變化,并消費(fèi)binlog以獲取增量數(shù)據(jù)。這種方式只適用于Mysql作為源數(shù)據(jù)庫(kù)的情況。雖然也有一些方案可以支持Oracle等商業(yè)數(shù)據(jù)庫(kù)的數(shù)據(jù)遷移,例如愚公等工具,但它們需要額外的物化視圖權(quán)限,并且可能對(duì)性能產(chǎn)生影響,實(shí)際應(yīng)用中使用時(shí)會(huì)有一定限制。
應(yīng)用層雙寫方案包括應(yīng)用同步雙寫和異步雙寫兩種方式。應(yīng)用同步雙寫是指應(yīng)用程序同時(shí)連接兩個(gè)數(shù)據(jù)源,在寫入數(shù)據(jù)時(shí)同時(shí)向兩個(gè)數(shù)據(jù)庫(kù)中寫入數(shù)據(jù)。這種方式會(huì)在一定程度上降低應(yīng)用程序的性能,因?yàn)楝F(xiàn)在需要同時(shí)插入兩個(gè)庫(kù),而不僅僅是一個(gè)庫(kù)。此外,該方式還要求應(yīng)用與兩個(gè)數(shù)據(jù)庫(kù)必須在相同機(jī)房或者同一可用區(qū),否則跨網(wǎng)絡(luò)導(dǎo)致的時(shí)間開銷會(huì)大大增加。應(yīng)用異步雙寫方案與同步雙寫的不同之處在于,第二個(gè)庫(kù)的寫入是異步進(jìn)行的。可以通過使用消息隊(duì)列的方式來(lái)實(shí)現(xiàn)這種異步操作。由于采用了異步雙寫,對(duì)應(yīng)用程序的性能影響非常小。

異步雙寫方案的具體實(shí)現(xiàn)如上圖所示。在這種方案中,應(yīng)用在寫入數(shù)據(jù)時(shí)同時(shí)將數(shù)據(jù)寫入消息隊(duì)列。為了確保單個(gè)表的時(shí)序正確性,可以為每個(gè)表配置一個(gè)獨(dú)立的消費(fèi)者來(lái)處理消息隊(duì)列中的數(shù)據(jù)。此外,為了進(jìn)一步保證數(shù)據(jù)的一致性,還需要設(shè)計(jì)一個(gè)基于增量行的檢查程序,該程序依賴于源表中的last_update_time字段,用于確保兩個(gè)數(shù)據(jù)庫(kù)之間的數(shù)據(jù)一致性。
對(duì)于換數(shù)據(jù)庫(kù)與上云同時(shí)存在的需求,其實(shí)應(yīng)該考慮分步去實(shí)施,即先完成一項(xiàng)再完成另一項(xiàng),這樣在上云的過程中可以利用同構(gòu)數(shù)據(jù)庫(kù)的主從同步方案,在換數(shù)據(jù)庫(kù)過程中不需要考慮跨機(jī)房網(wǎng)絡(luò)損耗問題帶來(lái)的各種限制。
迭代的遷移策略
在實(shí)際情況中,數(shù)據(jù)遷移可能需要采取迭代進(jìn)行的策略。例如,在云原生重構(gòu)方案中,企業(yè)可以安排一部分人員對(duì)系統(tǒng)進(jìn)行重構(gòu),同時(shí)讓另一部分人員繼續(xù)在舊系統(tǒng)中進(jìn)行需求的迭代開發(fā)。支持迭代遷移的基礎(chǔ)是前端能夠靈活地支持路由策略,即前端可以同時(shí)將部分服務(wù)路由到新環(huán)境,將其他服務(wù)路由到舊環(huán)境中。前端需要支持路由策略設(shè)計(jì)見下圖:

與異構(gòu)數(shù)據(jù)庫(kù)遷移策略相比,迭代遷移策略需要持續(xù)的周期。這種策略通常伴隨著系統(tǒng)的重構(gòu),并且一般按照模塊進(jìn)行。為了更好地實(shí)施迭代遷移,對(duì)每個(gè)模塊的遷移甚至可以將遷移過程分為兩個(gè)步驟:非實(shí)時(shí)讀業(yè)務(wù)的遷移和實(shí)時(shí)讀寫業(yè)務(wù)的遷移。
緩存的數(shù)據(jù)遷移策略
在進(jìn)行緩存遷移時(shí),一般不會(huì)直接遷移緩存數(shù)據(jù),但需要考慮緩存的預(yù)熱。對(duì)于中小規(guī)模的系統(tǒng),也可以直接丟棄緩存數(shù)據(jù),讓新環(huán)境的系統(tǒng)在運(yùn)行過程中逐漸生成新的緩存。然而,在高并發(fā)環(huán)境下,為了防止新環(huán)境系統(tǒng)在接收流量后發(fā)生緩存擊穿并導(dǎo)致雪崩效應(yīng),我們需要進(jìn)行緩存的預(yù)熱。為了使預(yù)熱的數(shù)據(jù)更符合實(shí)際情況,我們可以將舊環(huán)境中一定比例的寫入緩存操作異步同步給新環(huán)境的緩存服務(wù)器,從而實(shí)現(xiàn)預(yù)熱的效果。由于新緩存的更新是異步的且按比例進(jìn)行,對(duì)系統(tǒng)性能的影響很小。

如上圖,當(dāng)舊環(huán)境的緩存服務(wù)發(fā)生更新時(shí),異步地刷新環(huán)境緩存服務(wù)器的內(nèi)容,這樣新環(huán)境緩存服務(wù)器的數(shù)據(jù)就根據(jù)實(shí)際的數(shù)據(jù)分布提前完成了預(yù)熱。















 
 
 












 
 
 
 