《解密網易MySQL實例遷移高效完成背后的黑科技》要點:
本文介紹了解密網易MySQL實例遷移高效完成背后的黑科技,希望對您有用。如果有疑問,可以聯系我們。
網易蜂巢團隊:為企業提供專業容器云平臺,深度整合IaaS、PaaS及容器技術,提供彈性計算、DevOps工具鏈、微服務基礎設施等服務,幫助企業解決IT、架構及運維等問題,使企業更聚焦于業務,是新一代的云計算平臺.
我們把數據庫里部分或全部Schema和數據遷移到另一個實例的行為稱為實例遷移,將導出數據的實例稱為源實例,導入數據的實例稱為目標實例.根據遷移數據庫類型的不同,可以分為同種數據庫之間的遷移,如從MySQL遷到MySQL;跨數據庫類型的遷移,如從Oracle遷移到MySQL等.本文將介紹蜂巢RDS實例遷移功能的實現,并探討如何高效完成實例遷移任務.
那么,為什么要進行MySQL實例遷移呢?實例遷移的場景歸納起來主要有以下幾種:
1、從自建實例遷移到RDS:在云服務還未充分推廣時,存在大量的自建數據庫實例,舉網易公司為例,網易博客、網易郵箱等產品數百個MySQL實例直接部署在物理服務器上,隨著業務的擴展,必然要對實例進行擴容、升規格等操作,相比自建實例,RDS實例在故障處理、在線擴容、升級等方面存在天然的優勢,所以,目前絕大部分網易互聯網產品的數據庫均已使用實例遷移功能遷移到RDS上;
2、從其他公有云平臺遷移到RDS:蜂巢RDS推出近一年以來,很多用戶將部署在其他公有云平臺上的MySQL實例遷移到蜂巢RDS上,對實例遷移功能進行統計發現有50%是用于遷移其他公有云的MySQL實例.
在設計實例遷移功能前,我們對業界公有云進行了充分調研,僅有兩家主流公有云平臺提供實例遷移功能,那么為什么僅兩家呢,主要是因為提供在線實例遷移功能需要解決一系列問題,概括起來有以下幾點:
1、如何快速地對源實例進行一致性數據備份?
2、如何處理備份過程中對源實例業務的影響?
3、如何快速地將備份導入到目標實例?
4、如何同步源實例的增量數據到目標實例?
5、如何確保實例遷移高效完成?
下面逐條解析蜂巢RDS是如何解決這些難題的.
我們解決第一個問題的方法是采用多線程邏輯備份的方式來進行源實例一致性數據導出.
MySQL的數據備份工具有很多,邏輯備份工具包括經典的mysqlpump,MySQL 5.7版本新推出的mysqlpump,Percona開源工具mydumper;物理備份主要是Percona的xtrabackup工具.俗話說沒有最好的,只有最合適的,那么在這些備份工具中,哪種工具最適合用于進行實例遷移呢?我們的答案是mydumper.
首先我們排除了xtrabackup,雖然物理備份在性能上有優勢,但其無法在遠程備份源實例,在進行實例遷移時,我們不可能要求用戶賦予操作源實例服務器的權限,尤其在遷移其他公有云平臺的RDS實例時更不現實.此外,物理備份產生的備份數據往往比邏輯備份導出的數據更大,因為xtrabackup直接拷貝物理文件,而邏輯備份是導出SQL語句.下面是我們對幾種備份工具的對比測試結果,可供參考:
排除了物理備份后,還有三個選項:mysqldump、mysqlpump和mydumper.我們最終選擇了mydumper,因為mydumper是多線程的.等等!了解MySQL的同學會質疑,mysqlpump也是多線程的?對,mysqlpump的多線程思想甚至比mydumper更先進,詳見參考文獻1和2.但mysqlpump是表級的并發,且還不成熟,而mydumper是記錄級的并發,針對單個大表的場景,更容易發揮多線程優勢.
也許你會好奇,mydumper是如何實現記錄級的多線程一致性備份的,其備份流程圖如下:
mydumper由主線程和多個工作線程配合完成數據一致性備份,主線程執行FTWRL或Lock Tables tablelist Read阻塞寫操作來建立一致性備份點并記錄當前BinLog和GTID.工作線程在主線程仍持有鎖的情況下將各session的事務級別設置為可重復讀(repeatable-read),并開始進行快照讀,由于此時各表無法進行數據寫入或更新,所以工作線程快照讀的數據就是主線程建立一致性備份點的數據.待所有工作線程均已開始快照讀后,如果不存在MyISAM等非事務性表,主線程即可釋放讀鎖.mydumper原理的詳細分析詳見參考文獻3.
無論是物理備份還是邏輯備份,都會或多或少對數據庫線上業務造成影響.如何處理備份過程中對源實例業務的影響是我們需要解決的第二個問題.蜂巢RDS實例的設計原則是線上業務永遠比遷移任務更重要.由于無法有效了解源實例所在服務器層的監控數據,我們在MySQL數據庫層進行大量的優化來減低影響,包括引入持鎖時間超時機制、基于業務負載智能調整導出并發度和InnoDB Buffer Pool(BP)污染控制等.
如前所述,為了能夠得到一致性的數據,各種備份工具,包括xtrabackup和mydumper,都需要有個短暫給源實例加讀鎖的過程,正常情況下短暫,但也會有例外,如源實例中存在數據量較大的MyISAM表時,持鎖時間會變長.
為了能夠避免持鎖時間過長導致業務的寫操作被阻塞,使用蜂巢RDS進行實例遷移時,用戶可以選擇允許持有讀鎖的最長時間,如下圖所示,如果超過該閾值時間,會無條件解鎖并讓遷移操作失敗,用戶可以選擇在業務低峰期進行重試.
在順利加鎖建立一致性快照并解鎖后,就進入到各種Schema和表數據的導出環節,用戶應根據源實例的線上業務負載和實例的服務器IO能力來合理選擇導出數據的并發線程數,如上圖所示.
業務負載并不總是可以預測的,但業務總是最重要的,那么當短暫的業務高峰上來時,我們希望將服務器有限的IO能力還給業務,而不是用在遷移上.蜂巢RDS提供了負載監控閾值選項,在業務負載超過該閾值時,會暫停遷移操作,直到負載重新低于閾值.如果用戶選擇了多線程導出,則能夠根據業務負載動態調整線程個數,確保在業務優先的前提盡可能快速的完成數據導出操作.下圖為基于業務負載自適應調整導出線程的例子.
在邏輯導出過程中,還會根據用戶提供的遷移賬號權限,選擇性調整InnoDB BP參數來最大限度減小遷移連接的查詢操作對BP熱點數據的污染.盡可能將因遷移而進入BP的數據保留在BP的LRU List冷數據一側,并盡快被替換出BP,詳見參考文獻4.當然設置BP的參數需要賬號有Super權限,對于公有云上的源實例,無法進行該項優化.
使用與mydumper配套的多線程恢復工具myloader來將備份的數據導入到目標RDS實例上,myloader執行流程如下圖所示.由于此時目標實例沒有負載,所以可以盡可能調大導入并發線程數,將目標實例的IO能力吃滿.此外,在數據導入時,我們通過關閉slow log和binary log,將innodb_flush_log_at_trx_commit設置為0來最大限度提高導入性能,在完成數據導入后再將對應的參數調整為原值.這是我們解決第三個問題的方法.
在完成數據導入后,對于全量遷移的場景,遷移就結束了.若選擇增量遷移,還需將數據導出和導入時在源實例上產生的增量數據(Update/Delete)也遷移到目標實例,我們采用MySQL復制的方式來同步這些數據.
由于MySQL 5.5、5.6和5.7版本的復制存在較大差別,我們根據源實例的版本選擇對應的目標實例版本.對于MySQL 5.5及更低版本的源實例,選擇網易開源MySQL版本InnoSQL 5.5.30作為目標RDS實例版本,對于MySQL 5.6和5.7,選擇InnoSQL 5.7.12為目標實例版本.進行上述版本配對的原因在于:
一是希望用戶盡可能采用MySQL最新的穩定版本5.7,因為MySQL 5.7是有史以來最好的版本,帶來了眾多優秀的特性,包括基于GTID的復制、sys表等,同時相比之前的版本解決或優化了大量缺陷或不足.
二是能夠更加方便地配置復制.MySQL 5.7版本提供了基于GTID和基于BinLog兩套復制機制,針對源實例的不同的復制配置,能無縫適配.用戶在遷移源實例時,可選擇遷移實例上全部數據庫,也可選擇僅遷移部分數據庫,MySQL 5.7版本可使用新增的“CHANGE REPLICATION FILTER”語法在線進行過濾復制設置而無需重啟mysqld.由于MySQL 5.5及更低版本無法滿足MySQL 5.7版本與之建立復制所需的實例UUID,所以目標實例使用InnoSQL 5.5.30版本.當然,相比社區版MySQL 5.5.30,InnoSQL 5.5.30實現了在線過濾復制功能.
我們采用并行復制技術來提高增量數據同步的效率,快速縮短主從復制延遲.由于MySQL 5.6版本GTID特性并不完善,在將其遷移到MySQL 5.7版本時,采用基于DATABASE的并行復制方式,避免LOGICAL_CLOCK并行復制時由于GTID EVENT未記錄并行信息導致復制出錯的bug.這樣,第四個問題也得到了解決.
相信大家都認同,實例遷移是個重型操作,誰都不會閑得無事對線上庫來一把實例遷移.既然決定要進行實例遷移,那么就希望能夠一次性完成遷移,避免來回折騰.如何確保高效地遷移就顯得尤為重要,用戶需先進行遷移評估并完成準備工作,蜂巢RDS通過遷移預檢查、提供出錯重試等措施來提高遷移成功率.
用戶首先需在遷移前做好評估工作,包括選擇業務低峰期進行遷移,這樣既最小化對業務的影響同時也能夠提高遷移速度;確認業務連接數據庫的配置能夠進行一次性切換,縮短切換所需時間,同時避免部分業務邏輯連接源庫,另一部分連接目標庫導致數據不一致;其次,根據所遷移的數據量,合理選擇目標實例的存儲空間,避免因為目標實例空間不足導致失敗;最后,還需要創建滿足遷移要求的數據庫賬號.
我們希望在開始遷移前就發現所有可能引起遷移失敗的因素并糾正.遷移預檢查是重要手段,主要包括用戶在源實例創建的遷移MySQL賬號權限檢查、MySQL參數設置檢查.
遷移權限檢查用于確認遷移賬號是否能夠順利完成遷移操作,主要包括對數據庫定義、表定義,視圖、觸發器、存儲過程和函數等Schema的查看權限;對所選中數據庫中表的Lock Table權限,及表中數據Select權限;如果選擇增量遷移,則還需檢查賬號是否具備Replication slave和Replication client權限等.通過查詢源實例的MySQL、information_schema或performance_schema等系統庫來檢查遷移所需權限.MySQL參數檢查主要針對需要做增量數據同步的場景,如果用戶選擇增量遷移,源實例需正確設置server_id和log_bin等參數.如果在預檢查中發現錯誤,會給出明確的提示,引導用戶進行參數調整后再重新進行預檢查.
在遷移過程中,提供了進度顯示功能,如下所示:
遷移的每個階段都會有帶進度條的百分比顯示,并周期性自動刷新.同時還會顯示整體的遷移進度,方便用戶隨時查看.若在數據導出或導入等階段發生錯誤,則會提示錯誤信息,一般出現遷移錯誤的原因主要是由于存在MyISAM表導致持鎖時間超時,根據錯誤信息可以對遷移參數進行針對性修改后進行重試,無需重新開始遷移.
在確認目標實例和源實例間沒有復制延遲后,就可以結束遷移并將業務的IP切換為目標實例IP,當然,在IP切換前,請確認已經在蜂巢RDS實例上創建業務訪問所需的數據庫賬號并賦予合適的權限.
參考文獻:
文章出處:DBApllus社群