1. 程式人生 > 其它 >CPU靜默資料錯誤:儲存系統資料不丟不錯的設計思考

CPU靜默資料錯誤:儲存系統資料不丟不錯的設計思考

簡介:對於資料儲存系統來說,保障資料不丟不錯是底線,也是資料儲存系統最難的部分。據統計,丟失資料中心10天的企業,93%會在1年內破產。那麼如果想要做到資料不丟不錯,我們可以採取怎樣的措施呢?

作者 | 衝禔
來源 | 阿里技術公眾號

一、背景

對於資料儲存系統來說,保障資料不丟不錯是底線,也是資料儲存系統最難的部分。試想,如果您的銀行存款記錄為 1 萬,因為資料儲存系統異常導致該記錄丟失、或者資料錯誤導致位翻轉從 1 萬變為 0,其影響是致命的。根據統計,丟失資料中心10天的企業,93% 會在1年內破產。

業界的 Data integrity 和Data Corruption 術語就是描述此類問題,它們除了闡述資料錯誤外,還描述了在資料儲存、傳輸等過程中存在的問題。為了保證理解一致,先明確資料不丟和資料不錯的定義:

  • 資料不丟,是指相關內容不丟失。例如,100 MB 的檔案其部分、全部丟失;或者,檔案的元資料有部分、全部丟失,典型如檔案建立時間欄位丟失。
  • 資料不錯,是指內容存在,但是發生了錯誤。例如,100MB 的檔案全部都存在,但其部分、全部資料出錯,和原始資料不一樣(例如 1 萬錯誤的儲存為 0);或者,檔案的元資料出現部分或全部出錯。對於儲存系統來說,資料用 0 或 1 表示,因此資料錯誤的表現就是位翻轉,就是資料從 0 變為 1,或者從 1 變為 0。

同時,Data Consistency(資料一致性)也是相關術語,但它具有更嚴格的要求,資料丟失或錯誤會導致資料一致性問題;但是在資料不丟也不錯時,也不一定保證資料一致性,因為在業務邏輯設計中並沒有滿足一致性要求,例如資料庫事務ACID的一致性要求,通常是邏輯上的資料正確性。本文重點討論資料的不丟不錯故障原因,以及資料儲存系統如何防控設計,不對資料庫事務深入討論。

1 常見的磁碟、記憶體、網路資料翻轉(Bit Flip)

對於計算機系統來說,不管是計算還是儲存,不管是電子部件還是機械部件,都是採用 0 和 1 的二進位制系統,都存在資料翻轉的問題,所以資料不錯的關鍵是防護位翻轉。

  • 盤的位翻轉。不管是 HDD 還是 SSD,都包含儲存介質和資料讀取兩部分,位翻轉可能出現在介質層面,也可能出現在資料讀取層面。

    • 為了檢測介質層面的位翻轉,通常會增加額外的空間存放校驗位。例如,HDD 在塊大小512 位元組基礎上擴充套件為520 位元組,增加了8位元組(Data Integrity Field)內容,該內容中用了 2 位元組(Guard) 欄位存放基於該塊 512 位元組內容的 CRC16 值。
    • 為了檢測資料讀取的位翻轉檢測,在外部線纜介面訪問層採用了 CRC 來校驗,同時內部的讀寫部件則採用了 ECC 來檢查。為此,盤的S.M.A.R.T.資訊還提供了 UltraDMA CRC Error Count、Soft ECC Correction、Hardware ECC Recovered 欄位來統計錯誤數。
  • 記憶體位翻轉。記憶體作為電子裝置,容易受到干擾,例如訊號串擾、宇宙射線等,從而出現位翻轉,為此引入了 ECC(Error Correction Code)記憶體。
  • 網路位翻轉。網絡卡作為傳輸裝置,傳輸過程中因為線纜、介面、內部器件等問題,也可能出現位翻轉的情況,所以網路傳輸中,通常會增加校驗位(Checksum)來檢查翻轉。

以上是典型的資料翻轉場景,特別是盤和記憶體通常是在訪問時發現錯誤;而實際上在未發現時資料其實已經出錯,因此業界也叫“靜默資料錯誤(SDE,Silent Data Error)”。

2 隱蔽的 CPU SDE

除了儲存硬體有資料翻轉的資料靜默錯誤外,作為計算核心部件的 CPU 其實也有類似的問題。因為 CPU 內部也有暫存器、快取、傳輸匯流排等電子器件,儘管也加入了檢測機制,但也有出錯的概率。從 CPU 的錯誤分類來看,典型有如下三種:

  • 硬體可檢測錯誤。通過 CPU 內部的硬體設計,在某些情況下可以自動發現錯誤並校正錯誤,此時幾乎對系統沒有影響。
  • 使用者能觀測錯誤。在某些情況下硬體能檢測錯誤但是無法校正,並且這些錯誤要對使用者可見,典型如宕機崩潰。
  • 靜默資料錯誤。此類錯誤既沒有被硬體檢測到,也沒有被通知給作業系統,但是資料就是被 CPU 寫到了記憶體,從而無法知道它是錯誤的。

