云计算原理与实践
上QQ阅读APP看书,第一时间看更新

2.3 分布式系统概述

2.3.1 分布式系统的基础知识

关于分布式系统,可以从大学教材中找到很多相关知识,例如众所周知的安德鲁·S.塔嫩鲍姆(Andrew S. Tanenbaum)等人在 2002 年出版的《分布式系统原理与范型》(Distributed Systems:Principles and Paradigms)一书。其实,分布式系统的理论出现于20世纪70年代,“Symposium on Principles of Distributed Computing(PODC)”和“International Symposium on Distributed Computing (DISC)”这两个分布式领域的学术会议分别始于1982年和1985年。然而,分布式系统的广泛应用却是近几年的事情,其中一个重要原因就是大数据的出现。

随着社交网络、移动互联网、电子商务等技术的不断发展,互联网的使用者贡献了越来越多的内容。为了处理这些内容,每个互联网公司在后端都有一套成熟的分布式系统用于数据的存储、计算以及价值提取。Google 是全球最大的互联网公司,也是在分布式技术上相对成熟的公司,其公布的Google分布式文件系统GFS、分布式计算系统MapReduce、分布式表格系统Bigtable都成为业界竞相模仿的对象,此外,Google 的全球数据库 Spanner 更是能够支持分布在世界各地上百个数据中心的上百万台服务器。Google的核心技术正是后端这些处理海量数据的分布式系统。与Google类似,国外的亚马逊、微软以及国内互联网三巨头阿里巴巴、百度和腾讯的核心技术也是其后端的海量数据处理系统。

大数据技术的需求是推动分布式系统发展的一大动力。大数据存储技术的演变最初源于互联网公司的大规模分布式存储系统。与传统的高端服务器、高端存储器和高端处理器不同的是,互联网公司的分布式存储系统由数量众多的、低成本和高性价比的普通PC服务器通过网络连接而成。互联网的业务发展很快,而且注重成本,这就使得存储系统不能依靠传统的纵向扩展的方式,即先买小型机,不够时再买中型机,甚至大型机。互联网后端的分布式系统要求支持横向扩展,即通过增加普通PC服务器来提高系统的整体处理能力。普通PC服务器性价比高,故障率也高,需要在软件层面实现自动容错,保证数据的一致性。另外,随着服务器的不断加入,需要能够在软件层面实现自动负载均衡,使系统的处理能力得到线性扩展。

分布式系统的一个主要类别是分布式存储,而分布式存储和当今同样备受关注的云存储和大数据关系密切,分布式存储是基础,云存储和大数据是构建在分布式存储之上的应用。移动终端的计算能力和存储空间有限,而且有在多个设备之间共享资源的强烈的需求,这就使网盘、相册等云存储应用很快流行起来。然而,万变不离其宗,云存储的核心还是后端的大规模分布式存储系统。大数据则更近一步,不仅需要存储海量数据,还需要通过合适的计算框架或者工具对这些数据进行分析,抽取其中有价值的部分。如果没有分布式存储,便谈不上对大数据进行分析。

虽然分布式系统研究了很多年,但是大规模分布式存储系统是在近10年才流行起来,而且起源于以Google为首的企业界而非学术界。绝大部分分布式系统的原理和各大互联网公司的系统范型相关的论文都是比较复杂的,无论是理解还是实践都具有一定的门槛。

2.3.2 分布式系统的特性

乔治·库鲁里斯(George Coulouris)是《分布式系统:概念与设计》(Distributed Systems:Concepts and Design)一书的作者,曾是剑桥大学的高级研究员。他曾经对分布式系统下了一个简单的定义:你会知道系统当中的某台计算机崩溃或停止运行了,但是你的软件却永远不会。这句话虽然简单,但是却道出了分布式系统的关键特性。分布式系统的特性包括容错性、高可扩展性、开放性、并发处理能力和透明性,下面介绍这些概念的含义。

1.容错性

人们可能永远也制造不出永不出现故障的机器。类似的,人们更加难以制造出永不出错的软件,毕竟软件的运行还在一定程度上依赖于硬件的可靠性。那么在互联网上有许多的应用程序和服务,它们都有可能出现故障,但在很多时候,我们几乎都不能发现这些服务中断的情况,这时分布式系统的特点之一容错性就凸显出来了。在大规模分布式系统中,检测和避免所有可能发生的故障(包括硬件故障、软件故障或不可抗力,如停电)往往是不太现实的。因此,人们在设计分布式系统的过程中,就会把容错性作为开发系统的首要目标之一。这样,一旦在分布式系统中某个节点发生故障,利用容错机制即可避免整套系统服务不可用。

