小紅書MySQL數(shù)據(jù)一致性校驗能力探索與實踐

01 背景
1.1 什么是數(shù)據(jù)一致性校驗
在數(shù)據(jù)遷移、數(shù)據(jù)同步以及多數(shù)據(jù)中心部署等場景中,數(shù)據(jù)的一致性要求極為嚴格。然而冗長的同步計算鏈路產(chǎn)生的誤寫或丟失、主從復制延遲產(chǎn)生的臟讀,業(yè)務雙寫、人為誤操作產(chǎn)生的臟數(shù)據(jù)等眾多因素,都可能導致數(shù)據(jù)不一致。
通過建設數(shù)據(jù)一致性校驗能力,能夠及時、準確的發(fā)現(xiàn)并解決數(shù)據(jù)不一致問題,有效降低對業(yè)務的影響。
1.2 數(shù)據(jù)一致性校驗應具備的能力
在小紅書內(nèi)部,數(shù)據(jù)傳輸服務每天服務著眾多的業(yè)務,保障著眾多的數(shù)據(jù)同步任務,在數(shù)據(jù)同步過程中,源端和目標端的數(shù)據(jù)一致性需要嚴格保證,否則將會產(chǎn)生業(yè)務損傷。同時,在面對不同的業(yè)務場景下,數(shù)據(jù)一致性校驗工具能夠進行無損且快速的數(shù)據(jù)校驗。因此,針對數(shù)據(jù)一致性校驗工具我們需要面對以下難點:
- 數(shù)據(jù)量和內(nèi)容不斷地變化:在數(shù)據(jù)校驗過程中,源端和目標端數(shù)據(jù)的總量和內(nèi)容可能都在變化,是一個動態(tài)的過程,數(shù)據(jù)校驗能力需要應對不斷變化的數(shù)據(jù),防止產(chǎn)生誤報;
- 無鎖且不停服的數(shù)據(jù)校驗:數(shù)據(jù)一致性校驗不能影響現(xiàn)有的業(yè)務,需要在業(yè)務不停服的情況下進行,且應該在無鎖狀態(tài)進行,避免影響業(yè)務讀寫操作;
- 對數(shù)據(jù)庫的性能影響要可控:校驗工具一般都會高并發(fā)讀取數(shù)據(jù)庫的數(shù)據(jù),然而,數(shù)據(jù)庫同時承擔著線上的業(yè)務應用。如何有效平衡數(shù)據(jù)校驗速度以及數(shù)據(jù)庫穩(wěn)定性是校驗工具應該解決的重要命題。
- 適配不同數(shù)據(jù)源:由于校驗數(shù)據(jù)源具有多樣性,數(shù)據(jù)校驗需要考慮到不同數(shù)據(jù)源之間的差異,能夠在不同數(shù)據(jù)源之間實現(xiàn)數(shù)據(jù)校驗工作;
- 數(shù)據(jù)分布不均勻:在源端和目標端數(shù)據(jù)分布不均勻的場景下(如源端和目標端分表數(shù)量不一致),數(shù)據(jù)校驗程序能夠?qū)⒃炊藬?shù)據(jù)正確映射到目標端,并進行數(shù)據(jù)校驗工作。
- 快速定位不一致內(nèi)容:數(shù)據(jù)校驗的目的是為了驗證數(shù)據(jù)一致性,并針對不一致數(shù)據(jù)進行快速補救。所以,能夠定位并提供具體不一致的內(nèi)容也是數(shù)據(jù)校驗工具的重要特質(zhì)。
- 快速訂正數(shù)據(jù)的能力:當數(shù)據(jù)校驗定位到不一致內(nèi)容后,是否能夠提供數(shù)據(jù)訂正腳本幫助用戶快速修復不一致數(shù)據(jù)也是校驗工具必不可少的基礎能力。
02 現(xiàn)狀分析
隨著小紅書公司業(yè)務的不斷發(fā)展,原先的MySQL集群容量已經(jīng)無法滿足業(yè)務的發(fā)展,因此需要對原先的MySQL集群進行擴容等操作,以滿足業(yè)務不斷增長的需求。數(shù)據(jù)遷移一般需要將全部數(shù)據(jù)從源端遷移到目標數(shù)據(jù)源上,遷移通常是一次性的,遷移之后鏈路即停止。常見的場景有:
- 集群擴縮容,當預期流量增長或者資源達到瓶頸,對整個數(shù)據(jù)庫集群分片擴容,以減輕各個分片的壓力,同理預期流量下降或者資源利用率偏低時,要對集群縮容,避免資源浪費。
- 庫表遷移,由于容量或者業(yè)務邏輯變動,將數(shù)據(jù)庫集群上的部分庫或表遷出,到新的集群中,或者分表規(guī)則變更(分表鍵,分表數(shù),分表規(guī)則變更)都需要將原有數(shù)據(jù)同步一份至新表中。
- 異構數(shù)據(jù)源遷移,比如技術升級或者存儲介質(zhì)變更,需要將歷史數(shù)據(jù)同步至新的數(shù)據(jù)源。