CPU 的靜默資料錯誤是致命的,因為對程式的體驗就是讓 CPU 計算返回了結果並進行儲存和處理,但是資料實際已經出錯、業務也不知道,而且沒有任何告警。團隊經過資料校驗功能和 CPU SDE 錯誤檢查工具,發現了幾起 SDE 錯誤,並且業界谷歌和臉書都發表了文章描述該問題,可以說當前的業界難題。

二、CPU SDE故障發現過程

1 發現問題

近期團隊開發的兩個核心模組在某叢集的指定伺服器上都發現校驗資料異常,由於同時在兩個核心模組發現,在排除軟體模組問題後,把根因排查方向轉向硬體。

2 分析定位

通過對記憶體中的已知資料(/dev/shm/data) 讓 CPU 反覆計算校驗 md5,然後和該資料的 正確 md5 值比較,看 CPU 是否計算返回了錯誤資料。

$pwd
/dev/shm

$ cat t.py
import os
import sys
import hashlib

data = open("./data").read()

hl = hashlib.md5()
hl.update(data)
digest = hl.hexdigest()
print "digest is %s" % digest
if digest != "a75bca176bb398909c8a25b9cd4f61ea":
    print "error detected"
    sys.exit(-1)

經過在故障機器上測試,確實發現 CPU 計算 md5 的返回值中,會偶發返回錯誤 md5 值的情況,而且此時作業系統沒有發生任何異常,問題定位是和 CPU 相關。

3 廠家確認

通過和 CPU 廠家溝通,確認該 CPU 的某個 core 發生硬體故障,導致此異常,並討論瞭如下解決方案。

  • 短期解決方案。廠家提供工具線上快速監測類似故障,團隊完成該檢測工具(主要是針對典型的 CPU 指令集)的測試,並在業務上驗證通過後,快速上線。
  • 長期解決方案。廠家提供工具線上監測所有型別的靜默資料錯誤故障,並詳細討論根因和優化措施。

三、儲存系統資料不丟不錯設計思考

1 資料不丟不錯體系思考

為了更好的控制資料儲存系統在資料不丟不錯方面的風險,進行了如上圖所示的多維度思考。

故障模式

從故障來源角度看,故障模式分為硬體錯誤和軟體錯誤。

故障發生時刻

故障發生的時刻,有如下兩種情況:

  • On The Fly。表示資料錯誤發生在讀寫時,例如 CPU 計算、記憶體訪問、網路傳輸、磁碟讀取過程中。
  • Rest。表示資料儲存到介質後,因為部件老化、環境影響、宇宙射線等因素,導致位翻轉。
故障資料型別

從故障資料型別角度看,受影響的資料可能是元資料、也可能是資料;絕大部分系統都包含元資料和資料,包括底層的硬碟都有存放配置的元資料,因此它們都有可能發生錯誤。

故障檢測方法

資料錯誤 100% 會發生,沒有任何僥倖,故障的檢測方法將極為重要,能夠快速檢測到資料錯誤,將能爭取更多的機會修復資料。

為了檢測故障,業界提供瞭如下的典型校驗碼演算法或糾錯碼演算法:

  • XOR 演算法。按照二進位制的異或 (XOR) 計算校驗值,能夠檢測單 Bit 翻轉錯誤。
  • CRC(Cyclic redundancy check)演算法。通常由 n 個數據位,通過數學的多項式計算得到 k 個校驗位,實現錯誤檢測和糾錯。它被廣泛應用於資料的傳輸校驗、以及硬碟的儲存校驗中。
  • LDPC(Low Density Parity Check Code)演算法。它通過校驗矩陣定義的一類線性碼,為使譯碼可行,在碼長較長時需要校驗矩陣滿足“稀疏性”,即校驗矩陣中 1的 、密度比較低,也就是要求校驗矩陣中 1 的個數遠小於 0 的個數,並且碼長越長,密度就要越低。在 SSD 儲存中,LDPC 也被規模應用。

除了上述的基本檢測演算法外,還有和各層業務邏輯相關的檢測演算法,它要按照業務的資料結構和演算法邏輯進行正確性檢測。

故障修復方案

