大數據“復活”記
800
2025-03-31
一、用戶場景與解決方案
隨著業務的迅速增長,客戶原有的生產集群部署的服務器性能會逐漸無法滿足業務需求,由此客戶可能會采購一批高配置的服務器搭建新集群,希望將生產集群的數據遷移到新集群。
先前客戶通常使用GDS工具等方式,將生產集群數據先導出至中轉服務器,然后從中轉服務器再導入新集群。但這樣周期很長,且需要客戶提前準備大量機器用做GDS中轉服務器。事實上,GaussDB(DWS)從兩年前已研發出了一種新的集群數據遷移利器,可以高效完成該工作,該方案基于Roach物理備份恢復原理。
考慮到OLAP場景下,用戶集群動輒數百個節點,數據量則高達若干PB,集群數據遷移過程往往需要數小時之久。一種應對方案是一次全量遷移加多次增量遷移配合,另一種是全量遷移與斷點續做配合。目前客戶穩妥起見通常選擇固定的變更時間窗,停業務離線遷移結合斷點續做的方式。本文主要就斷點續做展開討論。
二、斷點續做原理解析
本文從宏觀到微觀,抽絲剝繭,帶大家逐層了解斷點續做的原理。
集群數據遷移框架是在SyncDataToStby.py工具中實現的,同時部署在新老集群上,該工具負責在生產集群上拉起GaussRoach.py -t backup備份任務,在新集群上拉起GaussRoach.py -t restore恢復任務。生產集群上由Roach備份生成的*.rch備份壓縮文件,通過scp命令傳輸到新集群上,新集群通過Roach工具解壓這些*.rch備份文件,從而將生產集群的數據文件以物理恢復的方式同步到了新集群。具體框架如下,細節本文不做展開描述。
上圖只是簡化示意,實際上scp動作發生在新老集群間的兩個CN/DN實例之間,而非兩個節點之間。因此,遷移框架支持兩套集群節點數不同,只要兩套集群的總DN個數相同即可(通常稱為異構遷移或異形遷移)。熟悉GaussDB(DWS)的讀者可能已經發現,該框架與GaussDB(DWS)雙集群容災架構完全相同。沒錯,該框架非常強大,對于異構或同構的雙集群跨AZ容災、集群間數據遷移都是通用的,且支持一次全量、多次增量容災或數據同步,支持在線不停業務周期數據同步或容災,支持容災或遷移過程中斷點續做。而集群數據遷移其實是使用了其最簡單的一種場景,相當于離線場景下只做了一次全量數據同步到新集群。
回到正題,如上框架下,如何做到集群遷移的斷點續做呢?
不難觀察到,該框架基于Roach物理備份恢復,生產集群相當于做了一次全量集群物理備份,新集群相當于做了一次全量集群物理恢復。全量備份和全量恢復兩個過程之間基本解耦,通過scp備份文件將兩個過程關聯起來。因此,該框架下的斷點續做實現,最主要的就是分別管理好生產集群的全量備份斷點續做和新集群的全量恢復斷點續做,以及兩個集群間的scp動作中斷場景的續做。上圖中的(1)、(2)、(3)標記指出了這3個過程。下文將基于這3個過程展開說明。
1、全量備份的斷點續做
全量備份調用的是GaussRoach.py備份工具,這個就是大家熟悉的單個集群的備份恢復工具Roach。要控制全量備份的斷點續做,就需要了解Roach工具的架構、內部運轉流程,作為基礎此處會帶大家額外回顧下Roach的知識,已掌握的讀者可以跳過。大家閱讀的時候可以考慮這樣的框架和流程下如何實現斷點續做。
GaussDB(DWS)集群是分布式架構的,其備份工具Roach也基于分布式架構。Roach主要包括兩個組件:調度框架GaussRoach.py和實際執行任務的gs_roach程序。假設集群有3個節點,用戶在節點1調用GaussRoach.py發起備份操作,那么我們就將節點1稱為master節點(主節點),其余節點稱為agent節點。GaussRoach.py通過ssh命令給每個節點都拉起gs_roach進程,后者根據本節點DN個數fork相應數量的gs_roach子進程,每個gs_roach進程負責一個DN的備份任務。備份任務結束后,所有gs_roach和GaussRoach.py進程退出。同一時刻,集群內所有DN相當于都在并行備份數據。
為節省內存開銷,主節點的gs_roach同時兼任Roach master和Roach agent身份。Roach master維護一個狀態機,與其余節點的Roach agent通過TCP長連接進行通信,前者扮演主控角色,給其余節點發送命令,通知它們按狀態機的次序逐個完成各項子任務,并控制其余節點的備份狀態保持同步。目前集群全量備份共有十幾個狀態,各個Roach agent節點需要按Roach master的指令依次完成十幾個子任務。Roach master會等待各個Roach agent都完成該項子任務才會推進到下一個狀態。為了更好地控制分布式交互,各個Roach agent也維護了自己的一個狀態機,其狀態大體與Roach master的狀態一一對應。
有了這些基礎知識后,就不難想到分布式框架下實現全量備份斷點續做的一個思路:用兩個元數據文件resume_backup_master.metadata和resume_backup_agent.metadata,分別記錄Roach master和Roach agent當前已完成到哪個狀態機階段,每完成一個子任務,就刷新一次續做的元數據文件。那么,中間出現故障后,需要拉起續做任務時,就讀取這倆文件獲知上次完成到哪個子任務,本次就從下一個子任務開始接著做。當然,每個節點都有Roach agent,所以resume_backup_agent.metadata也不止一個,每個節點負責維護自己的Roach agent續做元數據。同時,這個文件里面記錄的信息也遠遠不止子任務狀態。
然后進一步來看這十幾個子任務內部如何續做。最主要的子任務包括生成實例數據文件清單、備份行存文件、創建barrier點、備份xlog文件、備份列存文件。創建barrier點大家已經了解,是一個全局事務一致性點,將來集群恢復時就是恢復到這個點。最關鍵的是備份行存、備份列存兩個階段,往往需要若干小時,那么這兩個階段過程中出現故障,下次就得重新做這個子任務,有沒有辦法優化呢,使重做的顆粒度更小?
我們知道,備份過程實質是將各個CN/DN等實例下的數據文件生成*.rch格式的壓縮包,每個壓縮包最大不超過4GB(可配置)。每個4GB的文件通常都能在幾分鐘內完成生成和備份,記錄這些rch文件編號信息,就可以在下次續做時接著上次rch編號繼續備份,從而每個實例續做浪費的時間就控制在幾分鐘內。這個思想簡單,但實現起來卻非常復雜,與當前Roach的核心流程、各種性能優化機制都息息相關,要考慮很多因素。由于Roach支持在線備份,且PG不支持undo,我們在備份文件之前會先生成備份開始時刻的數據文件清單,備份時按當時時刻的文件大小截取拷貝到內存中。而從磁盤讀取文件內容開銷會很大,因此Roach設計了多reader線程機制來加速讀IO性能,小于8MB的文件(可配置)由reader線程負責讀取,較大文件則由主線程exec負責讀取,最后由exec負責內存數據匯總。這個性能優化機制帶來了一個問題,就是rch文件中的備份文件順序和文件清單中文件順序可能出現不連續跳變,下次續做就無法接著上次文件清單進度進行。由此,新增了roach_resume_trans_log日志文件記錄各個實例下的大小文件序號,分兩條線保證續做的正確性。
下圖是Roach備份過程中的生產者-消費者模型示意圖,有助于大家理解這個過程。圖中標記了幾個典型產生斷點的地方。
總結一下,4GB顆粒度的斷點續做,其實就是基于備份前生成的數據文件清單而進行的續做。通過輔助的roach_resume_trans_log日志文件,記下最近一次完成的4GB的rch備份壓縮文件里對應的數據文件編號最大值(包括exec線程和reader線程兩種編號),下次續做時從這里記錄的編號值接著讀取數據文件清單,進行續做。
2、全量恢復的斷點續做
集群全量恢復分為三個階段:停止集群、恢復集群、啟動集群。由于主備DN數據互為副本,備份DN時只備份了主DN數據,恢復集群過程中也只恢復主DN數據。然后在啟動集群階段,一方面會將主DN數據redo到barrier點,另一方面會用主DN數據build到備DN,使得備DN成為主DN數據的副本。這三個階段中,最耗時的就是恢復集群階段,本節主要展開討論這個階段的續做。
集群遷移場景下,為了盡可能縮短遷移時間窗,采用了很多黑科技,其中之一就是主備DN并行恢復。這樣省去了主DN數據build備DN過程,使得恢復和遷移時間縮短一半以上。原理是先將主DN的rch備份壓縮文件拷貝到備DN的關聯路徑下(都在新集群內部拷貝),然后主DN和備DN就可以同時進行解壓恢復rch文件了。最后只需特殊處理一下備DN的postgresql.conf即可。
全量恢復的斷點續做主要包括3個方面:
a) 全量恢復
看了前面的全量備份過程,大家自然聯想到全量恢復是不是也是由狀態機驅動、分為若干子任務。實際的情況是,全量恢復雖然也由狀態機驅動,但狀態個數非常少。這是因為恢復過程本身比較簡單,所有實例、行列存/xlog對于Roach來說都可以一視同仁,因為rch備份文件最初就設計為自解析模式的,Roach解析rch文件就完全可以知道是哪個節點、哪個實例、行列存還是xlog的數據文件,因此主要的恢復過程只需要一個子任務調度就可以了。
全量恢復的斷點續做,就只需處理好上次恢復到哪個rch。一種思路是也用meta元數據記錄上次恢復進度信息,另一種更簡單的思路是:不使用元數據,直接遍歷本地已恢復完的rch文件,即可得知本次需要從哪個rch開始續做恢復。為了在線集群遷移方便擴展,新集群恢復完的rch文件并沒有立即刪除,而是重命名為*.rch.resume_delete后綴,所以斷點續做時只需遍歷找到當前目錄下過濾掉*.rch.tmp、*.rch.resume_delete文件后,編號最小的那個*.rch文件,就是本次續做需要開始的文件。如下圖所示,上次中斷后,本次恢復只需從file_10.rch開始恢復即可。
b) 恢復中斷、恢復比備份快的場景
恢復可能異常中斷,導致Roach進程退出。另外若集群間帶寬為瓶頸,則新集群恢復rch文件的速度大于生成集群scp拷貝rch文件過來的速度,則也會導致Roach提前完成任務而退出。由此,需要保證過段時間新的rch文件被scp過來后,仍然能接著恢復。
為實現該目的,SyncDataToStby.py工具借助了雙集群之間的紐帶文件backuprestoreinfo.csv,該文件記錄了備份和恢復的當前狀態等信息。如果當前備份狀態為未完成,則恢復線程就會不斷檢測是否有新的rch文件傳輸過來,若有則先scp到新集群內的備實例,然后調度gs_roach并行恢復各個實例的新rch文件。直至所有的rch文件都恢復出來。
c) 啟動集群
由于恢復集群前,先停止了集群,所以截止此時集群還處于停止狀態,需要拉起集群。有了上面的backuprestoreinfo.csv和rch續做機制后,啟動集群就變得比較簡單,完全可以復用全量恢復的命令,再拉起一遍恢復續做任務即可。SyncDataToStby.py工具內部會檢查核實是否所有rch都已恢復完畢,是則執行集群啟動動作,否則續做全量恢復。
3、集群間scp中斷后的斷點續做
對于集群遷移來說,備份文件不僅要在本地生成,還需要scp到遠端新集群,這里就得額外考慮一些問題。本地rch文件生成速度往往較快,如果集群間帶寬有限,則rch文件會來不及scp到新集群,積壓在生產集群本地。對于生產集群來說,積壓過多備份文件在本地會導致磁盤空間緊張引發其它問題,因此斷點續做通過流控機制完美解決了積壓問題。對于新集群來說,如果出現斷點續做,那么下次續做時,就得先查看本地rch編號和新集群已經scp過去的rch文件編號。另外,考慮網絡傳輸時如果新集群設備掉電,可能造成新集群rch文件殘缺,因此scp過去時先落盤為*.tmp后綴,fsync成功后,再重命名回*.rch。
4、其它續做考慮
斷點續做還要考慮并行備份恢復。這里講到的并行備份恢復就是又一個黑科技了。最初的遷移框架設計是:全量備份完畢后,新集群開始執行全量恢復,由此生產集群的備份和新集群的恢復是一個串行過程,集群遷移總時間 = 全量備份時間 + 全量恢復時間。為了實現更快、風險更小的遷移目標,我們改造了遷移框架,使得生產集群的備份過程和新集群的恢復過程可以并行起來,生產集群每生成一個rch文件,就scp到新集群,然后新集群就開始恢復。新集群通過backuprestoreinfo.csv文件的信息,結合本地已恢復完成的*.rch.resume_delete文件編號信息,可以持續推進恢復流程直至全部完成。前面章節已有陸續提及,此處不做展開說明。
當然,斷點續做需要考慮的場景遠不止此,比如硬件故障造成的實例主備切換、日志分叉、行存備份階段內核開啟的延遲xlog開關、列存備份階段內核開啟的延遲ddl開關等因素的兼容。這些都做了堅固的適配,以便下次重入時可以正確處理。限于篇幅,本文不做進一步說明。
三、約束與展望
基于Roach的集群遷移框架,是機房搬遷等應用場景的數據遷移利器,可大幅縮短遷移時間窗,兩年來在大型金融機構客戶里面也已多次成功實踐,不斷刷新客戶的預期。該方案包含了很多黑科技,本文也有提及一二,但仍然有很多可以做的更好的地方。本節根據筆者的觀點,給出一些約束與展望,僅供參考。
1、本遷移方案目前主要用于線下離線集群搬遷,在線上場景只要打通兩套集群間互信與沙箱差異,也比較容易適配。在線遷移也是容易擴展的,因為第一版設計就已考慮兼容在線場景,事實上最新版本已差不多打通在線場景。
2、作為離線集群遷移方案,本方案還是要求集群處于啟動且Normal狀態。后續可以簡單做下適配,改造為停集群搬遷,這樣可以簡化主備切換、集群健康監控干擾等大量故障場景的處理。
3、由于是物理搬遷,所以兩套集群要求拓撲同構或異形,即兩套集群的DN總數要相同,否則不好做映射。該約束目前還暫無計劃去除。
4、斷點續做技術在NBU/OBS備份介質上面還沒有打通,剩最后一公里,后續版本已有規劃,屆時NBU/OBS集群備份將會更加健壯。
數據倉庫服務 GaussDB(DWS)
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。