前言
我们为什么需要分布式
在我们构建系统的时候,我们通常期望的是程序运行的性能随着计算机性能的增加而线性增长。但是这通常只有在单个计算机,或者仅仅是单核性能的提升时才能发生。如果我们需要的是 IO 性能的话,多加磁盘到了一定程度后的提升也不会太大。如果我们试图使用增加计算机数量的方式来增强性能时,我们就不得不考虑不同计算机之间互相通信的问题。为了解决这种多机协同处理数据的能力,我们可以引入分布式的思想。
分布式应具有的特点
- 可扩展性(Scalability)
- 可用性(Availability)
- 一致性(Consistency)
使用例
谷歌的 MapReduce
摘自MIT6.824 1.7 MapReduce 基本工作方式
MapReduce 是由 Google 设计,开发和使用的一个系统,相关的论文在 2004 年发表。
MapReduce 的基本使用
我们假设现在有 输入文件1
,输入文件2
和 输入文件3
,这些输入可能是从网上抓取的网页,更可能是包含了大量网页的文件。
MapReduce 启动时,会查找 Map
函数。之后,MapReduce 框架会为每个输入文件运行 Map
函数。这里很明显有一些可以并行运算的地方,比如说可以并行运行多个只关注输入和输出的 Map
函数。
Map
函数以文件作为输入,文件又是整个输入数据的一部分。Map 函数的输出是一个 key-value 对的列表。
运算的第二阶段是运行 Reduce
函数。MapReduce 框架会收集所有 Map 函数输出的 key-value 交给 Reduce
函数进行统计处理。
当然一次 MapReduce 基本是不足以解决问题的,我们通常会将多次 MapReduce 串联起来,这样可以解决更加复杂的问题。
GFS 分布式储存
摘自MIT6.824 3.1 分布式存储系统的难点(Why Hard)
背景
你可以想象,在分布式系统中,可能有各种各样重要的抽象可以应用在分布式系统中,但是实际上,简单的存储接口往往非常有用且极其通用。所以,构建分布式系统大多都是关于如何设计存储系统,或是设计其它基于大型分布式存储的系统。
GFS 论文涉及到的话题
分片、容错、复制和一致性。
分片
为了提升性能,自然的想法就是将数据分割放到大量的服务器上,这样就可以并行的从多台服务器读取数据。我们将这种方式称之为分片(Sharding)。
容错
我们在成百上千台服务器中进行分片时,宕机就属于一种常态的事件。因此,我们需要自动化的处理发生的错误。这个目标就是容错(Fault Tolerance)。
复制
为了容错,我们应该持有多份数据的副本。这样,当一台服务器宕机时,我们可以从其它服务器上获取数据。在我们写入数据的时候,我们也应该把数据写入到多个服务器上。这就是复制(Replication)。
一致性
当我们从多个服务器上读取数据时,我们希望读取到的数据是一致的,但数据在不同的服务器上写入的时候很可能是不同步的,这个问题就是一致性(Consistency)。但是要实现完全的一致性,我们就不得不牺牲一大部分的性能来保证数据完整的拷贝。因此在实际应用中,我们通常只保证一定程度的一致性。