7.这就是搜索引擎:核心技术详解 --- 云存储与云计算 

第7章 云存储与云计算 
 7.1 云存储与云计算概述 
  7.1.1 基本假设 
		1.大量廉价pc构成
		2.机器节点出现故障是常态
		3.水平增量扩展
		4.弱数据一致性
		5.读多写少型服务

  7.1.2 理论基础 
		CAP,BASE,ACID 及最终一致性。
		BASE 原则和 ACID 原则不同,是通过牺牲强数据一致性来获得高可用性的。尽管大多数云存储系统采纳了BASE原则,但是值得注意的是:云系统的发展过程中正向逐步提供局部
	  ACID特性发展,即全局而言符合BASE原则,但是局部支持ACID原则。这样就可以吸取两者各自的好处,在两者之间建立平衡,从google的MegaStore可以看出这种发展趋势。

  7.1.3 数据模型 
		所谓数据模型,就是云存储架构在应用开发者眼中是何种形式,比较常见的数据模型有2种:key/value 模式和模式自由列表模式。
		模式自由列表模式,每个记录由一个唯一的主键标识,不同点在于数据值,类似于关系数据库,数据值由若干个列属性构成,但是与数据库不同的是:数据库一旦确定包含哪些属性,
	  就固定不变,而云存储系统则不受此约束,可以随时增加或者删除某个列属性,同时每一行只存储部分列属性,不必完全存储。
	  	在云存储系统内部实现存储结构的时候,最终可以归结为两种实现方式:哈希加链表或者B+树的方式。哈希加链表查询速度比较快,但是一次只能查询一条记录,无法支持批量顺序查找
	  记录(scan方式),而B+树则支持这种查找方式,但是其管理方式相对复杂。

  7.1.4 基本问题 
		1.数据如何在机器之间分布
		2.多备份数据如何保证一致性
		3.如何响应客户端的读写请求
		4.加入(或者坏掉)一台机器如何处理
		5.如何在机器之间进行负载均衡

  7.1.5 Google的云存储与云计算架构 
		从大的角度划分,可以将这些计数划分为两类:
			1.云存储技术
				GFS文件系统
				Chubby 锁服务
				BigTable
				MegaStore

			2.云计算技术
				MapReduce
				Percolator
				Pregel

			    GFS 是一个分布式文件系统,对海量数据提供了底层的存取支持,至于文件内容本身不做格式要求。BigTable 提供了数据的结构化和半结构化视图,其数据模型与具体应用更
			  贴近,同时BigTable 提供了记录行内针对列属性的原子操作,即实现了基于行的事务,但不提供行间或者表间的事务支持;MegaStore 则在 BigTable 基础上在事务支持方面又向
			  数据库方向前进了异步,支持对数据的分组,组内数据支持ACID原则,同时强调局部数据的强数据一致性和高可用性,可在此基础上直接提供面向用户的实时交互服务。Chubby 则在
			  GFS和BigTable中起到了很大的作用,包括主服务器的选举,元数据的存储,粗粒度的锁服务等。
			  	MapReduce 和 Percolator 这2个模型则是在以上云存储架构下的计算模型,两者都是后台计算模型,即实时性不够,比较适合后天运算。mapreduce 适合做大规模数据的全局
			  统计,对于数据的增量更新无法支持。而 percolator 则是对 mapreduce 计算模型的补充,可以对已有数据做部分更新,并在bigtable的行事务基础上提供行间事务和表间事务,
			  同时利用观察同时的方式来组织运算系统。而Pregel 计算模型则是专门针对大型图结构研发的云计算技术。另外,google 正在进行第二代GFS以及代号为 Spanner 的第二代bigtable
			  的研发。
			  	受google云存储与云计算架构的启发,开源届组织起功能类似的Hadoop项目。其中 HDFS 类似于GFS文件系统的功能,HBase 则是仿照 bigtable 设计的,zookeeper 起到类似于
			  Chubby 的功能,同时hadoop也支持mapreduce计算模型。

 7.2 Google文件系统(GFS) 
		在google的云存储,云计算框架中,gfs是其他相关技术的基石,因为gfs提供了海量非结构化信息的存储平台,并提供了数据的冗余备份,成千台服务器的自动负载均衡以及失效服务器检测等各种
	  完备的分布式存储功能。

  7.2.1 GFS设计原则 
		1.gfs 采用大量商业pc来构建存储集群
		2.gfs 文件系统所存储的文件绝大多数是大文件,文件大小部分在 100MB 到几个GB之间,所以系统的设计应该对这种大文件的读写操作做出优化。尽管gfs也支持小文件读写,但是不作为重点,也
		不会进行正对性的操作优化。
		3.系统中存在大量的追加写操作,即将新增内容追加到已有文件的末尾,已经写入的内容一般不做更改,很少有文件的随机写行为,即指定已有文件中间的某个位置,在这个位置之后写入数据。
		4.对于数据读取操作来说,绝大多数读文件操作都是顺序读,少量的操作是随机读,即按照数据在文件中的顺序,一次顺序读入较大量的数据,而不是不断定位到文件指定位置,读取少量数据。

  7.2.2 GFS整体架构 
		gfs 文件系统主要由3个组成部分构成:唯一的主控服务器(master),众多的chunk服务器和 gfs 客户端。主控服务器主要做管理工作,chunk服务器负责实际的数据存储并响应gfs客户端的
	  读写请求。尽管gfs由上千台机器构成,但是在应用开发者眼中,gfs类似于本地的统一文件服务器,分布式存储系统的细节对应用开发者来说不可见。

	  	在应用开发者来看,gfs文件系统类似于linux文件系统或者是windows操作系统提供的文件系统,即由目录和存放在某个目录下的文件构成的树形结构。在gfs系统中,这个树形结构被称作gfs命名空间。
	  同时,gfs为应用开发者提了文件的创建,删除,读取和写入等常见的操作接口(API)。
	  	gfs 中存储的都是大文件,虽然每个文件大小各异,但是gfs在实际存储的时候,首先会将不同大小的文件切割成固定大小的数据块,每一块被称作一个chunk,通常chunk的大小设定为64MB,这样,每个文件
	  就由若干个大小固定的chunk构成。
	  	每个gfs文件被切割成固定大小的chunk,gfs即以chunk为基本存储单元,同一个文件的不同chunk可能存储在不同的chunk服务器上,每个chunk服务器可以存储很多来自于不同文件的chunk数据。另外,
	  在chunk服务器内部,会对chunk进一步切割,将其切割为更小的数据块,每一块也被称作一个block,这是文件读取的基本单位,即一次读取至少一个block。
	  	总结起来就是:gfs命名空间由众多的目录和gfs文件构成,一个gfs文件由众多固定大小的chunk构成,每个chunk又由更小粒度的block构成,chunk是gfs中基本的存储单元,而block是基本的读取单位。
	  	gfs 主控服务器主要做管理工作,不仅要维护gfs的命名空间,还要维护chunk的命名空间,之所以如此,是因为在gfs系统内部,为了能够识别不同的chunk,每个chunk都会被赋予一个独一无二的编号,
	  所有chunk的编号构成了chunk命名空间,gfs主控服务器还记录了每个chunk存储在哪台chunk服务器上的信息。另外,因为gfs文件被切割成了chunk,gfs系统内部就需要维护文件名称到其对应的多个chunk
	  之间的映射关系。chunk服务器负责对chunk的实际存储,同时相应gfs客户端对自己负责的chunk的读写请求。

	  	对于gfs客户端来说,应用开发者提交的读数据请求是:读取文件file,从某个位置p开始读,读出大小为L的数据。gfs系统在接收到这种请求后,会在内部做转换,因为chunk大小是固定的,所以从p位置和大小
	  L可以推算出要读的数据位于文件file中的第几个chunk中,即请求被转换为 <文件file,chunk序号> 的形式。随后,gfs系统将这个请求发送给gfs主控服务器,因为gfs主控服务器保存了一些管理信息,通过gfs
	  主控服务器可以知道要读的数据在哪台chunk服务器上,同时可以将chunk序号转换为系统内唯一的chunk编号,并将这2个信息回传到gfs客户端。gfs客户端知道了去哪台chunk服务器读取数据后,会和chunk服务器
	  建立联系,并发送给要读取的chunk编号以及读取范围,chunk服务器在接收到请求后,将请求数据发送给gfs客户端,如此就完成了一次数据读取工作。

  7.2.3 GFS主控服务器 
		google 的云存储服务器有一个显著的特点,就是大量采用主从服务器,即单一的主控服务器和众多的存储服务器,主控服务器主要从事系统元数据的存储管理及整个分布式系统的管理,比如负载均衡,数据在
	  存储服务器之间迁移,检测加入新的服务器及失效机器等工作。采取主从结构的好处是:因为整个系统存在一个全局的主控节点,所以管理起来相对简单。相应的缺点是:因为主控服务器是唯一的,很多请求都需要
	  通过主控服务器,所以很容易造成整个系统的瓶颈。另外,正是因为只有唯一的主控节点,所以可能存在单点失效问题。

	  	维持整个系统需要3类元数据:
	  		1.gfs命名空间和chunk命名空间
	  			主要用来对目录文件及chunk的增删改等信息进行记录。
	  		2.从文件到其所属chunk之间的映射关系
	  			因为一个文件会被切割成众多chunk,所以系统需要维护这种映射关系。
	  		3.每个chunk在哪台chunk服务器存储的信息
	  			在gfs系统中,每个文件会被切割成若干个chunk,同时每个chunk会被复制多份,并存储在不同的服务器上。云存储平台必须提供冗余保证数据的安全。

	  	有了以上3类信息,gfs就可以根据文件名找到对应的chunk,同时知道每个chunk存储在哪台chunk服务器上,gfs客户端程序通过gfs主控服务器就可以知道该到哪里去读写相应的数据。
	  	由于管理数据非常重要,所以安全性也必须得到保障。gfs将前2类管理信息(命名空间及文件到chunk映射表)记录在系统日志文件内,并且将这个系统日志分别存储在多台服务器上,这样就避免了
	  信息丢失的问题。对于第3类管理数据,主控制服务器在启动时询问每个chunk服务器,之后靠定时询问来保持最新的信息。
	  	除了存储管理系统元信息之外,主控服务器主要承担一些系统管理工作,比如创建新chunk及其备份数据,不同chunk服务器之间的负载均衡,如果某个chunk不可用,则负责重新生成这个chunk
	  对应的备份数据,以及垃圾回收等工作。
	  	在对数据进行备份和迁移的时候,gfs重点考虑2个因素:一个是chunk数据的可用性,即如果发现chunk数据不可用,哟啊及时重新备份,以避免某个chunk的所有备份都不可用导致数据丢失;另外
	  一个要尽可能减少网络传输压力,因为在不同机器之间传递数据,因为数据量大,所以尽可能减少网络传输压力对于系统整体性能表现很重要。

  7.2.4 系统交互行为 
		本节我们以gfs系统如何完成写操作来介绍系统中各个组成部分的交互行为。出于系统的可用性,gfs系统为每份chunk保留了另外2个备份chunk,而gfs客户端发出写操作请求后,gfs系统必须将这个
	  写操作应用到chunk的所有备份,这样才能维护数据的一致性。为了方便管理,gfs对于多个互相备份的chunk,从中选出一个作为主备份,其他被称为次级备份,由主备份决定次级备份的数据写入顺序。

		gfs客户端首先和主控服务器通信,获知哪些chunk服务器超出了要写入的chunk,包括主备份和两个次级备份的地址数据。之后gfs客户端将要写入的数据推送给3个备份的chunk,备份chunk首先
	  将这些待写入的数据放在缓存中,然后通知gfs客户端是否接受成功,如果所有的备份都接收数据成功,gfs客户端通知主备份可以执行写入操作。主备份自己将缓存的数据写入chunk中,通知次级备份
	  按照指定的顺序写入数据,次级备份写完后答复主备份写入成功,主备份会通知gfs客户端这次写操作完成。


 7.3 Chubby锁服务 
		Chubby是google针对分布式系统资源管理的粗粒度锁服务,一个Chubby实例大约可以负责1w台4核cpu机器之间的对资源的协同管理。这种锁服务主要的功能是让众多客户端程序进行相互之间的同步,
	  并对系统环境或者资源达成认知。
	  	在客户端程序看来,Chubby好像是一个类似于文件系统的目录和文件管理系统,并在此基础上提供针对目录和文件的锁服务,chubby 的文件主要存储一些管理信息或者基础数据,chubby 要求对
	  文件内容一次性全部读完或者写入,这是为了尽可能抑制客户端程序写入大量数据到文件中,因为chubby的目的不是数据存储,而是对资源的同步管理,所以不推荐在文件中保存大量数据。同时,chubby
	  还提供了文件内容更改后的通知机制,客户端可以订阅某个文件,当文件内容发生变化或者一些系统环境发生变化,chubby 会主动通知这些订阅该文件的客户端,使得这种信息变化快速传播。
	  	chubby的理论基础是 Paxos 一致性协议,paxos 是在完全分布环境下,不同客户端能够通过交互通信并投票,对于某个决定达成一致的算法。chubby以此为基础,但是也做了改造,paxos是完全
	  分布的,没有中心管理节点,所以要通过多轮通信和投票来达成最终一致,效率比较低,chubby处于系统效率考虑,增加了一些中心管理策略,在达到同一目标的情况下改善了系统的效率。
	  	在gfs中,chubby被用来选举哪台服务器作为主控服务器。在bigtable中,则有很多功能:选举主控服务器,主控服务器用此服务来发现其他数据存储服务器,客户端程序根据chubby来找到主控服务器及
	  在chubby文件中存储部分管理数据等。
	  	chubby服务由多个chubby单元构成,每个chubby单元一般包含5台服务器,通过选举的方式推举其中一台作为主控服务器,其他4台作为备份服务器,之所以很重要,主要是防止单台服务器宕机后不能提供
	  服务,多台机器可以在某台主控服务器不能提供服务时,由另外一台机器接管。
	  	主控服务器由所有机器选举推出,但是是有任期的,在一段时间内由选举出的服务器充当主控服务器,当任期满后,会再次投票。
	  	所有客户端对chubby的读写请求都由主控服务器来负责,主控服务器遇到写请求后,会更改维护的管理数据,而其他所有备份服务器只是同步管理数据到本地,保持数据和主控服务器一致,当备份机器接收到
	  请求时,会将请求转发给主控服务器,通过这种集中式管理,容易维护数据的一致性。
	  	chubby对外提供了类似于简单文件系统的接口,树形结构的层级目录和文件构成了chubby的管理数据。

 7.4 BigTable 
		BigTable 是一种针对海量结构化或者半结构化数据的存储模型,在google的云存储体系中处于核心地位,起到了承上启下的作用。gfs 是一个分布式海量文件管理系统,对于数据格式没有假定,而BigTable
	  以gfs为基础,建立了数据的结构化解释,对于很多实际应用来说,数据都是有一定格式的,在应用开发者看来,BigTable 建立的数据模型与应用更贴近。MegaStore 存储模型和 Percolator 计算模型都是
	  建立在BigTable 之上的存储和计算模型。

  7.4.1 BigTable 的数据模型 
		所谓数据模型,就是说在应用开发者眼里 BigTable 是怎样的一种结构。BigTable  本质上是一个三维的映射表,其最基础的存储单元是由(行主键,列主键,时间)三维主键(key)所定位的。
		BigTable 内可以保留同一信息随着时间变化的不同版本,这个不同版本由时间维度来进行表达。BigTable 的数据模型粗看很像关系型数据库的关系模型,但是两者有着重要的区别,关系型数据库的列
	  在设计表格之初就已经指定,而BigTable 是可以随时对表格的列进行增删的,而且每行只存储列内容不为空的数据,这被称作模式自由型数据库。
	  	BigTable 是分布式的海量存储系统,成百上千台机器为应用的相关表格提供存取服务。在实际存储表格信息时,会将表格按照行主键进行切割,将一段相邻的行主键组成的若干行数据作为一个存储单元,
	  这被称为一个子表,表格由子表构成,而每个子表的数据交由子表服务器来进行管理。

  7.4.2 BigTable整体结构 
		整体架构主要包含:主控服务器,子表服务器和客户端程序。每个表格将若干个连续的行数据划分为一个子表,这样表格的数据就会被分解为一些子表。子表服务器主要负责子表的数据存储和管理,
	  同时需要响应客户端程序的读写请求,其负责管理的子表以gfs文件的形式存在,bigtable内部将这种文件称之为SSTable,一个子表就是由子表服务器磁盘中存储的诺干个SSTable文件组成,一个
	  子表就是由子表服务器磁盘中存储的若干SSTable文件组成的;主控服务器负责整个系统的管理工作,包括子表的分配,子表服务器的负载均衡,子表服务器失效检测等。客户端程序则是具体应用的
	  接口程序,直接和子表服务器进行通信,来读写某个子表对应的数据。

  7.4.3 BigTable的管理数据 
		对具体应用来说,可以根据需要在bigtable系统中创建自己的表格,每个表格都会被分割成若干子表,并存储在不同的子表服务器中。那么,bigtable 如何知道每个子表存储在哪个子表服务器呢?
	  要知道这一点,需要维护一些特殊的管理数据。
	  	bigtable 利用chubby 系统和一个呗称为元数据表的特殊表格来共同维护系统管理数据。元数据表是bigtable中一个起着特殊作用的表,这个表格的每一行记载了整个bigtable中某个具体子表
	  存储在哪台子表服务器上等管理信息,但是它易于也会被切割成若干子表并存储在不同的子表服务器中。这个表的第1个子表被称为root子表,用来记录元数据表自身除root子表外其他子表的位置,因为
	  元数据表的子表也是分布在不同机器上的,通过root子表的记录就可以找到元数据表中其他子表存储在哪台机器上,即通过root子表就可以找到完整的元数据表。
		
  7.4.4 主控服务器(Master Server) 
		主控服务器在bigtable中专门负责管理工作,比如自动发现是否有新的子表服务器加入,是否有子表服务器因为各种障碍原因不能提供服务,是否有些子表服务器负载过高等情况,并在各种情况下负责
	  子表服务器之间的负载均衡,保证每个子表服务器的负载都是合理的。
	  	chubby在bigtable的正常运转过程中起了很大的作用,不但在其中存储了最基础的管理数据,还提供了粗粒度的加锁服务。

  7.4.5 子表服务器(Tablet Server) 
		子表服务器是bigtable系统中用来存储和管理子表数据的,功能如下:
			1.存储管理子表数据,包括子表存储,子表恢复,子表分裂,子表合并等
			2.响应客户端对子表的读请求
			3.响应客户端对子表的写请求

 7.5 Megastore系统 
		google的绝大多数应用是建立在gfs文件系统和bigtable存储系统之上的,这套系统比较适合大量数据的后台计算,对于实时交互的应用场景来说,并非这套系统的优势应用场景。
	  Megastore 即是google针对这类应用自行研发的海量存储系统。
	  	这类实时应用的要求:数据量太大,需要系统有较高的可扩展性。其次,对互联网应用来说,推出时间早晚其最终的结局可能差异很大,所以存储系统应该支持应用的快速开发和部署。
	  再次,因为是实时与用户交互,所以数据读写要求高速度低延迟的要求。另外,存储系统应用能够保证数据的一致性要求,否则用户写入数据后仍看到的是过时的数据。还有高可用性。
	  	Megastore 的基本思路是:将大规模数据进行细粒度的切割,切割成若干实体群组,在实体群组内提供满足acid语义的强数据一致性服务,但是在实体群组之间提供相对弱的数据一致性
	  保证。利用改造的paxos协议来将数据分布到多个数据中心,这样同时满足了数据请求的高速度低延迟及高可用性,可用性是通过将数据分布到不同数据中心获得的,而数据请求的高速度低延迟
	  则是靠优化后的paxos协议来保证的。

  7.5.1 实体群组切分 
		Megastore 将数据切割成很多细粒度的实体群组,每个实体群组同时分布到不同的数据中心,Megastore利用paxos协议保证实体群组内数据具有acid语义的强一致性,不同实体群组则提供
	  了较弱的数据一致性。同一个数据中心内,Megastore利用bigtable来作为数据存储系统。
	  	实体群组之间采用消息队列的方式完成跨群组的事务操作。实体群组1发出一个消息,将事务追加到消息队列中,实体群组2接收消息队列中自己对应的消息事务并对数做出更改。Megastore 对
	  跨群组事务采用了两阶段提交的方式,这种方式相对耗时,但是由于大部分数据更新操作发生在实体群组内部,所以从系统总体效率来说问题不大。另外,Megastore还提供了实体群组内的局部
	  索引和全局范围的全局索引。

  7.5.2 数据模型 
  7.5.3 数据读写与备份 

 7.6 Map/Reduce云计算模型 
		Map/Reduce 是 google 针对海量信息处理提出的非常著名的云计算模型,目前包括 Hadoop 等众多开源系统都采纳了这一方法,已经成为主流云计算模型。
		Map/Reduce 不仅是一种计算模型,同时也是系统提供的一个计算框架,也就是说,这个计算框架负责将应用程序的计算任务自动分配到众多机器上,并对机器失效等情况进行检测跟踪,应用开发者
	  只需要关注应用任务本身要完成的工作,至于底层的分布式管理工作完全交个这个框架来完成,这样大大加快了应用的开发速度。

  7.6.1 计算模型 
		Map/Reduce 计算模型的基本思路:输入数据是有key/value数值对组成的一组记录,通过map操作,将其转换为新的key1/value1数值对,输入数据的每条记录可能生成多条中间数据记录。Reduce
	  操作则将中间数据里相同key的value值进行累加等处理,生成key1/value2这种汇总的记录形式。对应用开发者来说,只需要写好 Map 和 Reduce 两个操作代码,其他的工作都由Map/Reduce 框架完成。

  7.6.2 整体逻辑流程 
		Map/Reduce 框架首先将应用任务的数据进行切割,把巨大的原始输入数据切割成固定大小的片段,之后将数据分发到不同的机器上,同时对每个数据片段启动一个Mapper任务,来对这个数据片段进行Map操作,
	  数据经过Map转换后转换为新的 key/value 形式,这种中间数据存储在本地机器中。Combiner 任务的目的是对本地的中间数据相同的key的value值先行汇总,主要目的是减少后续将中间数据通过网络传输给
	  Reducer的数据传输量,减少网络负载;分割器将中间结果根据其key值进行哈希取模,将中间结果据此分成R分,这里r份是 Reducer的数目,这么做的目的是让每个 Reducer 只负责汇总其中的一部分数据。
	  多个 Reducer 位于其他机器上,通过网络传输将自己应该负责的各个Mapper产生的中间结果取到本地,并按照中间结果记录的key进行排序,之后就可以对这个数据进行 Reduce 操作,将相同的key的记录value
	  值进行汇总,得到最终计算结果。
	  	Map/Reduce 计算模型本质上是通过分而治之的思想,多机协作来对数据集合进行全局性的统计。在实际应用中,往往是多个Map/Reduce子任务先后串联,前面的Map/Reduce输出结果作为后续的Map/Reduce任务
	  的输入数据,类似于流水线一样共同完成复杂的计算任务。

  7.6.3 应用示例 
 7.7 咖啡因系统——Percolator 
  7.7.1 事务支持 
  7.7.2 观察/通知体系结构 
 7.8 Pregel图计算模型 
 7.9 Dynomo云存储系统 
  7.9.1 数据划分算法(Partitioning Algorithm) 
  7.9.2 数据备份(Replication) 
  7.9.3 数据读写 
  7.9.4 数据版本控制 
 7.10 PNUTS云存储系统 
  7.10.1 PNUTS整体架构 
  7.10.2 存储单元 
  7.10.3 子表控制器与数据路由器 
  7.10.4 雅虎消息代理 
  7.10.5 数据一致性 
 7.11 HayStack存储系统 
  7.11.1 HayStack整体架构 
  7.11.2 目录服务 
  7.11.3 HayStack缓存 
  7.11.4 HayStack存储系统 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值