故障恢复对于分布式系统设计与开发来说极其重要。当服务器崩溃后,我们需要通过一种方法来回滚永久数据的状态,确保尚未处理完成的数据不被传递到下一个状态继续处理,并解决多个节点数据可能存在的不一致性问题,这往往涉及事务性。常见的避免故障的方法包括消息重发、冗余等。

2.高可扩展性

高可扩展性是指系统能够在运行过程中自由地对系统内部节点或现有功能进行扩充,而不影响现有服务的运行。下面是一个现代分布式系统设计的案例:Storm实时处理系统。在Storm中,节点主要由Spout和Bolt两大类组成,Spout作为消息源会将搜集到的数据发送到Storm计算拓扑中,再通过一系列消息处理单元 Bolt 进行分布式处理,最终将处理结果合并得到最终结果。此处,消息处理单元 Bolt 是分布式数据处理的核心组件,每当消息处理单元的数据处理完成后,它就会把当前阶段处理的数据发送给下一级消息处理单元做进一步处理。利用这种机制,可以随意在消息处理单元后进行扩充,如果数据处理的结果还达不到需求,可在Storm计算拓扑中继续追加新的消息处理单元,直至满足需求。图2.12所示为基本的Storm实时处理系统拓扑结构图,其中每个方框都是一个节点。

图2.12 基本的Storm实时处理系统拓扑结构

3.开放性

分布式系统的开放性决定了一个系统是否具备自我扩展和与其他系统集成的能力。我们可以通过对外提供开放应用程序编程接口(Open API)的方式来提高分布式系统的开放性,提供哪些接口及如何提供决定了开发的系统的开放程度,以及与现有系统和其他系统集成、扩展的能力。有很多开源产品在这方面做得非常好,一方面是因为开源的特性导致系统的开放程度很高,另一方面是因为现代软件开发过程都十分重视开放应用编程接口,以求与更多系统进行集成。当然,只有开放应用编程接口还不够,如果提供的接口能够遵循某种协议,那么势必会进一步增加系统的开放性,为未来发展带来更多可能。

4.并发处理能力

分布式系统引发的一个问题就是并发导致的一致性该如何处理?在分布式系统中,我们假设有两个节点A和B同时操作一条数据仓库的记录,那么数据仓库中的最终结果是由节点A操作产生的,还是由节点 B 操作产生的呢?这样看来,并发请求处理对对象的操作可能相互冲突,产生不一致的结果,设计的分布式系统必须确保对象的操作在并发环境中能够安全使用。因此,对象的并发或同步操作必须确保数据的一致性。除了一致性之外,人们还希望可以一直对系统进行读写,这就是所谓的可用性。

5.透明性

在分布式系统内部,可能有成千上万个节点在同时工作,对用户的一个请求进行处理,最终得出结果。系统内部细节应该对用户保持一定程度的透明,我们可以为用户提供资源定位符(URL)来访问分布式系统服务,但用户对分布式系统内部的组件是无从了解的。我们应该把分布式系统当作一个整体来看待,而不是多个微型服务节点构成的集合。

2.3.3 分布式存储系统实例:Apache Hadoop

Hadoop 是由 Apache 基金会开发的分布式存储与计算框架。用户不需要了解底层的分布式计算原理就可以轻松开发出分布式计算程序,可以充分利用集群中闲置的计算资源,将集群的真正威力调动起来。可以访问Hadoop的官方网站详细了解相关信息。

Hadoop由两个重要模块组成。一个是Hadoop分布式文件系统(Hadoop Distributed File System),顾名思义,就是一个分布式的文件系统,可以将文件数据分布式地存储在集群中的不同节点上。另一个是MapReduce系统,是一个针对大量数据的分布式计算系统。Hadoop的核心组成如图2.13所示。

图2.13 Hadoop的核心组成

1.关于Apache Hadoop

Hadoop的思路来自谷歌提出的MapReduce分布式计算框架。谷歌的MapReduce框架可以把一个应用程序分解为许多并行计算指令,跨越大量的计算节点运行非常巨大的数据集。而一方面Hadoop的MapReduce是对谷歌MapReduce的开源实现;另一方面其分布式文件系统则是谷歌的 GFS的开源实现。

