数据和计算系统如何容错?

容错是大规模数据系统和计算系统的必备功能,不能容错的分布式系统基本没有可用性。大家可能觉得高质量的系统错误率没有那么高,实质上系统的故障率总是随着系统规模和复杂程度增加。笔者读书的时候曾经听过一位参与过先进飞行控制系统设计的专家讲课。这位专家有一句原话是说飞机大多是带故障飞行的。笔者很多研究无人机的师兄们都有意无意的避免坐飞机。笔者坐飞机也会再三确认购买保险 :) 这不是吓唬大家,只是为了说明容错与我们息息相关。本篇我们来聊聊系统容错的方方面面。

1. 可靠性从哪里来

1.1 安全、可靠与可用

安全(safety)可靠(reliable)可用(available)是我们常用的几个词汇。安全通常指避免灾难的能力,可靠指的是无故障提供指定功能的能力,可用指的是某个时间段系统能够正常运行。安全与可靠容易区分。举个例子来说,一架飞机坏了停在地上,它是安全的,因为它不可能引发灾难,但是不可靠,因为它无法完成飞行任务。可靠和可用的区别是什么呢?再举一个例子,你把钱存在银行里,晚上银行下班了,你没法通过柜台取钱。你的资产没有问题,银行具备可靠的保管你的资产的能力,但是它的服务不是7 x 24 小时可用的。

存储行当的人常说的黑话有DU(Data Unavailable)DL(Data Loss)DL指的是数据丢失,DU指的是数据不可用。例如一个存储阵列的机头坏了,数据仍然在硬盘里,但是访问不了,这就是DU。如果一个RAID5,硬盘同时坏掉了二块,数据丢了,那就是DL。保证数据可靠可用是数据系统的生命线,在这个基础上谈性能和功能才有意义。

1.2 失效安全是第一原则

系统设计应该将失效安全确定为第一原则,它指的是如果我们的系统发生故障,应该尽量避免灾难性的后果。典型的例子是电梯故障后第一时间停止不动。数据系统中常常需要去重(deduplication),如何高效的找到重复数据呢?常用的方式是计算数据的指纹,例如数据的MD5哈希值。如果哈希值不同,则认为数据不一致,如果哈希值相同,则直接比较数据确认数据本身一模一样。哈希算法原理上不能排除不同数据有同样的哈希值,但是同样的数据必定有同样的哈希值,所以用哈希值可以过滤掉不同的数据,直接比较原始数据才能确认完全的一致性。这个方法体现了失效安全的设计原则,因为哈希重复的小概率事件不会导致不同的数据被误判成相同而造成数据丢失。

1.3 可靠性从哪里来?

任何系统,无论硬件或软件,都可能存在故障。构成系统的组件越多,系统组件故障概率越高。如何在存在故障情况下仍然保证复杂系统的可靠性和可用性呢?答案是容错,即在系统层面屏蔽组件故障。一切容错方法的基础是冗余,即存在多个组件执行同样的功能。例如数据在多个硬盘上做RAID需要硬盘空间的冗余,服务在多台机器上做热备需要额外的机器做冗余。冗余转化为成本的增加,容错方法增加了系统无故障时的运行代价,必然带来一定的性能损耗。所有的系统设计最后都面临可靠性、性能和成本之间的权衡。我们常听到某些厂商的宣传,说他的系统性能达到物理极限,可靠性达到了几十个九,但是价格非常便宜。从原理上讲这中间可能有一项是在打消费者的马虎眼。可靠性是设计出来的,不是吹出来的。

1.4 容错总有个限度

冗余是可靠性的基础,那么冗余决定着系统对错误容忍的限度。用户成本总是有限的,不可能配置无限制的冗余,所以不存在无限制的容错。例如数据存三分拷贝,那么只能同时容忍三个硬盘故障。那么限度之外的可靠性怎么保证呢?靠管理。拿存储系统来说,必须有人定期巡检,监控硬盘的健康,故障硬盘及时更换,老化的硬盘主动替换。它的目的在于减少故障的概率,延长一次故障和二次故障之间的时间。实际中很多客户或者集成商,硬盘坏了不知道,或者拖延处理,结果造成冗余耗尽,数据丢失,故障演变成灾难。

笔者曾经在某研究所实施系统,实施过程中布线需要拆掉半层楼的地板。某位老师过来帮忙,不小心把旁边友商的电源踢掉了,造成服务不可用,恢复了半天之久。友商系统采用的是三个数据拷贝的冗余,但是因为电源不够,三台机器都连接在同一个电源上,最终造成了一个单点故障。所以说再好的技术也不能弥补管理的漏洞。可靠性是技术和管理相辅相成的结果。

图片

2. 所有的系统都是分布式系统

计算机系统发展到今天,大量采用了分层设计的观念。下层为上层提供服务,上层把下层系统当成一个黑盒子,只关注功能接口,忽略实现细节。分层设计的优势是不同层次的人可以独立工作。分层设计的性能不是最优的。为了提升性能,需要打开黑盒子,给上层提供更多额外的语义,将内部实现机制暴露出来,即所谓协同设计。例如操作系统开发者常常要处理刷TLB缓存,操作memory bar,关注内存顺序模型(memory model)等等。因为计算机硬件的多CPU、多核、内存和外设之间也存在复杂的交互协议,事实上构成了一个分布式系统。为了提升性能,一个CPU指令写内存时,如果内存被别的CPU锁住,它可能选择将写操作缓存到硬件buffer中,异步刷到内存。如果另一个CPU要读同一个内存的内容,这个时候要求程序员调用硬件的某个机制确保刚才的更新操作从buffer到了内存。

图片

上图展示了多CPU和内存在微观层面运行一个MESI协议确保缓存一致性。下图的硬件系统运行的则是更高级和复杂的基于Directory的缓存一致性协议。这些协议并不比一个典型的分布式数据系统使用的算法简单,却在在一个访存指令中完成。软件与硬件并没有特别严格的界限,软中有硬,硬中有软,软硬兼施才是王道。

很多人将存储系统也理解成硬件盒子。事实上即便是最传统的存储系统也是由硬件和软件组成的分布式系统。这其中包括多个主机、硬件柜(JBOD)、多硬盘,且不说主机上运行复杂的存储软件,即便是JBOD和硬盘都不是纯粹的硬件,上面也运行固件(firmware),和存储软件发生复杂的交互行为。可靠性设计正是要从这个分布式系统出发考虑,通过硬件之间的冗余,传

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值