数据迁移,不停机上线的正确姿势
互聯網系統,經常會有數據遷移的需求。系統從機房遷移到云平臺,從一個云平臺遷移到另一個云平臺,系統重構后表結構發生了變化,分庫分表,更換數據庫選型等等,很多場景都需要遷移數據。
在互聯網行業,很多系統的訪問量很高,即便在凌晨兩三點也有一定的訪問量。由于系統數據遷移,導致服務暫停幾分鐘,是很難被業務方接受的!本文我們就來聊一下,在用戶無感知的前提下,如何設計不停機數據遷移方案!
數據遷移過程我們要注意哪些關鍵點呢?第一,保證遷移后數據準確不丟失,即每條記錄準確而且不丟失記錄;第二,不影響用戶體驗(尤其是訪問量高的C端業務需要不停機平滑遷移);第三,保證遷移后的性能和穩定性。
數據遷移方案
掛從庫
在主庫上建一個從庫。從庫數據同步完成后,將從庫升級成主庫(新庫),再將流量切到新庫。
這種方式適合數據結構不變,而且空閑時間段流量很低,允許停機遷移的場景。一般發生在平臺遷移的場景,如從機房遷移到云平臺,從一個云平臺遷移到另一個云平臺。大部分中小型互聯網系統,空閑時段訪問量很低。在空閑時段,幾分鐘的停機時間,對用戶影響很小,業務方是可以接受的。所以我們可以采用停機遷移的方案。步驟如下:
1,新建從庫(新數據庫),數據開始從主庫向從庫同步。
2,數據同步完成后,找一個空閑時間段。為了保證主從數據庫數據一致,需要先停掉服務,然后再把從庫升級為主庫。如果訪問數據庫用的是域名,直接解析域名到新數據庫(從庫升級成的主庫),如果訪問數據庫用的是IP,將IP改成新數據庫IP。
3,最后啟動服務,整個遷移過程完成。
這種遷移方案的優勢是遷移成本低,遷移周期短。缺點是,切換數據庫過程需要停止服務。
雙寫
老庫和新庫同時寫入,然后將老數據批量遷移到新庫,最后流量切換到新庫并關閉老庫讀寫。
這種方式適合數據結構發生變化,不允許停機遷移的場景。一般發生在系統重構時,數據結構會發生變化,如表結構改變或者分庫分表等場景。有些大型互聯網系統,平常并發量很高,即便是空閑時段也有相當的訪問量。幾分鐘的停機時間,對用戶也會有明顯的影響,甚至導致一定的用戶流失,這對業務方來說是無法接受的。所以我們需要考慮一種用戶無感知的不停機遷移方案。
以筆者之前經歷的用戶系統重構為例,聊一下具體方案。當時的場景是這樣的,用戶表記錄數達到3000萬時,系統性能和可維護性變差,于是我們將用戶中心從單體工程中拆分出來并做了重構,重新設計了表結構,而且業務方要求不停機上線!下面是我們當時的方案,步驟如下:
代碼準備。在服務層對用戶表進行增刪改的地方,要同時操作新庫和老庫,需要修改相應的代碼(同時寫新庫和老庫)。準備遷移程序腳本,用于做老數據遷移。準備校驗程序腳本,用于校驗新庫和老庫的數據是否一致。
開啟雙寫,老庫和新庫同時寫入。注意:任何對數據庫的增刪改都要雙寫;對于更新操作,如果新庫沒有相關記錄,需要先從老庫查出記錄,將更新后的記錄寫入新庫;為了保證寫入性能,老庫寫完后,可以采用消息隊列異步寫入新庫。
利用腳本程序,將某一時間戳之前的老數據遷移到新庫。注意:1,時間戳一定要選擇開啟雙寫后的時間點(比如開啟雙寫后10分鐘的時間點),避免部分老數據被漏掉;2,遷移過程遇到記錄沖突直接忽略(因為第2步的更新操作,可能已經把記錄拉到了新庫);3,遷移過程一定要記錄日志,尤其是錯誤日志,如果有雙寫失敗的情況,我們可以通過日志恢復數據,以此來保證新老庫的數據一致。
第3步完成后,我們還需要通過腳本程序檢驗數據,看新庫數據是否準確以及有沒有漏掉的數據
數據校驗沒問題后,開啟雙讀,起初給新庫放少部分流量,新庫和老庫同時讀取。由于延時問題,新庫和老庫可能會有少量數據記錄不一致的情況,所以新庫讀不到時需要再讀一遍老庫。逐步將讀流量切到新庫,相當于灰度上線的過程。遇到問題可以及時把流量切回老庫
讀流量全部切到新庫后,關閉老庫寫入(可以在代碼里加上熱配置開關),只寫新庫
遷移完成,后續可以去掉雙寫雙讀相關無用代碼。
利用數據同步工具
????我們可以看到上面雙寫的方案比較麻煩,很多數據庫寫入的地方都需要修改代碼。有沒有更好的方案呢?
????我們還可以利用Canal,DataBus等工具做數據同步。以阿里開源的Canal為例。
上面是Canal的原理圖,
1,Canal模擬mysql slave的交互協議,把自己偽裝成mysql的從庫
2,向mysql master發送dump協議
3. mysql master收到dump協議,發送binary log給slave(canal)
4. canal解析binary log字節流對象,根據應用場景對binary log字節流做相應的處理
所以上面的用戶系統數據遷移,就不需要開啟雙寫了,服務層也不需要編寫雙寫的代碼,直接用Canal做增量數據同步即可。相應的步驟就變成了:
代碼準備。準備Canal代碼,解析binary log字節流對象,并把解析好的用戶數據寫入新庫。準備遷移程序腳本,用于做老數據遷移。準備校驗程序腳本,用于校驗新庫和老庫的數據是否一致。
運行Canal代碼,開始增量數據(線上產生的新數據)從老庫到新庫的同步。
利用腳本程序,將某一時間戳之前的老數據遷移到新庫。注意:1,時間戳一定要選擇開始運行Canal程序后的時間點(比如運行Canal代碼后10分鐘的時間點),避免部分老數據被漏掉;3,遷移過程一定要記錄日志,尤其是錯誤日志,如果有些記錄寫入失敗,我們可以通過日志恢復數據,以此來保證新老庫的數據一致。
第3步完成后,我們還需要通過腳本程序檢驗數據,看新庫數據是否準確以及有沒有漏掉的數據
數據校驗沒問題后,開啟雙讀,起初給新庫放少部分流量,新庫和老庫同時讀取。由于延時問題,新庫和老庫可能會有少量數據記錄不一致的情況,所以新庫讀不到時需要再讀一遍老庫。逐步將讀流量切到新庫,相當于灰度上線的過程。遇到問題可以及時把流量切回老庫
讀流量全部切到新庫后,將寫入流量切到新庫(可以在代碼里加上熱配置開關。注:由于切換過程Canal程序還在運行,仍然能夠獲取老庫的數據變化并同步到新庫,所以切換過程不會導致部分老庫數據無法同步新庫的情況)
關閉Canal程序
遷移完成。
此外,對于數據結構不改變的不停機數據遷移,也可以利用Canal處理。除了第3步DBA可以直接利用工具做老數據的遷移,其他步驟基本和上面一樣。
希望本文對大家有所幫助。原創不易,如果感覺本文有幫助,有勞轉發或點一下“在看”!讓更多人收獲知識!
作者簡介:曾任職于阿里巴巴,每日優鮮等互聯網公司,任技術總監,15年電商互聯網經歷,擅長高并發場景下系統性能和穩定性解決方案。
IT技術分享社區
個人博客網站:https://programmerblog.xyz
文章推薦程序員效率:畫流程圖常用的工具程序員效率:整理常用的在線筆記軟件遠程辦公:常用的遠程協助軟件,你都知道嗎?51單片機程序下載、ISP及串口基礎知識硬件:斷路器、接觸器、繼電器基礎知識
總結
以上是生活随笔為你收集整理的数据迁移,不停机上线的正确姿势的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jersey创建restful服务及调用
- 下一篇: java numberformat_ja