云计算概论-Google云计算原理与应用

全球最大搜索引擎、Google Maps、Google Earth、Gmail、YouTube等。这些应用的共性在于数据量巨大,且要面向全球用户提供实时服务。因此Google必须解决海量数据存储和快速处理问题。Google研发出了简单而又高效的技术,让多达百万台的廉价计算机协同工作,共同完成这些任务,这些技术在诞生几年后才被命名为Google云计算技术

Google文件系统GFS

Google文件系统(Google File System, GFS)是一个大型的分布式文件系统。它为Google云计算提供了海量存储,并且与Chubby、Map Reduce及Bigtable等技术结合十分紧密,处于所有核心技术的层。GFS不是一个开源的系统,我们仅能从Google公布的技术文档来获得相关知识。
当前主流分布式文件系统有RedHat的GFS (Global File System)IBM的GPFS、Sun的Lustre等。这些系统通常用于高性能计算或者大型数据中心,对硬件设施要求较高。
GoogleGES的新颖之处在于它采用廉价的商用机器构建分布式文件系统,同时将GFS的设计Google应用的特点紧密结合,简化实现,使之可行,最综达到创意新颖、有用、可行的完美组合。GFS将容错的任务交给文件系统完成,利用软件的方法解决系统可靠性问题,使存储的成本成倍下降。GFS将服务器故障视为正常现象,并采用多种方法,从多个角度,使用不同的容错措施,确保数据的安全、保证提供不间断的数据存储服务。

系统架构

在这里插入图片描述

GFS将整个系统节点分为三类角色

在这里插入图片描述

GFS的实现机制

  • 客户端首先访问Master节点,获取交互的Chunk Server信息,然后访问这些Chunk Server,完成数据存取工作。这种设计方法实现了控制流和数据流的分离
  • Client与Master之间只有控制流而无数据流,极大地降低了Master的负载。
  • Client与Chunk Server之间直接传输数据流,同时由于文件被分成多个Chunk进行分布式存储,Client可以同时访问多 个Chunk Server,从而使得整个系统的I/O高度并行,系统整体性能得到提高

GFS的特点

采用中心服务器模式

GFS采用中心服务器模式管理整个文件系统,简化了设计,降低了实现难度。Master管理分布式文件系统中的所有元数据。文件被划分为Chunk进行存储,对于Master来说,每个ChunkServer只是个存储空间。Client发起的所有 操作都需要先通过Master才能进行。

  • 可以方便地增加Chunk Server。
  • Master掌握系统内所有Chunk Server的情况,方便进行负载均衡。
  • 不存在元数据的一致性问题。
不缓存数据

缓存(Cache) 机制是提升文件系统系能的一个重要手段,通过文件系统为了提高性能,一般需要实现复杂的缓存机制。GFS文件系统根据应用的特点,没有实现缓存。

  • 文件操作大部分是流式读写,不存在大量重复读写,使用Cache对性能提高不大。
  • Chunk Server上数据存取使用本地文件系统从可行性看,Cache与实际数据的一致性维护也极其复杂。
在用户态下实现

文件系统是操作系统的重要组成部分,通常位于操作系统的底层(内核态)。在内核态实现文件系统,可以更好的和操作系统本身结合,向上提供兼容的POSIX接口。然而,GFS却选择在用户态下实现。

  • 在用户态下实现,直接利用POSIX编程接口存取数据,无须了解操作系统的内部实现机制和接口,降低了实现难度,提高通用性。
  • POSIX接口提供功能更丰富,在实现过程中可以利用更多的特性,而不像内核编程那样受限。
  • 用户态下有多种调试工具,而在内核态中调试相对困难。
  • Master和Chunk Server都以进程方式运行,单个进程不影响整个操作系统,从而可以对其进行充分优化。在内核态下,如果不能很好地掌握其特性,效率不但不会高,甚至还会影响到整个系统运行的稳定性。
  • 在用户态下,GFS和操作系统运行在不同的空间,两者耦合性降低,方便GFS自身和内核的单独升级。

容错机制

Master容错

在这里插入图片描述
当Master发生故障时, 在磁盘数据保存完好的情况下,可以迅速恢复以上元数据。
为了防止Master彻底死机的情况,GFS还提供了Master远程的实时备份,这样在当前的GFS Master出现故障无法工作的时候,另外一台GFS Master可以迅速接替其工作。

