MIT6.033系统设计3:分布式层面的设计

现在非常多的计算机系统都是分布式的,因为我们在一台机器上无法部署整个系统,因此需要用多个物理机构成的集群来部署一个完整的系统,每一台物理机有不同的职责,这个时候的系统就是分布式的。同时,我们使用的计算机物理设备往往是不可靠的,随时可能会因为各种问题而发生崩溃,而分布式系统中有多台物理机,因此发生崩溃的概率会更高,如何在不可靠的设备上建立可信的系统,保证系统能够稳定地提供各种服务,成为了分布式系统设计中最需要考虑的问题之一。

数据中心和云

数据中心和云是现在计算机产业界的基础设施,数据中心通过大量的机器存储各种各样的数据,而云则对外提供了各种方便的云服务。
数据中心由一个个计算机集群组成,每个集群包含多个rack(机架),每个机架上会有多台物理机,物理机用来存储数据,同时,很多数据中心被部署在云端,可以对外提供数据的云存储服务。
image.png
同时,数据中心存储的数据,为了能够容错容灾,会进行冗余备份,在多台物理机上存储多份相同的数据,来保证某台物理机在发生故障的时候,数据不会丢失,依然可以被正常读取使用。如下图所示,数据中心通过层级化的交换机网络来构建数据的冗余备份。从最顶端的交换机开始,会有多条不同的路径通向同一份数据。
image.png
image.png

可信系统

我们使用的各种硬件设备实际上是不可靠的,随时都有可能因为各种原因崩溃,那么如何保证运行在这些物理设备上的系统是可信的?首先我们要在系统开发阶段,就辨识系统可能出现的各种错误和异常情况,并制定好解决方案,然后在系统运行的时候用一定的机制检测错误并及时进行错误处理。这样才能保证系统提供的服务是可信的。
对于一个系统而言,其错误处理能力可以用AFR(全年错误率)和MTBF(错误间的平均时间)等指标进行计算
磁盘阵列(RAID)是一种处理系统崩溃的常见方式,通过冗余的备份,将数据多份保存,以便在一个备份崩溃的时候启用另一个备份,常见的RAID策略有:

  • RAID1:镜像备份,对于N个磁盘的数据量,实际存储的时候需要2N个磁盘
  • RAID4:将N个磁盘的数据通过XOR运算后保存在1个新的磁盘中,需要N+1个磁盘
  • RAID5:将1个磁盘能保存的文件分散到N+1个磁盘上面

image.png
这几种RAID都可以处理单个磁盘崩溃的情况。

事务Transaction

事务又是计算机系统设计中的一个重要概念。前面我们说,为了建立可信的系统,我们需要建立各种纠错机制,而优秀的纠错机制建立在优秀的程序抽象上面,而事务就是为了保证系统的可靠性,对系统中一些操作集合所提出的进一步抽象,一个事务包含了若干个连续的操作,具有原子性和独立性,一方面,事务只能被完整地执行或者完全不执行,这就是原子性,另一方面,事务的执行不能被其他程序所干扰,这就是独立性。
对于单个用户和单个文件的操作,事务的原子性可以用浅拷贝来实现,即操作之前先拷贝一份一样的文件,然后在拷贝的文件上面进行操作,如果成功了,就让原有的文件被修改后的文件所覆盖,但是这种方法的效率非常低下。

日志与原子性Atomic

日志Logging为我们提供了一种更好的事务原子性实现办法,它的做法说白了就是在进行具体的操作前先把要进行的操作写下来,如果出现了问题需要回滚,就根据日志中记录的操作从后往前进行回归,不过这个又涉及到具体的事务回滚算法,这里按下不表。

独立性Isolation

我们说事务需要提供原子性和独立性,原子性可以由日志来提供,而独立性我们至今为止还没有实现。事务的独立性要求多个事务独立执行,互相之间不会受到不必要的干扰。如果我们有两个事务同时处理一块内存上的数据,那么我们就会面临访问冲突的问题。
二阶段锁协议(Two-phase Locking, 2PL)就是一种实现事务独立性的方法,它的具体规定如下:

  • 每个需要被共享的变量都有一个锁
  • 在操作某个变量之前,事务必须获得对应的锁
  • 在一个事务释放了锁之后,它就不能再申请任何的锁

image.png