典型的資料錯誤故障修復方案有如下兩類:

  • 資料冗餘修復。例如基於編碼冗餘進行修復,以及副本、糾錯碼的資料修復。
  • 資料備份修復。儲存基於時間點的資料,典型如增量備份、全量備份,當檢測到資料錯誤時,可以基於時間點恢復資料,只是它不是最新資料。

2 硬體資料錯誤和修復典型場景

記憶體資料錯誤
  • 資料錯誤模式。發生單位元錯誤,出現位翻轉。
  • 故障發生時刻。通常是在讀寫記憶體時發生,典型如記憶體讀、寫、拷貝等。
  • 故障資料型別。該錯誤位元影響的相關資料,可能是業務元資料,或者業務資料。
  • 故障檢測方法。採用 ECC記憶體,採用類似漢明碼技術的資料位+校驗位來檢測。
  • 故障修復方案。典型情況下,ECC 能夠自動修復單位元錯誤,應用無感知;也能夠檢測多位元錯誤,但是無法修復,此時作業系統層面會反饋記憶體的 MCE 錯誤。
網絡卡資料錯誤
  • 資料錯誤模式。網絡卡內的部件異常、網口網線鬆動,出現數據錯誤。
  • 故障發生時刻。通過網路傳輸資料時刻,典型如網路收發包。
  • 故障資料型別。該錯誤位元影響的相關資料,可能是業務元資料,或者業務資料。
  • 故障檢測方法。在各層網路協議包中增加校驗,通過校驗來檢測錯誤。
  • 故障修復方案。通常在網路協議中,對於錯誤的網路包採取丟棄、重傳的方式處理。
盤資料錯誤
  • 資料錯誤模式。除了盤介面傳輸採用 CRC 校驗外,盤儲存介質會出現位翻轉的錯誤。
  • 故障發生時刻。儲存在介質上的資料會出現靜默資料錯誤,只是在讀取時才會發現。
  • 故障資料型別。該錯誤位元影響的相關資料,可能是業務元資料,或者業務資料。
  • 故障檢測方法。在介質儲存資料時,例如 512 位元組 Sector 儲存資料時,儲存額外的 CRC 校驗資料和LBA(Logical block addressing)資訊,從而可以檢查資料是否出錯、或者 LBA 是否寫偏(典型發生在 Firmware 錯誤)。通過後臺的資料掃描,發現該錯誤。
  • 故障修復方案。通過業務軟體層做多塊盤間的冗餘,例如儲存資料副本、糾刪碼,從而可以通過正確的冗餘資料來進行修復。
CPU 資料錯誤
  • 資料錯誤模式。難度最大的是 CPU 靜態資料錯誤,例如計算 CRC 返回錯誤值,但作業系統並未上報異常。
  • 故障發生時刻。使用 CPU 進行資料計算時。
  • 故障資料型別。該錯誤位元影響的相關資料,可能是業務元資料,或者業務資料。
  • 故障檢測方法。單機系統內不同 CPU Core 重複處理對比檢測、分散式系統不同機器的 CPU 重複處理對比檢測,做到端到端檢測(End to End Detect,E2E Detect),如下圖所示。
  • 故障修復方案。上層業務要做好原始資料的備份,在檢測到異常後進行恢復,例如機器按照追加寫方式儲存原始資料,在後期計算處理出錯後可以恢復;而且可以設計回收站機制,即使軟體層面刪除了資料,也會保留一定週期,從而在軟體邏輯出 Bug 後也有修復的機會。

3 軟體資料錯誤和修復典型場景

軟體 Bug 導致資料錯誤影響分析

軟體 Bug 影響很嚴重,特別是在分散式系統之上開發軟體,在該業務層如果沒有資料備份,就只有一份資料,一旦出現軟體Bug 刪除資料,將是災難式的影響。業務層軟體通常分為資料和元資料,兩者的受影響程度有差異,通常元資料的資料錯誤影響更大。

軟體 Bug 的資料錯誤檢測

業務軟體的資料基於儲存時間,有如下兩種型別:

  • 增量資料。業務新寫入、更改、刪除的資料,通常由業務軟體的前臺邏輯處理。
  • 存量資料。業務前期儲存的資料,由於業務軟體有資料遷移、空間整理等需要改變資料,設計後臺邏輯來處理。

因此,需要針對性的做錯誤檢測,包含如下的檢測緯度:

  • 增量資料處理檢測。在業務軟體前臺邏輯中儲存資料更新日誌,檢測邏輯通過檢查更新日誌,來校驗前臺邏輯是否存在 Bug。
  • 存量資料處理檢測。在業務軟體後臺邏輯中儲存資料變更日誌,檢測邏輯通過檢查變更日誌,來校驗後臺邏輯是否存在 Bug。
  • 全量資料檢測。針對儲存介質的靜默資料損壞,即使沒有軟體修改資料,也可能發生資料錯誤,所以需要設計全量資料掃描邏輯,主動發現錯誤。