在數(shù)據(jù)遷移過程中,我們利用自研的數(shù)據(jù)傳輸服務將數(shù)據(jù)從源集群同步到新集群。然而,網(wǎng)絡抖動、臟寫污染等問題可能導致源端與目標端數(shù)據(jù)出現(xiàn)不一致。然而,現(xiàn)在的一些業(yè)界解決方案可能無法滿足現(xiàn)在小紅書內(nèi)部的復雜業(yè)務場景,我們需要一款適配上述各種場景的數(shù)據(jù)一致性校驗工具,來確保在數(shù)據(jù)傳輸過程中的數(shù)據(jù)質(zhì)量,保障數(shù)據(jù)的一致性。因此,我們決定為小紅書打造一套全新的數(shù)據(jù)校驗系統(tǒng),以應對內(nèi)部業(yè)務的多樣化和現(xiàn)有基礎架構的挑戰(zhàn),它融合了業(yè)界成熟的校驗技術。其主要具有以下特性:
- 允許源端和目標端數(shù)據(jù)分布不一致:數(shù)據(jù)一致性校驗工具能夠適應數(shù)據(jù)分布不一致的情況,針對單表、分庫分表等場景都能夠很好的進行校驗工作。
- 自動選擇最佳校驗方式:根據(jù)源端和目標端的表結構以及數(shù)據(jù)分布等信息,數(shù)據(jù)一致性校驗工具會自動選擇最合適的校驗方法,從而快速進行數(shù)據(jù)校驗。
- 適應動態(tài)數(shù)據(jù)變化:數(shù)據(jù)一致性校驗工具支持在數(shù)據(jù)量和內(nèi)容不斷變化的情況下進行校驗。
- 無中斷&無鎖校驗:數(shù)據(jù)一致性校驗工具能在不中斷服務且無需鎖定的狀態(tài)下進行數(shù)據(jù)校驗,確保業(yè)務和同步鏈路的順暢運行。
- 校驗參數(shù)動態(tài)可配置:數(shù)據(jù)一致性校驗工具提供了一系列可配置參數(shù),允許用戶根據(jù)需要動態(tài)調(diào)整校驗速度和批次大小。
- 快速定位不一致內(nèi)容:數(shù)據(jù)一致性校驗工具在發(fā)現(xiàn)數(shù)據(jù)不一致時,能夠快速發(fā)現(xiàn)具體不一致的內(nèi)容。
- 自定義列校驗和規(guī)則轉化:數(shù)據(jù)一致性校驗工具支持自定義列校驗,即使源端和目標端列名不同,也能通過配置列映射實現(xiàn)校驗。同時支持用戶自定義列轉化規(guī)則。
03 數(shù)據(jù)一致性校驗在小紅書內(nèi)部得實現(xiàn)
3.1 校驗類型
按照數(shù)據(jù)校驗的方式,可以劃分為全量數(shù)據(jù)校驗和增量數(shù)據(jù)校驗:
- 全量校驗:這種方法涉及對數(shù)據(jù)庫中所有數(shù)據(jù)的一次性檢查,確保高準確度。然而,它反映的僅是校驗時刻的數(shù)據(jù)狀態(tài)。全量數(shù)據(jù)校驗又被分為同構全量數(shù)據(jù)校驗和異構全量數(shù)據(jù)校驗,通常情況下,全量數(shù)據(jù)校驗建議多次周期性運行,以確保數(shù)據(jù)一致性。
- 增量校驗:此方法基于數(shù)據(jù)變更事件,僅校驗新變更的數(shù)據(jù),減少了校驗量并提高了實時性。但它無法覆蓋歷史數(shù)據(jù)的一致性校驗。
在實際應用中,我們會根據(jù)具體情況靈活結合這兩種校驗方式,以更有效地確保數(shù)據(jù)的準確性和時效性。

在實際實踐中,我們將全量數(shù)據(jù)校驗根據(jù)源端和目標端校驗表結構的差異又細分為同構校驗和異構校驗,它們的主要區(qū)別如下:

在實際進行全量數(shù)據(jù)校驗時,數(shù)據(jù)一致性校驗工具會自動根據(jù)源端和和目標端的數(shù)據(jù)源類型、校驗表的數(shù)據(jù)分布以及數(shù)據(jù)校驗任務配置等多種因素為校驗任務選擇合適的校驗方式,此過程中用戶不感知。
3.2 方案實現(xiàn)
基于實時數(shù)據(jù)流傳輸服務的特點,我們抽象了讀取端(Reader)、寫入端(Writer)和處理端(Processor)組件,實現(xiàn)了業(yè)務邏輯解耦。
- 讀取端(Reader):主要負責從源端獲取數(shù)據(jù),分為Selector和Replicator。Selector主要負責在全量數(shù)據(jù)校驗時對全量數(shù)據(jù)的抽取,而Replicator主要負責在增量數(shù)據(jù)校驗時對Binlog的解析。
- 處理端(Processor):主要負責數(shù)據(jù)的處理、過程和加工。在數(shù)據(jù)校驗時,如果用戶自定義了列映射或者數(shù)據(jù)轉化規(guī)則,此時通過Processror可以對數(shù)據(jù)進行一次二次轉化,然后和目標端數(shù)據(jù)進行對比。
- 寫入端(Writer):主要負責將數(shù)據(jù)寫入下游,主要包括數(shù)據(jù)校驗實時位點更新、校驗摘要更新以及校驗不一致數(shù)據(jù)的持久化等。

3.3 全量數(shù)據(jù)校驗
全量數(shù)據(jù)校驗是指對數(shù)據(jù)庫中的全量數(shù)據(jù)進行一次對比,它是一次性任務。在實際實踐中,全量數(shù)據(jù)校驗一般會被多次運行,從而確保數(shù)據(jù)的完整性和準確性。全量數(shù)據(jù)校驗需要在數(shù)據(jù)傳輸服務全量同步任務運行完成后,且增量同步任務追平延遲后開啟,否則會因為數(shù)據(jù)同步延遲導致大量數(shù)據(jù)不一致誤判。

全量數(shù)據(jù)校驗分為同構校驗和異構校驗,兩者均采用分塊抽樣校驗法。數(shù)據(jù)一致性校驗工具在執(zhí)行全量校驗時,會分批次從源端和目標端提取數(shù)據(jù)塊,然后對比這些數(shù)據(jù)塊以驗證一致性。分塊策略允許用戶配置數(shù)據(jù)塊的大小,每次從數(shù)據(jù)庫中提取固定數(shù)量的數(shù)據(jù)進行校驗。一旦完成一個數(shù)據(jù)塊的校驗,程序就會繼續(xù)下一個數(shù)據(jù)塊。當提取的數(shù)據(jù)量小于設定的數(shù)據(jù)塊大小時,校驗結束。若在某個數(shù)據(jù)塊中發(fā)現(xiàn)不一致,將進行復檢,僅當多次校驗均不一致時,才會記錄為數(shù)據(jù)不一致。采用分塊校驗的原因包括:
- 提高校驗效率:避免一次性處理大量數(shù)據(jù),減少對比時間,加快整體校驗速度。
- 減少業(yè)務影響:分塊校驗減輕了對業(yè)務數(shù)據(jù)庫的讀取壓力,避免對業(yè)務操作造成顯著影響。
同構全量數(shù)據(jù)校驗通過校驗和(checksum)實現(xiàn),因為上下游數(shù)據(jù)分布是均勻的,我們可以通過主鍵對數(shù)據(jù)進行分塊的checksum校驗。在此過程中,待校驗表的數(shù)據(jù)被劃分為多個固定大小的校驗塊(chunk)。在特定時刻,源端和目標端的對應數(shù)據(jù)塊將進行整體Hash校驗和(如CRC32),以判斷數(shù)據(jù)是否一致,同構校驗過程中,校驗塊的大小可以動態(tài)調(diào)整,設置過大可能會增大數(shù)據(jù)庫壓力,同時可能會因為區(qū)間過大導致區(qū)間數(shù)據(jù)不一致概率大;設置過小,可能會降低校驗速度。在實際應用中,業(yè)務可以根據(jù)上下游數(shù)據(jù)庫的指標以及數(shù)據(jù)變化情況進行動態(tài)調(diào)整數(shù)據(jù)塊的大小。

