Bigtable:结构化数据的分布式存储系统(二)

译自Bigtable_A Distributed Storage System for Structured Data算法

做者:Fay Chang, Jeffrey Dean, Sanjay Ghemawat, Wilson C.Hsieh, Deborah A. Wallach Mike Burrows, Tushar Chandra, Andrew Fikes, Robert E.Gruber缓存

5 实现服务器

Bigtable包括三个主要组件,分别是连接到客户端程序的库、Master服务器以及多个Tablet服务器。Bigtable能够动态地增删集群中的Tablet服务器,调整负载均衡。网络

Master服务器主要负责如下工做:为Tablet服务器分配Tablets、检测新加入的或过时失效的Tablet服务器、调整Tablet服务器的负载均衡以及对GFS上的文件进行垃圾收集。此外,Master服务器还负责处理对模式的相关修改操做,例如建立表和列族。数据结构

每一个Tablet服务器都管理一个Tablet集合(每一个服务器通常有几十个至上千个Tablet)。每一个Tablet服务器负责处理其所加载的Tablet的读写操做,同时负责分割过大的Tablet。负载均衡

和不少Single-Master类型的分布式存储系统类似,客户端读取的数据都不通过Master服务器,而是经过直接与Tablet服务器通讯进行读写操做。所以,大多数客户端程序彻底不须要和Master服务器通讯,Master服务器的负载很轻。分布式

一个BigTable集群存储了不少表,每一个表包含了一个Tablet集合,而每一个Tablet包含了某个范围内的行的全部相关数据。在初始状态下,一个表只有一个Tablet。随着数据的增加,表被自动分割成多个Tablet,缺省状况下,每一个Tablet的大小约为100MB到200MB。性能

5.1 Tablet的位置编码

咱们经过相似B+树的三层结构来存储Tablet的位置信息(图4)。3d

图4:Tablet位置层

第一层是存储在Chubby中的文件,文件包含了RootTablet的位置信息。Root Tablet包含特定元数据表中全部Tablet的位置信息。每一个元数据Tablet包含一个用户Tablet集合的位置信息。Root Tablet是元数据表的第一个Tablet。RootTablet永远不会被分割,从而确保Tablet的位置信息存储结构不会超过三层。

在元数据表中,每一个Tablet的位置信息都存放在一个行关键字下面,而这个行关键字是由Tablet所在表的标识符和Tablet的最后一行编码而成的。每一行元数据都存储了大约1KB的内存数据。在一个大小为128MB的元数据Tablet 中,采用这种三层结构的存储模式,能够标识2^34个Tablet的地址(若是每一个Tablet存储128MB数据,则总共能够存储2^61字节数据)。

客户端库会缓存Tablet的位置信息。若是客户端程序没有缓存某个Tablet的位置信息,或发现缓存的地址信息不正确,则能够递归的方式在树状存储结构中查询Tablet的位置信息。若是客户端缓存是空的,则寻址算法须要经过三次网络来回通讯寻址,包括一次Chubby读操做。若是客户端缓存的地址信息过时了,那么寻址算法最多可能须要6次来回网络通讯才能更新数据,由于只有在缓存中查不到数据时才能发现数据过时(假设元数据Tablet不会频繁移动)。Tablet的地址信息是存放在内存中的,所以对地址信息的操做没必要访问GFS文件系统。但咱们通常会预取Tablet地址,从而进一步减小访问开销:每当须要从元数据表中读取一个Tablet的元数据时,都会多读取几个Tablet的元数据。

元数据表中还存储了次要信息,包括每一个Tablet的事件日志(例如,服务器何时开始为该Tablet提供服务)。这些信息有助于排查错误和性能分析。

5.2 Tablet的分配

一个Tablet只能分配给一个Tablet服务器。Master服务器记录了当前活跃的Tablet服务器以及Tablet的分配状况。若是一个Tablet没有被分配且正好有一个Tablet服务器有足够的空闲空间装载该Tablet,Master服务器便会给向Tablet服务器发送装载请求,将Tablet分配给这个服务器。

Bigtable使用Chubby跟踪记录Tablet服务器的状态。Tablet服务器启动时会在Chubby的指定目录下创建一个惟一命名的文件,并获取该文件的独占锁。Master服务器实时监控该目录(服务器目录),及时发现Tablet服务器。若是因为网络中断丢失了Chubby上的独占锁,Tablet服务器便会中止为Tablet提供服务。(Chubby的高效机制可以确保Tablet服务器在不增长网络负担的状况下知道其是否还持有锁)。只要文件还存在,Tablet服务器就会试图从新得到对该文件的独占锁;若是文件不存在了,Tablet服务器就会自行退出,没法继续提供服务。Tablet服务器终止时(好比,集群的管理系统将运行该Tablet服务器的主机从集群中移除)会尝试释放它持有的文件锁,这样Master服务器就能尽快把Tablet分配到其它的Tablet服务器。

Master服务器负责检查Tablet 服务器是否已经中止为其Tablet提供服务;如是,则尽快从新分配其加载的Tablet。Master服务器经过轮询Tablet服务器文件锁的状态来检测Tablet服务器什么时候中止为Tablet提供服务。若是Tablet服务器报告丢失了文件锁或Master服务器最近几回尝试与其通讯都没有获得响应,Master服务器便会尝试获取该Tablet服务器文件的独占锁。若是Master服务器成功获取了独占锁, 则说明Chubby处于正常运行状态,而Tablet服务器要么是宕机了、要么是不能与Chubby通讯了。所以,Master服务器便会删除该Tablet服务器在Chubby上的服务器文件,确保其再也不给Tablet提供服务。Tablet服务器在Chubby上的服务器文件被删除后,Master服务器便会把以前分配给该Tablet服务器的全部的Tablet放入未分配的Tablet集合中。为了确保Bigtable集群在Master服务器与Chubby之间的网络出现故障时仍然可使用,Master服务器在其Chubby会话过时后便会主动退出。但Master服务器的故障不会改变现有Tablet在Tablet服务器上的分配状态。