Chunk Server容错

  • GFS采用副本的方式实现Chunk Server的容错。
  • 每一个Chunk有多 个存储副本(默认为三个),分布存储在不同的ChunkServer上。
  • 对于每一个Chunk,必须将所有的副本全部写入成功,才视为成功写入相关的副本出现丢失或不可恢复等情况,Master自动将该副本复制到其他ChunkServer,从而确保副本保持一定的个数。
  • GFS中的每一 个文件被划分成多个Chunk, Chunk的默认大小是64MB
  • 当读取一一个Chunk时,ChunkServer会将读取的数据和校验和进行比较,如果不匹配,就会返回错误,使Client选择其他ChunkServer上的。
效果图:

在这里插入图片描述

系统管理技术

GFS是一个分布式文件系统, 包含从硬件到软件的整套解决方案。除了上面提到的GFS的一些关键技术外,还有相应的系统管理技术来支持整个GFS的应用,这些技术可能不一定为GFS独有。

大规模集群安装技术

GFS集群中通常有非常多的节点,而现在的Google数据中心动辄有万台以上的机器在运行。需要相应的技术支撑。

故障检测技术

GFS构建在不可靠廉价计算机之上的文件系统,由于节点数目众多,故障发生十分频繁。

节点动态加入技术

当有新的ChunkServer加入时,如果需要实现安装好系统,那么系统扩展将是一件繁琐的事请。能够做到只需裸机加入,j就会自动获取系统并安装运行,大大减少GFS维护工作量。

节能技术

Google采用了多种机制降低服务器能耗,如采用蓄电池代替昂贵的UPS(不间断电源系统)。

分布式数据处理MapReduce

MapReduce是Google提出的一个软件架构,是一种处理海量数据的并行编程模式,用于大规模数据集(通常大于1TB)的并行计算。Map (映射)、Reduce(简化) 的概念和主要思想, 都是从函数式编程语言和矢量编程语言借鉴来的。正是由于MapReduce有函数式和矢量编程语言的共性,使得这种编程模式特别适合于非结构化和结构化的海量数据的搜索、挖掘、分析与机器智能学习等。

产生背景

Jeffrey Dean(Google MapReduce 架构设计师):Jeffery Dean设计一个新的抽象模型,封装并行处理、容错处理、本地化计算、负载均衡的细节,还提供了一个简单而强大的接口。这就是MapReduce。

MapReduce这种并行编程模式思想最早是在1995年提出的。

与传统的分布式程序设计相比,MapReduce封装 了并行处理容错处理本地化计算负载均衡等细节,还提供了一个简单而强大的接口。通过这个接口,可以把大尺度的计算自动地并发和分布执行,使编程变得非常容易。另外,MapReduce也具有较好的通用性,大量不同的问题都可以简单地通过MapReduce来解决

MapReduce把对数据集的大规模操作,分发给一个主节点管理下的各分节点共同完成,通过这种方式实现任务的可靠执行与容错机制。在每个时间周期,主节点都会对分节点的工作状态继续标记。一旦分节点状态标记为死亡状态,则这个节点的所有任务都将分配给其他分结点重新执行。

据相关统计,每使用一次Google搜索引擎, Google的后台服务器就要进行10^11运算。这么庞大的运算量,如果没有好的负载均衡机制,有些服务器的利用率会很低,有些则会负荷太重,有些甚至可能死机,这些都会影响系统对用户的服务质量。而使用MapReduce这种编程模式, 就保持了服务器之间的均衡,提高了整体效率。

编程模型

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

举例:

例如,假设我们想利用MapReduce来计算一 个大型文本文件中各个单词出现的次数,Map的输入参数指明了需要处理哪部分数据,以"<在文本的起始位置,需要处理的数据长度>”表示,经过Map处理,形成- -批中间结果"<单词,出现次数>”。而Reduce函数处理中间结果,将相同单词出现的次数进行累加,得到每个单词总的出现次数。
在这里插入图片描述

Map代码部分:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class Demo {

	public static void main(String[] args) {
		//!list有序,set和map无序
		//创建ArrayList
		ArrayList list = new ArrayList();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("a");
		System.out.println(list); //[a, b, c, a]
		//创建HashSet
		HashSet set = new HashSet();
		set.add("a");
		set.add("b");
		set.add("c");
		set.add("a");
		System.out.println(set); //[a, b, c]
		//创建HashMap--键值对 (key, value)
		//键值对 key=是内容 value=是序号
		//			  a          1
		//			  b          2
		//			  c          3
		//			  a          4
		//注意:尽量保证key唯一
		HashMap map = new HashMap();
		map.put("a", 1);
		map.put("b", 2);
		map.put("c", 3);
		map.put("a", 4);
		System.out.println(map); //{a=4, b=2, c=3}
		//键值对 key=姓名 value=成绩
		//          张三              100
		//          李四              90
		//          王五              95
		HashMap map1 = new HashMap();
		map1.put("张三", 100);
		map1.put("李四", 90);
		map1.put("王五", 95);
		System.out.println(map1); //{李四=90, 张三=100, 王五=95}
	}
	
}
效果图:

在这里插入图片描述

实现机制

在这里插入图片描述

  • (1) MapReduce函数首先把输入文件分成M块,接着在集群的机器上执行分派处理程序。
  • (2)这些分派的执行程序中有一个程序比较特别,它是主控程序Master。剩下的执行程序都是作为Master分派的Worker (工作机)。总共有M个Map任务和R个Reduce任务需要分派,Master选择空闲的Worker来分配这些Map或Reduce任务。
  • (3)一个被分配了 Map任务的Worker读取并处理相关的输入块。它处理输入的数据,并将分析出的<key,value>对传递给用户定义的Map函数。Map函数产生的中间结果< key,value>对暂时缓冲到内存。
  • (4)这些缓冲到内存的中间结果将被定时写到本地硬盘,这些数据通过分区函数分成R个区。中间结果在本地硬盘的位置信息将被发送回Master,然后Master负责把这些位置信息传送个ReduceWorker。
  • (5)当Master通知执行Reduce的Worker关于中间< key,value>对的位置时,它调用远程过程,从MapWorker的本地硬盘上读取缓冲的中间数据。当Reduce Worker读到所有的中间数据,它就使用中间key进行排序,这样可使相同key的值都在一起。 因为有许多不同key的Map都应对相同的Reduce任务,所以,排序是必须的。如果中间结果过于庞大,那么就需要使用外排序。
  • (6) Reduce Worker根据每一个唯一 中间key来遍历所有的排序后的中间数据, 并且把key和相关的中间结果值集合传递给用户定义的Reduce函数。Reduce函数的结果写到一个最终的输出文件。
  • (7)当所有的Map任务和Reduce任务都完成的时候,Master激活用户程序。此时MapReduce返回用户程序的调用点。

容错机制

由于MapReduce在成百上千台机器上处理海量数据,所以容错机制是不可或缺的。总的来说,MapReduce通过重新执行失效的地方来实现容错。

Master失效

Master会周期性地设置检查点(checkpoint)并导出Master的数据。一旦某个任务失效,系统就从最近的一个检查点恢复并重新执行。由于只有一个Master在运行,如果Master失效了,则只能终止整个MapReduce程序的运行并重新开始。

Worker失效

Master会周期性地给Worker发送ping命令,如果没有Worker的应答,则Master认为Worker失效,终止对这个Worker的任务调度,把失效Worker的任务调度到其他Worker上重新执行。

案例分析

假设有一批海量的数据,每个数据都是由26个字母组成的字符串原始数据集合是完全无序的,怎样通过MapReduce完成排序工作,使其有序(字典序)呢?

注:排序通常用于衡量分布式数据处理框架的数据处理能力。

第一步:

对原始的数据进行分割(Split),得到N个不同的数据分块。
在这里插入图片描述

第二步:

Map阶段:
对每一个数据分块都启动一个Map进行处理。
采用桶排序的方法,每个Map中按照首字母将字符串分配到26个不同的桶中。
在这里插入图片描述

第三步:

对于Map之后得到的中间结果,启动26个Reduce。按照首字母将Map中不同桶中的字符串集合放置到相应的Reduce中进行处理。
具体来说就是首字母为a的字符串全部放在Reduce1中处理,首字母为b的字符串全部放在Reduce2,以此类推。每个Reduce对于其中的字符串进行排序,结果直接输出。由于Map过程中已经做到了首字母有序,Reduce输出的结果就是最终的排序结果。
在这里插入图片描述

分布式锁服务Chubby

初步了解Chubby

Chubby是Google设计的提供粗粒度锁服务的一个文件系统,它基于松耦合分布式系统,解决了分布的一致性问题。

通过使用Chubby的锁服务,用户可以确保数据操作过程中的一致性,这种锁只是一种建议性的锁而不是强制锁,这种选择使系统具有更大的灵活性。

GFS使用Chubby选取一个GFS主服务器,Bigtable使用Chubby指定一个主服务器并发现、控制与其相关的子表服务器。除了最常用的锁服务,Chubby作为一个稳定的存储系统存储包括元数据在内的小数据。

Google内部还使用Chubby进行名字服务(NameServer)。

Paxos算法