Hadoop原本是Apache Nutch中的一个子项目。后来Apache将MapReduce模块与Nutch Distributed File System(NDFS)单独抽离出来成为一个顶级项目。

Hadoop已经成为目前世界上最流行的分布式计算框架之一,Apache也建立了不少与Hadoop相关的项目,如HBase、Cassandra、Avro、Hive、Mahout等项目。

2.HDFS分布式文件系统

Hadoop分布式文件系统(HDFS)是一个主从式的分布式文件系统,是GFS的一种开源实现。HDFS 可以利用大量廉价存储器组成分布式存储集群,取代昂贵的集中式磁盘存储阵列。而 HDFS集群由一个NameNode和多个DataNode组成,除此之外还有用于热备份的Secondary NameNode,防止集群出现单点故障。

以下介绍HDFS的各个组成部分。

(1)NameNode

NameNode是整个集群的管理者。它并不存储数据本身,而负责存储文件系统的元数据。它负责管理文件系统名称空间,并控制外部客户端对文件系统的访问。

NameNode决定如何将文件内容映射到DataNode的数据块上。此外,实际数据传输并不会经过NameNode,而会让对应的DataNode接收实际数据,并处理分布式存储系统的负载均衡问题。

整个文件系统只有一个 NameNode,因此很明显集群可能会出现单点故障,这点需要利用Secondary NameNode来解决问题。

(2)Secondary NameNode

Secondary NameNode 是 NameNode 的备份节点,HDFS 会将 NameNode 的数据实时备份到Secondary NameNode上,当NameNode宕机需要重启时,则可以利用Secondary NameNode中的数据加快NameNode的重启恢复速度。

(3)DataNode

DataNode是实际的数据存储节点,负责相应NameNode创建、删除和复制块的命令。NameNode会读取来自DataNode的心跳信息,以此判断DataNode是否存活。同一份数据会以多份副本存储在不同的DataNode上,一旦某一个DataNode宕机,NameNode会立即采取手段来处理问题。

(4)MapReduce模型

MapReduce 既是 Hadoop 中的模块,也是一个计算模型。用户需要自己将算法划分成 Map 和Reduce两个阶段。首先将数据划分为小块的数据,将数据分配到不同计算节点的Map任务中计算,然后将计算结果汇总到Reduce节点中进行合并,得出最终结果。

MapReduce系统也是主从式的计算系统。在使用YARN后,每个集群有一个Resource-Manager,用于管理整个集群。集群中每个计算节点都有一个 NodeManager,负责管理某个节点的容器并监视其资源使用。每个应用程序由一个MRAppMaster进行管理。

3.Apache Hadoop特性

Apache Hadoop具有以下几个特点。

(1)高可靠性:Apache Hadoop可以可靠地将数据存储到节点上。

(2)高可扩展性:Apache Hadoop的存储和计算节点可以快速扩展,并自动进行负载均衡。

(3)高效性:一方面 Apache Hadoop 会自动在各个节点之间动态调动数据,保证每个节点存储均衡,另一方面读取数据时我们可以从不同节点并行读取,提高数据读取的速度。

(4)高容错性:Apache Hadoop会将数据冗余存储在不同节点上,保证数据容错性,计算任务失败时也会自动重新分配任务。

(5)低成本:Apache Hadoop是开源软件,可以节省商业软件的购买成本。同时,Apache Hadoop可以用廉价节点组成的集群取代昂贵的超级计算机,从而可以节省硬件成本。

Apache Hadoop虽然是异常可靠的分布式计算框架,但其计算存储模型也导致它的严重缺陷——实时性较差。MapReduce 计算模型本身是一种批处理的计算模型,也就是积累一批数据,启动MapReduce 任务处理完这一批数据,等到下次积累到一定程度,再定时或手动启动一轮新任务,而不是随着数据到来即时处理。

此外,HDFS不是一个高实时性的分布式文件系统。为了提高其实时性,我们还需要自己加上很多缓存优化。而致命问题在于MapReduce各个任务之间的通信完全使用HDFS完成,这也就从根本上导致MapReduce不可能具有极高的实时性。这也为后来Spark计算框架的普及提供了空间。

由于Hadoop十分流行,本书不再详述,读者可以查看官方文档或其他教程来获取进一步的信息。