数据存储的高可靠性是指在系统面对异常情况时,数据不丢失且服务不中断。异常情况有很多种,包括磁盘失效、服务器崩溃、网络故障及人为事故等,根据Facebook的报告,在一个拥有3000台服务器的生产集群中,一天最多会有110台服务器崩溃。若数据存储的可靠性没得到保证,会造成严重的后果,例如,2017年亚马逊的S3存储系统发生了持续5小时的故障,影响数十万个网站的正常访问,造成约1.5亿美元的损失。
实现高可靠性的基本方式是提供数据冗余,主要包括多副本和纠删码两种机制。如图1.4所示,在多副本机制中,每份数据被重复存储在多个不同位置,因此当某个位置的数据由于某种异常事件无法被访问时,其余位置的数据仍然能够提供服务;而在纠删码机制中,系统将多份数据通过某种编码方式计算出若干份校验块,并将这些数据与相关校验块存储在不同位置;当无法访问某份数据时,其内容可通过校验块和其余数据重新计算获得。相比于多副本机制,纠删码机制具有更低的存储空间开销,但计算和恢复开销更高。对于一个成熟的存储系统,在每个层级都具有相应的可靠性保障:在存储设备层,利用LDPC(Low-Density Parity-Check Code,低密度奇偶校验码)等纠错机制检测数据是否出现错误并尝试修复数据;在服务器层,基于RAID机制的磁盘阵列机制可以容忍某个存储设备的失效;在集群层,通过分布式多副本机制或分布式纠删码处理服务器的异常事件。此外,数据还有可能被周期性地备份和归档。
图1.4 多副本与纠删码
尽管上述机制从理论上能保证数据存储的可靠性,但存储软件是由程序员通过代码编写而成的,若代码中存在漏洞,仍然会造成数据内容发生错误。例如存储软件并发访问处理不当会导致数据内容混乱。因此,为了获得高可靠性,存储软件还需要进行大量的正确性测试,甚至采用一些形式化的手段。亚马逊构建新一代对象云存储系统时,运用了轻量级的形式化方法去验证存储软件在接口语义、数据一致性、并发访问正确性等多个方面是否符合预期 [5] 。