對於資料錯誤檢測設計,需要考慮如下的關鍵點:

  • 錯誤檢測模組要解耦。該模組應該是獨立模組,單獨設計,和前臺、後臺的資料處理邏輯不相關,從而錯誤檢測模組才能準確的檢測出 Bug。
  • 資料處理邏輯記錄日誌的完備性。處理邏輯包括前臺邏輯、後臺邏輯,它們都需要保證 日誌完整(漏記資料變化的記錄),日誌正確(日誌記錄包含校驗,例如 CRC),避免日誌丟失(掉電、異常時,日誌不會丟)。
  • 提高檢測效率。資料錯誤檢測的目的,除了找出 Bug 外,最重要是支撐資料恢復,提升檢測效率可以更好的幫助資料恢復。檢測效率主要度量單位時間內檢測檔案數(元資料檢測)、單位時間內檢測資料量(資料檢測),例如每天檢測多少檔案數、多少檔案量。
  • 元資料檢測優先順序高於資料檢測。基於元資料重要性,檢測時要優先、快速檢查元資料,從而可以更好的控制資料錯誤的影響。
  • 合理利用資料冗餘層的校驗。例如儲存的全量資料檢測,可以充分利用分散式儲存在資料冗餘層(副本、糾刪碼)的後臺掃描(Scrub),當檢測到了某塊盤的資料錯誤、可在此層通過冗餘對比正確性並修復。
軟體 Bug 的資料修復

資料錯誤檢測到軟體 Bug,並且發生了實際的資料錯誤,就必須要進行資料修復,要考慮如下的關鍵點:

  • 資料冗餘預埋。業務軟體設計時,要考慮資料層冗餘,構建在冗餘儲存之上。典型如分散式儲存的多副本、糾刪碼技術,保證資料塊在靜態資料後(特別是儲存介質的硬體、Firmware 資料錯誤),能夠在該層做資料修復。
  • 資料備份。業務軟體儘管構建在資料冗餘層上,但是業務層看到的單個檔案,如果軟體 Bug 誤刪除該檔案仍然會導致資料丟失。所以,業務軟體層要做好資料備份設計,例如 CheckPoint、多版本、快照、備份等。
  • 資料備份保留週期。備份的資料長期保留有成本問題,因此需要合理設定保留週期,保證備份和成本的平衡。
  • 資料備份時間一致性。業務軟體可能在多層都會備份資料,因此各層要提供備份介面能力,由業務層統一設定備份時間。
  • 資料恢復效率。資料恢復工具要能夠儘快恢復資料,比每天恢復檔案數、每天恢復資料量。
  • 錯誤檢測和備份恢復的統一設計。假設“資料備份保留週期”為 Tb,“錯誤檢測時間”為 Td,“資料恢復時間”為 Tr,則需要保證 Tb > Td + Tr。

四、小結

資料不丟不錯需要體系化的設計,要能夠有效的防護硬體資料錯誤、抵禦軟體 Bug,從而要從資料冗餘、備份,錯誤資料檢測,資料恢復等維度全面構建,如下圖所示。

業務作為資料儲存系統,基於上述思路做了如下的工作:

  • 分散式資料冗餘配置。在分散式層配置副本或糾刪碼,從而在某份資料出錯後,可用正確資料校正。
  • 業務層採用追加寫支援多版本,實現資料備份。將備份的歷史資料儲存到回收站中,待需要恢復時使用。
  • 端到端的 CRC 校驗。拉通業務各層,在單機、分散式的計算環節、網路環節、寫入盤環節進行校驗,對於重要元資料要重點校驗。
  • 記錄前臺、後臺的資料更新日誌。業務將各類資料變化的請求資訊,正確記錄到日誌,並將日誌持久化儲存。
  • 增量、存量、全量資料檢測機制。針對增量資料,結合日誌實現典型如 1 天內掃描檢測完成;對於存量資料,結合日誌實現典型如 3 天內掃描檢測完成;對於全量資料,基於引數配置實現典型如 60 天內掃描檢測。
  • 資料恢復機制和組織。業務成立專門的資料恢復團隊,針對每個版本演練資料恢復準確性;並通過批量處理機制,提高恢復效率。

儘管業務做了上述不丟不錯的預防機制,但在 CPU 靜態資料錯誤方面還有很大的提升空間。理論上要做到資料不丟不錯,只能是概率上無限接近於 100%。要達到該目的,除了技術上不斷優化外,還需要在責任心和管理上下苦功夫,要始終保持對資料的敬畏之心。

原文連結
本文為阿里雲原創內容,未經允許不得轉載。