Paxos算法是Leslie Lamport最先提出的一种基于消息传递的一致性算法,用于解决分布式系统中的一致性问题。在目前所有的一致性算法中,该算法最常用且被认为是最有效的。
分布式系统的一致性问题,就是如何保证系统中初始状态相同的各个节点在执行相同的操作序列时,看到的指令是完全一致的, 并且最终得到完全一致的结果。

方案:
在分布式系统中设置一个专门节点,在每次需要进行操作前,系统的各个部分向它发出请求,告诉该节点接下来系统要做什么。该节点接收第一个到达的请求内容作为接下来的操作,这样就能够保证系统只有一个唯一的操作序列。 但是这样做也有一个很明显的缺陷,那就是一旦这 个专门节点失效,整个系统就很可能出现不一致。为了避免这种情况,在系统中必然要设置多个专门节点,由这些节点来共同决定操作序列。针对这种多节点决定操作序列的情况,Leslie Lamport提出了Paxos算法。

三个节点,三个条件

在这里插入图片描述

系统的约束条件

p1:每个acceptor只接受它得到的第一个决议。
p2:一旦某个决议得到通过,之后通过的决议必须和该决议保持一致。

p2a:一旦某个决议v得到通过,之后任何acceptor再批准的决议必须是v。
p2b:一旦某个决议v得到通过,之后任何proposer再提出的决议必须是v。

Chubby系统设计

通常情况下Google的一个数据中心仅运行一-个Chubby单元, 这个单元需要支持包括GFS、Bigtable在内的众多Google服务 ,因此在设计Chubby时候,必须充分考虑系统需要实现的目标以及可能出现的各种问题。

Chubby的设计目标主要有以下几点:

  • 高可用性和高可靠性:这是系统设计的首要目标,在保证这一目标的基础上在考虑系统的吞吐量和存储能力。
  • 高扩展性:将数据存储在价格较为低廉的RAM,支持大规模用户访问文件。
  • 支持粗粒度的建议性锁服务:根本目的是提高系统的性能。
  • 服务信息的直接存储:可以直接存储包括元数据、系统参数在内的有关服务信息,而不是再维护另一个服务。
  • 支持缓存机制:用户可以及时的了解到事件的发生。
  • 支持通报机制:通过一致性缓存将常用信息保存在客户端,避免了频繁地访问主服务器。

Chubby的基本架构

在这里插入图片描述
客户端:在客户这一端每个客户应用程序都有一个Chubby程序库(Chubby Library) ,客户端的所有应用都是通过调用这个库中的相关函数来完成的。

服务器端:服务器一端称为Chubby单元,一 般是由五个称为副本(Replica) 的服务器组成的,这五个副本在配置上完全一致, 并且在系统刚开始时处于对等地位。

Chubby中的Paxos

单个Chubby副本结构

在这里插入图片描述

  • (1)最底层是一个容错地日志,该日志对于数据库的正确性提供了重要的支持。不同副本上日志的一致性正是通过Paxos算法来保证的。副本之间通过特定的Paxost协议进行通信,同时本地文件中还保存有一份同Chubby中相同的日志数据。
  • (2)最底层上是一个容错的数据库,这个数据库主要包括一个快照和一个记录数据库操作的重播日志,每一次的数据库操作最终都将提交至日志中。 和容错的日志类似的是,本地文件中也保持着一份数据库数据副本。
  • (3) Chubby构建在这个容错的数据库之上,Chubby利用这个数据库存储所有的数据。Chubby的客户端通过特定的Chubby协议和单个的Chubby副本进行通信。

由于副本之间的一致性问题,客户端每次向容错的日志中提交新的值时,Chubby就会自动调用Paxos架构保证不同副本之间数据的一致性。

分布式结构化数据表Bigtable

初步了解Bigtable

Bigtable是Google开发的基于GFS和Chubby的分布式存储系统。Google的很多数据,包括Web索引、卫星图像数据等在内的海量结构化和半结构化数据,都存储在Bigtable中。从实际上看,Bigtable并没有什么全新的技术,但是如何选择合适的技术并将这些技术高效、巧妙地结合在一起恰恰是 最大的难点。Bigtable在很多方面和数据库类似,但它并不是真正意义上的数据库。

设计动机与目标

Bigtable的设计动机

  • 需要存储的数据种类繁多:包括URL、网页内容、用户的个性化设置在内的数据都是Google需要经常处理的。
  • 海量的服务请求:Google运行着目前世界上最繁忙的系统,它每时每刻处理的客户服务请求数量是普通的系统根本无法承受的。
  • 商用数据库无法满足需求:一方面现有商用数据库的设计着眼点在于其通用性。另一方面对于底层系统的完全掌控会给后期的系统维护、升级带来极大的便利。