當校驗過程中,發(fā)現(xiàn)某個 chunk 的上下游的 checksum 不一致,通過二分法將原來的 chunk 劃分成大小接近的兩個子 chunk,對子 chunk 進行 checksum 對比,進一步縮小不一致行的可能范圍。通過 checksum 對比不斷的縮小不一致行的可能范圍,可以減少需要進行逐行對比的數(shù)據(jù)行,加快對比速度,減少內(nèi)存損耗,并且由于每次計算 checksum 都相當于遍歷一次二分后的子 chunk,理論上不考慮多次額外消耗,二分檢驗的開銷相當于只對原 chunk 多做兩次 checksum,當chunk大小變成1時,即可找到對應的不一致記錄。但是,在一個校驗塊內(nèi),如果我們發(fā)現(xiàn)源端的數(shù)據(jù)比目標端數(shù)據(jù)要少,我們會通過逐行對比的方式去尋找出不一致的數(shù)據(jù)。
異構全量數(shù)據(jù)校驗采用逐行對比的方法。在執(zhí)行校驗時,系統(tǒng)會分批次從源端提取數(shù)據(jù),并通過一系列預設規(guī)則進行處理,以便與目標端的數(shù)據(jù)進行比較。一旦發(fā)現(xiàn)數(shù)據(jù)不一致,系統(tǒng)將自動進行復檢,且復檢的間隔時間會逐漸延長,呈指數(shù)級增長。這種機制旨在減少對系統(tǒng)的不必要負擔,同時確保數(shù)據(jù)的準確性。

3.4 增量數(shù)據(jù)校驗
增量數(shù)據(jù)校驗專注于驗證數(shù)據(jù)遷移、同步或更新過程中新增或修改的數(shù)據(jù),確保數(shù)據(jù)的完整性和準確性,對保持數(shù)據(jù)一致性和可靠性至關重要。數(shù)據(jù)一致性校驗工具的增量校驗功能實時監(jiān)控源端數(shù)據(jù)變更,并與目標端數(shù)據(jù)進行比對。它與全量數(shù)據(jù)校驗獨立運行,用戶可按需選擇是否啟用增量校驗。

增量校驗以源端數(shù)據(jù)庫為基準,利用其binlog來驅(qū)動校驗過程。通過主鍵或唯一鍵,系統(tǒng)會檢索目標數(shù)據(jù)庫中相應的行數(shù)據(jù),進行一致性對比。考慮到數(shù)據(jù)同步或校驗任務可能存在延遲以及數(shù)據(jù)頻繁變更等問題,實際的源端與目標端數(shù)據(jù)庫數(shù)據(jù)可能比已消費的binlog位點更新。為應對這種情況,我們設計了延遲點查以及復查機制來對兩邊數(shù)據(jù)庫的當前數(shù)據(jù)執(zhí)行一致性比對,確保數(shù)據(jù)的準確性。
04 總結與展望
4.1 階段性總結
小紅書MySQL數(shù)據(jù)一致性校驗工具自上線以來,已經(jīng)在數(shù)據(jù)庫遷移、單元化等重要場景得到了很好的應用,為小紅書內(nèi)部業(yè)務提供了數(shù)據(jù)一致性保障。
4.2 展望
后續(xù)關于數(shù)據(jù)一致性校驗將在以下方面繼續(xù)深入建設。
- 增強產(chǎn)品成熟度:持續(xù)深化現(xiàn)有功能,簡化操作流程,提升用戶體驗。后續(xù)會豐富數(shù)據(jù)源,支持更多的端到端異構數(shù)據(jù)校驗。
- 擴展產(chǎn)品應用范圍:進一步擴展至數(shù)據(jù)入湖入倉、數(shù)據(jù)變更訂閱、緩存更新等場景,以全面提升數(shù)據(jù)傳輸?shù)姆召|(zhì)量,同時支持用戶定制業(yè)務邏輯,支持對賬等復雜場景。
- 提升數(shù)據(jù)修復效率:完善數(shù)據(jù)修復功能,減少手動操作,降低成本,提供一鍵生成修復SQL能力,快速進行回歸驗證。
- 完善數(shù)據(jù)質(zhì)量大盤:提供歸因分析能力,對產(chǎn)生的不一致數(shù)據(jù)進行原因推測,建立質(zhì)量大盤。
05作者簡介
初原(張勇)
小紅書關系型數(shù)據(jù)庫部研發(fā)工程師,數(shù)據(jù)庫中間件小組成員,畢業(yè)于西北工業(yè)大學,現(xiàn)主要負責小紅書數(shù)據(jù)傳輸服務的日常維護與迭代。
元甲(鄭云龍)
小紅書關系型數(shù)據(jù)庫部研發(fā)工程師,數(shù)據(jù)庫中間件小組成員,畢業(yè)于浙江大學,曾就職于美團基礎架構中間件中心,目前是小紅書數(shù)據(jù)傳輸服務負責人。
克邪(沈力鍇)
小紅書關系型數(shù)據(jù)庫部研發(fā)工程師,數(shù)據(jù)庫中間件小組負責人,畢業(yè)于中國科學技術大學,現(xiàn)主要負責小紅書數(shù)據(jù)傳輸服務、數(shù)據(jù)庫代理和數(shù)據(jù)庫SDK等數(shù)據(jù)庫中間件產(chǎn)品的整體架構和技術演進。