集群管理系统启动Master服务器以后,Master服务器首先要了解当前Tablet的分配状态,而后才会修改分配状态。Master服务器在启动的时候执行如下步骤:

  1. Master服务器从Chubby获取惟一的Master锁,阻止建立其余Master服务器实例。
  2. Master服务器扫描Chubby的服务器文件目录,获取运行中的服务器。
  3. Master服务器与全部正在运行的Tablet服务器通讯,获取每一个Tablet服务器上Tablet的分配信息。
  4. Master服务器扫描元数据表获取全部的Tablet集合。扫描过程当中,Master服务器发现尚未分配的Tablet时,便会将该Tablet加入未分配的Tablet集合,等待合适的时机进行分配。

在元数据Tablet被分配以前,扫描是没法进行的。所以,在扫描以前(步骤4),若是在第3步的扫描过程当中发现RootTablet尚未分配,Master服务器便会把Root Tablet加入到未分配的Tablet集合,从而确保Root Tablet会被分配。因为RootTablet包含全部元数据Tablet的名称,所以当Master服务器扫描完Root Tablet后,就能获得全部METADATA表的Tablet名称。

只有出现如下事件时,现有Tablet集合才会改变:建立新表或删除旧表、两个Tablet被合并、一个Tablet被分割成两个小的Tablet。Master服务器能够跟踪记录全部这些事件,由于前两类事件都是由它启动的。Tablet分割事件须要特殊处理,由于这类事件是由Tablet服务器启动的。分割操做完成以后,Tablet服务器便会在元数据表中记录新的Tablet信息,完成提交;提交后,Tablet服务器便会通知Master服务器。若是没有把分割操做已提交的信息发送给Master服务器(可能Tablet服务器或Master服务器宕机了),Master服务器在要求Tablet服务器装载已经被分割的子表时便会发现新的Tablet。经过对比元数据表中Tablet信息,Tablet服务器会发现Master服务器要求其装载的Tablet并不完整,进而从新向Master服务器发送通知信息。

5.3 Tablet服务

如图5所示,Tablet的持久化状态信息保存在 GFS 上。更新操做提交到REDO日志中。在这些更新操做中,最近提交的操做存放在排序的缓存中,咱们称之为memtable;较早提交的操做存放在一系列SSTable中。恢复Tablet时,Tablet服务器首先从元数据表中读取其元数据。元数据包括组成Tablet的SSTable列表以及一系列的Redo标点。这些标点指向可能含有该Tablet数据的已提交日志记录。Tablet服务器把SSTable的索引读进内存,使用在Redo标点以后提交的更新重建memtable。

图5:Tablet形式

对Tablet服务器进行写操做时,Tablet服务器首先要检查该操做格式是否正确、操做发起者是否有执行该操做的权限。权限验证的方法是从Chubby文件里读取有写权限的操做者列表(这个文件通常存放在Chubby客户端缓存中)。成功的修改操做会记录在提交日志中。能够经过批量提交的方式提升包含大量小修改操做的应用程序的吞吐量。写操做提交后,写的内容便会插入到memtable里。

对Tablet服务器进行读操做时,Tablet服务器会进行相似的完整性和权限校验。有效的读操做是在由一系列SSTable和memtable合并的视图里执行的。SSTable和memtable是按字母顺序排序的数据结构,所以能够高效生成合并视图。

进行Tablet合并和分割时,正在进行的读写操做可以继续进行。

5.4 压缩

随着写操做的执行,memtable不断变大。当memtable的大小到达阈值时,该memtable 便会会被冻结,而后建立一个新的memtable;被冻结的memtable会被转换成SSTable,写入GFS18。Minor 压缩过程有两个目的:一是缩减Tablet服务器使用的内存;而是在服务器灾难恢复过程当中,减小必须从提交日志里读取的数据量。在压缩过程当中,正在进行的读写操做仍能继续进行。

每一次Minor 压缩都会建立一个新的 SSTable。若是Minor 压缩过程不间断地持续进行下去,读操做可能须要合并来自多个SSTable的更新。为了限制合并文件的数量,咱们会按期在后台执行Merging 压缩过程。Merging 压缩过程读取一些SSTable和memtable的内容,合并成一个新的SSTable。Merging压缩过程完成后,输入的这些SSTable和memtable就能够删除了。

将全部SSTable合并成一个新SSTable的过程叫做Major 压缩。由非Major 压缩产生的SSTable可能含有特殊的删除条目,这些删除条目收录了依然有效的原有SSTable中的已删除数据。而Major 压缩过程生成的SSTable不包含已经删除的信息或数据。Bigtable循环扫描全部的Tablet,并按期对Tablet执行Major 压缩。Major 压缩机制容许Bigtable回收已删除数据占有的资源,而且确保Bigtable能及时清除已删除的数据,这对存放敏感数据的服务来讲很是重要。

参考资料

  1. Fay Chang, Jeffrey Dean, Sanjay Ghemawat, Wilson C.Hsieh, Deborah A. Wallach Mike Burrows, Tushar Chandra, Andrew Fikes and Robert E.Gruber. Bigtable_A Distributed Storage System for Structured Data

  2. Yan Wei. Google Bigtable中文版

相关文章
相关标签/搜索