首页 > 代码库 > Note: Bigtable, A Distributed Storage System for Structured Data

Note: Bigtable, A Distributed Storage System for Structured Data

Abstract Introduction::
  Bigtable设计主旨:可扩地扩展到pByte级别和数千台机器的系统, 通用、可伸缩、高性能、高可用性。
  不实现完整的关系数据模型,而是支持一个可以动态控制,允许用户自解释数据属性;
  用户甚至可以指定数据(使用时)是存在内存中还是磁盘中;
  支持row级别的事务处理;不支持跨行事务;;

2. Data model
数据模型:三位数据模型: row、column、timestamp。
row:即数据的key,是任意字符串(其实不一定要求是“字符”),特点有:
   1) 字典序排序;
   2) 排序后一段范围内的key集合称为tablet,它是分布式存储和负载均衡的基本单位(这是个重要概念);
column:格式为family:qualifier,列的分组称为column familly,它是访问控制的基本单位;特点有:
  1)很少变化、数量无限扩展;
  2)同一个family的数据类型应该基本相同,因为同一个family数据会一起压缩并存储;
timestamp:使用版本号的概念更合适,因为它除了是时间外,也可以是任何client指定的64bit数据。
  1)降序排序,确保最新的数据优先读取;
  2)可指定保留几份版本数据,或者指定保留某个时间段内的数据;超出限定的数据将被垃圾回收器(GC)自动回收;

3.API
基本api:1.基于row的读写;2基于row range的迭代读写;

4. Build Blocks
1) Bigtable使用的事GFS分布式文件系统;
2)SSTable的文件格式:提供持久化、有序、不可变的k-v映射存储。支持单独查找一个k-v,以及基于范围的迭代访问k-v。它的内部以64KB(可配置)为单位存储数据,并在文件的最后存放block的索引数据;当SSTable文件打开时,block index会加载到内存中,使用二分查找对应的block。

3)强依赖于高可用的Chobby系统:确保master可用;存储表的位置信息的根结点位置;发现和处理tablet server是否可用;存储schema数据;存储acl;
各组件链接关系(tablet location其实是在server中的某些tablets,但它逻辑上和chobby更紧密些,画一起更简洁明了):

5. Implementation
1)系统组件:
  a)client library:
   直接链接tablet server读写数据;所以master负载应该是很低的;
  b) master server:
    负责分配tablet到tablet server,检测tablet server是否可用;tablet server负载均衡; GC管理;元数据变更处理;
  c) tablet server
    tablet server以cluster的形式组织起来,可以动态的加入或退出cluster;
    每个tablet server管理多个tablet(数千个),负责tablet的读写;当一个tablet过大时,负责分裂成两个;
数据组织的逻辑结构:包含关系:Bittabe cluster->n-table->n-tablet->n-sstable->n-block;

组件间的连接关系:clinter->tablet server;  tablet server –>master;tablet是可以放在任何server上的,这个对应关系保存在tablet Location中,由master负责维护。这样当一台server故障时,tablet可以转移到其他server上。
特别注意:像mysql的复制功能,gibtable只字不提,这是因为备份时GFS天然支持的!

5.1 Tablet location
1)当client要查找一个key对应的值时,它要链接tablet server,然后找到对应的tablet中的数据,所以就需要一个tablet定位过程;这就需要一个tablet location的组件。
2)tablet location组件由分布式的三级B+数结构存储(别忘了tablet就是key字典序中的一个range,所以用B+树是很合适的,key就是天然的索引);这些数据也存在某些独立的tablet中;每个tablet的相关信息组织在约1kB大小的metadata中;用户通过key为索引就可以通过三次查找找到key所在的tablet的位置信息。位置信息中包含tablet所在的tablet server的地址,然后client就可以链接tablet server去读取key-value了。
  a)Chobby-Root tablet:第一级B+树,也就是root节点,限制其不可分裂;当client第一次访问bigtable,它到chubby中读取root节点的tablet server的地址(这里,chobby充当了一个配置服务器的角色);
  b)由于B+树每个节点限制为128M,而每个metadata为1K,所以一个节点能存储128M/1K=2*17个metadata;又由于第一、第二级数节点只存贮对应对应key range的首个metadata,所以三级B+树最多能存储2**17(root级)*(2**17(第二级))=2**34个tablet的地址;而每个tablet平局128数据,所以至少可以存储2**61B数据。(事实上,tablet的大小没有限制,所以理论上可以存储无限大的数据)
  c) 为了减少chobby、root的访问量,这里有一个权衡:当tablet地址变化时,client访问user tablle产生miss,此时client不能直接跳到根节点开始找(否则root负载太大),而是只能从user table往树根一级一级往上找;最坏情况是一直找到chobby,然后有从chobby往叶子节点找,总共需要6次网络访问:user table->other metadata->root->chobby->root->other metadata(此时已经找到tablet的位置,下一步连接user table就不属于定位操作了); 首次访问需要3次网络访问:chobby->root>other metadata;
  d) 位置信息都是缓存在client端的,并且应该很少变化,所以不会成为瓶颈;

