简介:对于数据存储系统来说,保障数据不丢不错是底线,也是数据存储系统最难的局部。据统计,失落数据中心 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%。要达到该目标,除了技术上一直优化外,还须要在责任心和治理上下苦功夫,要始终保持对数据的敬畏之心。
原文链接
本文为阿里云原创内容,未经容许不得转载。