Bigtable应达到的基本目标

  • 广泛的适用性:Bigtable是为了满足一系列Google产品而并非特定产品的存储要求。
  • 很强的可扩展性:根据需要随时可以加入或撤销服务器。
  • 高可用性:确保几乎所有的情况下系统都可用。
  • 简单性:底层系统的简单性既可以减少系统出错的概率,也为上层应用的开发带来便利。

数据模型

Bigtable数据的存储格式

Bigtable是一个分布式多维映射, 表中的数据通过一个行关键字(Row Key)、一个列关键字(Column Key)以及一个**时间戳(**Time Stamp)进行索引。

Bigtable的存储逻辑可以表示为:(row:string, column:string, time:int64)→string
在这里插入图片描述

行:
  • Bigtable的行关键字可以是任意的字符串,但是大小不能够超过64KB
  • 表中数据都是根据行关键字进行排序的,排序使用的是词典序
  • 同一地址域的网页会被存储在表中的连续位置
  • 倒排便于数据压缩, 可以大幅提高压缩率
列:
  • 将其组织成所谓的列族(Column Family)
  • 族名必须有意义, 限定词则可以任意选定
  • 组织的数据结构清晰明了, 含义也很清楚
  • 族同时也是Bigtable中访问控制(Access Control)的基本单元
时间戳:
  • Google的很多服务比如网页检索和用户的个性化设置等都需要保存不同时间的数据,这些不同的数据版本必须通过时间戳来区分
  • Bigtable中的时间戳是64位整型数,具体的赋值方式可以用户自行定义

系统架构

Bigtable基本架构

在这里插入图片描述

主服务器

主服务器功能

  • 新子表分配
  • 子表服务器状态监控
  • 子服务器之间的负载均衡

解释:

  • 当一个新的子表产生时,主服务器通过一个加载命令将其分配给一个空间足够的子表服务器。
  • 创建新表、表合并以及较大子表的分裂都会产生一个或多个新子表。
  • 分割完成之后子服务器需要向主服务发出一个通知。
  • 主服务器必须对子表服务器的状态进行监控,以便及时检测到服务器的加入或撤销。

子表服务器

子表实际组成

  • 不同子表的SSTable可以共享
  • 每个子表服务器上仅保存一个日志文件
  • Bigtable规定将日志的内容按照键值进行排序
  • 每个子表服务器上保存的子表数量可以从几十到上千不等,通常情况下100个左右
    在这里插入图片描述

SSTable格式的基本示意

SSTable是Google为Bigtable设计的内部数据存储格式。所有的SSTable文件都存储在GFS上,用户可以通过键来查询相应的值。
在这里插入图片描述
SSTable中的数据被划分为一个一个的块(Block) ,每个块的大小是可以设置的,一个来说设置为64KB。在SSTable的结尾有一个索引(Index) ,这个索引保存了SSTable中块的位置信息,在SSTable打开时这个索引 |会被加载进内存,这样用户在查找某个块时在内存中查找块的位置信息,然后在硬盘上直接找到这个块,这种查找速度非常快。

Google应用程序引擎

Google App Engine简介

什么是Google App Engine?

Google App Engine是一个由Python应 用服务器群、Bigtable数据库及GFS数据存储服务组成的平台,它能为开发者提供一-体化的可 自动升级的在线应用服务。

Google App Engine可以让开发人员在Google的基础架构上运行网络应用程序。
在Google App Engine中,用户可以使用appspot.com域上的免费域名为应用程序提供服务,也可以使用Google企业应用套件从自己的域为它提供服务。
可以免费使用Google App Engine。注册个免费账户即可开发和发布应用程序,而且不需要承担任何费用和责任。

Google App Engine的整体架构

在这里插入图片描述

应用程序环境

应用程序环境的特征

  • 动态网络服务功能。能够完全支持常用的网络技术。
  • 具有持久存储的空间。 在这个空间里平台可以支持一些基本操作, 如查询、分类和事务的操作。
  • 具有自主平衡网络和系统的负载、自动进行扩展的功能。
  • 可以对用户的身份进行验证, 并且支持使用Google账户发送邮件
  • 有一个功能完整的本地开发环境,可以在自身的计算机上模拟GoogleApp Engine环境。

Google App Engine服务

  • 图像操作API:Image类、exception类
  • 邮件API:允许的附件类型、EmailMessage类
  • Memcache API:构造函数、实例方法
  • 用户API:User对象、登录网址、User类
  • 数据库API:Model类、Property类、Query类、GqlQuery类、Key类

注:实现机制为主要掌握的内容

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值