5.2 tablet assignment
1) 每个tablet仅分配给一个tablet server,master跟踪已分配和未分配的tablet;所以,master可以控制不同tablet server间的tablet数量,从而根据各种策略做负载均衡;(注意,master跟踪的事tablet而不是tablet server;
2) table server管理是通过chobby实现高可用的。每个server起来后,向chobby的某个固定目录注册一个(文件和一个文件的lock,lock是与session关联);
3)master检测这个目录下文件的变化,如果一个server网络故障或挂了,master获取对应文件的lock,然后删除文件,并把这个故障的server占用的tablet分配给其他的server;由于文件被删除了,即使那个故障的server自己恢复了,也不能直接加入,而是只能初始化自己,重新加入系统中;
4)这里由于机器数量巨大,需要特别注意减少网络负载:lock 和file并存就是为了做到即减少网络负载,又能避免短时间的网络问题导致的系统震荡。lock的作用就是提供了一个缓冲的时间段,例如server网络故障,丢失了lock,但很快自己恢复了,如果此时master还没有发现(没有占用的这个lock),server自己获取到了lock,就恢复了正常服务(像什么也没发生)。
5)如果master丢失了自己的lock,它直接“自杀”;由于client是不依赖master的,所以系统还能工作(少部分功能失效);新的master:
  a)获取到了chobby上的“master lock”;
  b)扫面chobby上的server 列表信息
  c)扫面所有的server,获取已分配的tablet的分配信息;
  d)扫面metadata表,以获取各个server的对应的tablet(这样就能知道对应server上还有那些tablet没有分配了);
然后,master就可以正常工作了;
6)tablet变更有创建、删除、分裂三种方式;前两种方式必须经过master分配;分裂的形式,由server在分裂后,提交到metadata,然后通知master;

5.3 Tablet serving

1)tablet是不可以修改的,只能创建时写入,或删除;
2)memtable:所有的更新,先写redo log成功后,才更新到memtable中;memtable是一个在内存中的缓冲区(不是完整的tablet缓冲);
3)读操作需要合并memtable和磁盘中的old tablet,才能得到最新的内容;
4)恢复tablet时,从metadata中读取tablet以及它的redo point,然后恢复redo log;
5) 写的步骤:
  a)check well-formed;
  b)authorized;
  c)log;
  d)insert into memtable;
  e)memtable达到一定阈值,创建新的memtable,然后直接将老得memtable转换为sstable并写到GFS;注意,不是合并到old tablet;
  f)有两个合并tablet的后台进程负责合并memtable产生的tablet;
6)读的步骤:
  a)check
  b)authorized;
  c)合并memtable+一系列由memtable产生的tablet+old tablet;
7)删除tablet操作只是在metadata中记录一个删除标志,由后台进程负责真正的删除工作;

6 Refinements
1)locality groups
  a)locality group是客户端制定的特定列集合,以保存在一个独立的sstable文件中;这样当要读取这些列时,就不需要读取整个row;
  b)可以指定这些locality gropu对应的内容缓存在内存中;
2)compression
  a)两段压缩,先用长窗口的压缩算法,再用短窗口的压缩算法;
  b)client端自定义压缩算法,
  c)基于block的压缩,这样取一个block就不需要把其他block的内容读出来了;空间换时间;
  d)将内容类型相同的列放到一个locality group中集中存储有利于提高压缩比;
3)caching
  两级缓存机制
  a)第一级是基于面向用户k-v的缓存,对重复访问key最有效;
  b)第二级是面向GFS的block的缓存,对于访问邻近的数据特别有效;
4)bloom filter
  client自定义一个filter,告诉系统一个locality group(sstable)中是否含有对应的row/col对的信息;
::这点说得太简单了,不知道怎么实现的:) 但文中说有时很有效;
5)commit-log
  a)一个tablet server共用一个commit log文件,每条记录包含(table,row,log sequence number)作为key;
  b)恢复时将log文件以64M为单位由master分配给不同server分别排序,负责恢复tablet的server到不同的排序server上取对应tablet的log;
6)speeding up tablet recovery
  当master移动一个tablet到另一台server,步骤:
  a)压缩tablet;
  b)停止服务;
  c)第二次压缩(从第一次压缩点到停止服务点的增量数据;
  d)传输到新server上并解压;
  e)恢复服务;
7)exploiting immutability
由于sstable是不能更新的,可以有效应用copy on write技术;

7 performance evaluation
1) 每行数据量小时,sstable的block应使用较小的值;
2)下面的图够明确了

8.Real application, 有做广告的嫌疑。。

9. Lessons
1)  故障是多种多样的;
2)新特性要按需加,而不是为了使其“更完美”;
3)系统级的监控很重要;
4)设计简单化,使用更成熟可靠的技术;