數(shù)據(jù)遷移怎么做?
隨著企業(yè)數(shù)字化的深入,系統(tǒng)上云或者國產(chǎn)化改造的需求也是越來越多,數(shù)據(jù)遷移作為其中的重點中的重點,絕對是不可繞開的一個關(guān)鍵環(huán)節(jié)??赡苡腥藭X得數(shù)據(jù)遷移不是很簡單嗎,用binlog把數(shù)據(jù)同步到新庫不就完了嗎?這就把問題想簡單了,事實上數(shù)據(jù)遷移架構(gòu)可能會非常復(fù)雜,而且每個企業(yè)可能都面臨著不同的現(xiàn)狀與歷史情況。比如不是所有的系統(tǒng)數(shù)據(jù)庫都是Mysql,像金融等大型企業(yè)的系統(tǒng)早期大量使用了Oracle或其它的一些商業(yè)數(shù)據(jù)庫,甚至在某些限制的情況下DBA團(tuán)隊都不提供7*24小時的主備同步的功能。這時你的架構(gòu)應(yīng)該怎么設(shè)計?
一般來說系統(tǒng)按服務(wù)對象可以分為ToC、ToB、ToG,對于后兩類系統(tǒng)或者規(guī)模較小的ToC類系統(tǒng),通??梢杂型C發(fā)布窗口,有停機窗口的系統(tǒng)數(shù)據(jù)遷移比無停機窗口7*24小時提供在線服務(wù)的系統(tǒng)相對來說會簡單不少
對于小型系統(tǒng)來說,系統(tǒng)的割接可能比較簡單,通常會在新系統(tǒng)中驗證通過后觀察一段時間,確認(rèn)不存在回切風(fēng)險后逐步下線舊系統(tǒng)即可。而對于大型系統(tǒng)來說,系統(tǒng)割接的時間可能持續(xù)幾個月甚至數(shù)年的時間,就像在飛行的飛機上換發(fā)動機一樣。對于高并發(fā)系統(tǒng),數(shù)據(jù)的遷移除了數(shù)據(jù)庫的遷移外還需要考慮緩存的數(shù)據(jù)遷移或預(yù)熱以防止新系統(tǒng)在切入流量后發(fā)生緩存擊穿而雪崩。下面是一些常用的策略和對限制性條件下的思考:
最簡單的數(shù)據(jù)遷移策略
先來看一下最簡單的數(shù)據(jù)遷移策略:即可停機的一次性遷移。也就是說在停機發(fā)布窗口內(nèi),完成數(shù)據(jù)遷移并完成新環(huán)境的功能驗證測試,等恢復(fù)后用戶訪問到的系統(tǒng)已經(jīng)更新為新系統(tǒng)。這種方式的優(yōu)點是方案簡單,缺點是當(dāng)正常提供服務(wù)時間發(fā)現(xiàn)新環(huán)境存在重大問題時,由于新環(huán)境的數(shù)據(jù)庫通常已經(jīng)寫入了新數(shù)據(jù),已經(jīng)沒辦法切回到舊環(huán)境的舊系統(tǒng),所以這種策略適用于小規(guī)模系統(tǒng)。
具體的做法是在停機維護(hù)開始后先在舊數(shù)據(jù)庫中執(zhí)行mysqldump,再在新數(shù)據(jù)庫中導(dǎo)入dump文件,這種方式甚至都不要求新舊環(huán)境之間的網(wǎng)絡(luò)互通。在dump文件導(dǎo)入成功后,先進(jìn)行數(shù)據(jù)驗證,通過后數(shù)據(jù)遷移工作即基本完成。再對新環(huán)境的應(yīng)用程序進(jìn)行功能驗證測試,通過后切換流量入口讓新環(huán)境接替舊環(huán)境對外提供服務(wù)。見下圖:
可回切的遷移策略
再來看一下稍微復(fù)雜一點的數(shù)據(jù)遷移策略:可回切的遷移策略。為了降低遷移的風(fēng)險,企業(yè)通常會考慮在遷移完成并開始對外提供服務(wù)出現(xiàn)問題時進(jìn)行回切。為了滿足回切的需求,我們通常會讓新舊兩套數(shù)據(jù)庫之間進(jìn)行數(shù)據(jù)同步,新環(huán)境數(shù)據(jù)庫為主庫,舊環(huán)境數(shù)據(jù)庫為從庫,在回切時進(jìn)行手工的主從倒換。這種方式也要求新舊環(huán)境間的網(wǎng)絡(luò)是互通的。
如上圖,剛開始,舊環(huán)境數(shù)據(jù)庫作為主庫,新環(huán)境數(shù)據(jù)庫作為從庫。為了進(jìn)一步減少數(shù)據(jù)遷移的時間,可先把新環(huán)境的應(yīng)用程序部署等各類工作提前做好,先不切入流量入口即可。
如上圖,在停機發(fā)布窗口到來時,先停止舊環(huán)境流量,確認(rèn)主從數(shù)據(jù)庫數(shù)據(jù)同步完成后,手工執(zhí)行主從倒換將舊環(huán)境數(shù)據(jù)庫轉(zhuǎn)換為從庫,新環(huán)境數(shù)據(jù)庫轉(zhuǎn)換為主庫。在對外提供服務(wù)后,由于寫入新數(shù)據(jù)庫的數(shù)據(jù)也會同步到舊數(shù)據(jù)庫,只要新舊庫之間的數(shù)據(jù)一致,舊服務(wù)就具備了回切的條件。
當(dāng)發(fā)現(xiàn)新環(huán)境服務(wù)存在嚴(yán)重問題需要回切時,先停止新環(huán)境流量,確認(rèn)數(shù)據(jù)同步完成后手工執(zhí)行主從倒換并將流量入口切回舊環(huán)境。由于主從間的同步可以在數(shù)據(jù)遷移前就持續(xù)進(jìn)行,真正遷移時只需要確認(rèn)從庫的數(shù)據(jù)追上了主庫的數(shù)據(jù)后進(jìn)行手工主從倒換,所以在這種方式也適用于很短停機窗口的系統(tǒng)。
雙寫的遷移策略
接下來我們來看一下更為復(fù)雜的異構(gòu)數(shù)據(jù)庫遷移策略:雙寫策略。前面介紹的兩種策略都適用于同構(gòu)數(shù)據(jù)庫的數(shù)據(jù)遷移,但是對于異構(gòu)數(shù)據(jù)庫之間的數(shù)據(jù)遷移,我們應(yīng)該如何設(shè)計呢?畢竟國產(chǎn)化改造多數(shù)情況是從一些商業(yè)數(shù)據(jù)庫往國產(chǎn)或開源的數(shù)據(jù)庫上進(jìn)行遷移居多。
有一些商業(yè)的異構(gòu)數(shù)據(jù)遷移工具號稱可以支持7*24小時的異構(gòu)數(shù)據(jù)庫同步,但由于不同商業(yè)數(shù)據(jù)庫擁有各自豐富的特性,很難覆蓋所有方面。因此,我認(rèn)為可以使用這類商業(yè)工具來進(jìn)行存量數(shù)據(jù)的輔助遷移和驗證,但對于實時產(chǎn)生的增量數(shù)據(jù),主要還是依靠應(yīng)用程序的雙寫機制來處理。
關(guān)于雙寫的實現(xiàn)方法,有多種選擇,每種方法都有其優(yōu)缺點和適用環(huán)境。根據(jù)增量數(shù)據(jù)的來源不同,主要有增量日志訂閱方案和應(yīng)用層雙寫方案。
增量日志訂閱方案中,最常見的是使用開源工具Canal來訂閱主庫的Mysql binlog變化,并消費binlog以獲取增量數(shù)據(jù)。這種方式只適用于Mysql作為源數(shù)據(jù)庫的情況。雖然也有一些方案可以支持Oracle等商業(yè)數(shù)據(jù)庫的數(shù)據(jù)遷移,例如愚公等工具,但它們需要額外的物化視圖權(quán)限,并且可能對性能產(chǎn)生影響,實際應(yīng)用中使用時會有一定限制。
應(yīng)用層雙寫方案包括應(yīng)用同步雙寫和異步雙寫兩種方式。應(yīng)用同步雙寫是指應(yīng)用程序同時連接兩個數(shù)據(jù)源,在寫入數(shù)據(jù)時同時向兩個數(shù)據(jù)庫中寫入數(shù)據(jù)。這種方式會在一定程度上降低應(yīng)用程序的性能,因為現(xiàn)在需要同時插入兩個庫,而不僅僅是一個庫。此外,該方式還要求應(yīng)用與兩個數(shù)據(jù)庫必須在相同機房或者同一可用區(qū),否則跨網(wǎng)絡(luò)導(dǎo)致的時間開銷會大大增加。應(yīng)用異步雙寫方案與同步雙寫的不同之處在于,第二個庫的寫入是異步進(jìn)行的??梢酝ㄟ^使用消息隊列的方式來實現(xiàn)這種異步操作。由于采用了異步雙寫,對應(yīng)用程序的性能影響非常小。
異步雙寫方案的具體實現(xiàn)如上圖所示。在這種方案中,應(yīng)用在寫入數(shù)據(jù)時同時將數(shù)據(jù)寫入消息隊列。為了確保單個表的時序正確性,可以為每個表配置一個獨立的消費者來處理消息隊列中的數(shù)據(jù)。此外,為了進(jìn)一步保證數(shù)據(jù)的一致性,還需要設(shè)計一個基于增量行的檢查程序,該程序依賴于源表中的last_update_time字段,用于確保兩個數(shù)據(jù)庫之間的數(shù)據(jù)一致性。
對于換數(shù)據(jù)庫與上云同時存在的需求,其實應(yīng)該考慮分步去實施,即先完成一項再完成另一項,這樣在上云的過程中可以利用同構(gòu)數(shù)據(jù)庫的主從同步方案,在換數(shù)據(jù)庫過程中不需要考慮跨機房網(wǎng)絡(luò)損耗問題帶來的各種限制。
迭代的遷移策略
在實際情況中,數(shù)據(jù)遷移可能需要采取迭代進(jìn)行的策略。例如,在云原生重構(gòu)方案中,企業(yè)可以安排一部分人員對系統(tǒng)進(jìn)行重構(gòu),同時讓另一部分人員繼續(xù)在舊系統(tǒng)中進(jìn)行需求的迭代開發(fā)。支持迭代遷移的基礎(chǔ)是前端能夠靈活地支持路由策略,即前端可以同時將部分服務(wù)路由到新環(huán)境,將其他服務(wù)路由到舊環(huán)境中。前端需要支持路由策略設(shè)計見下圖:
與異構(gòu)數(shù)據(jù)庫遷移策略相比,迭代遷移策略需要持續(xù)的周期。這種策略通常伴隨著系統(tǒng)的重構(gòu),并且一般按照模塊進(jìn)行。為了更好地實施迭代遷移,對每個模塊的遷移甚至可以將遷移過程分為兩個步驟:非實時讀業(yè)務(wù)的遷移和實時讀寫業(yè)務(wù)的遷移。
緩存的數(shù)據(jù)遷移策略
在進(jìn)行緩存遷移時,一般不會直接遷移緩存數(shù)據(jù),但需要考慮緩存的預(yù)熱。對于中小規(guī)模的系統(tǒng),也可以直接丟棄緩存數(shù)據(jù),讓新環(huán)境的系統(tǒng)在運行過程中逐漸生成新的緩存。然而,在高并發(fā)環(huán)境下,為了防止新環(huán)境系統(tǒng)在接收流量后發(fā)生緩存擊穿并導(dǎo)致雪崩效應(yīng),我們需要進(jìn)行緩存的預(yù)熱。為了使預(yù)熱的數(shù)據(jù)更符合實際情況,我們可以將舊環(huán)境中一定比例的寫入緩存操作異步同步給新環(huán)境的緩存服務(wù)器,從而實現(xiàn)預(yù)熱的效果。由于新緩存的更新是異步的且按比例進(jìn)行,對系統(tǒng)性能的影響很小。
如上圖,當(dāng)舊環(huán)境的緩存服務(wù)發(fā)生更新時,異步地刷新環(huán)境緩存服務(wù)器的內(nèi)容,這樣新環(huán)境緩存服務(wù)器的數(shù)據(jù)就根據(jù)實際的數(shù)據(jù)分布提前完成了預(yù)熱。