2/14 BigTable

BigTable 是Google早期架构的三剑客之一。相比MapReduce解决计算任务调度问题,GFS解决分布式文件系统及其容错问题,BigTable处于中间层为结构化数据存储提供了一个高效且可扩展的解决方案。

数据模型

正如名字所暗示的,BigTable的抽象是数据存在一张大表中,利用Row,Column Family,Column和Timestamp索引数据。Row是读写的基本单位,每次对Row的读写都是原子的。表按照Row key的字典序排序,以至于相似的Row key聚集在一起(局部性,Locality),对一群相似Row key有很高的读性能。

Column Family是访问控制(Access Control)的基本单位,Column Family包含了一系列Column。为了便于压缩,Column Family中的Column数据类型是相同的。约定Column的key是family:qualifier。通常一张表包含有限的几个Column Family,但是Column Family中Column的数量是无限的,所以BigTable中都是稀疏表。

Timestamp与每个Cell绑定在一起。Timestamp的存在允许BigTable为每个Cell存储多个版本的数据。由于BigTable按照字典序排序,最新版本总是最先被读取到。另外,用户可以根据业务需求自定义垃圾回收策略,比如只保留最后n个版本,或者只保留一定时间内的版本。

架构

从物理上,一个BigTable集群包含一个master,一个Chubby,一个GFS,和多个Tablet Server。从逻辑上,一个BigTable集群管理多张Table,每张Table按照排好序的Row key划分为多个Tablet,一个Tablet分为多个在GFS持久化的SSTable,一个位于GFS的commit Log,和一个当前活跃的memtable。值得注意,一张Table中Tablet之间是有序的,memtable和SSTable内部也是有序的,但是SSTable之间是无序的。

master有如下作用:

  1. 把Tablet分配给Tablet Server
  2. membership(错误检测)
  3. 负载均衡
  4. 垃圾回收

Chubby是一个类似Zookeeper的高可用的锁服务。Tablet Server以在Chubby目录下创建一个文件并获取一个互斥锁的方式声明自己的存在。例外,Chubby也保存了权限与根Tablet等信息。

BigTable也用Tablet保存Tablet的位置信息,这种Tablet称为Metadata Tablet。类似用户Tablet,Metadata Tablet也被master指派给Tablet Server管理。BigTable采用类似B树的三层结构组织Metadata Tablet和用户Tablet,由Chubby的文件保存树根的位置。

每张Tablet都一个活跃的memtable位于Tablet Server的内存中,对Tablet的写操作都先写入commit log,然后写入memtable。位于内存的memtable可以很方便快速的维护row key的顺序。

用户把一系列相关的Column Family指定为一个Locality Group。Locality Group物理的以SSTable文件的形式持久化。文件系统把文件分成多个Block存储。SSTable把所有Block的index和row key范围存在文件末尾。从SSTable读取某个row key时,先读取末尾的indices,再利用二分查找就可以确定目标Block的index。如此只需要两次磁盘读操作就可以在SSTable中索引到一个row key。除了block indices,tablet利用bloomfilter快速判断row key是否位于该SSTable中。

读写操作

客户端一般缓存了Tablet Server的位置。当缓存失中,client递归的回到Metadata Tablet甚至更上一层最新信息。但是大多数情况,client直接与Tablet Server沟通,减轻了master的压力。

假设client已经得知Tablet Server的位置。如果client向Tablet Server请求读操作,Tablet Server先后通过Bloomfilter和block indices检测,目标可能位于memtable,可能位于SSTable,Tablet Server可以直接读出需要的数据。

如果执行一个写操作,操作先写入commit log中,然后以维持排序的方式写入memtable。当memtable超过一定大小,memtable以SSTable的形式持久化到GFS,这个过程称为minor compaction。

一旦持久化,SSTable中的记录是不可更改的。这一点避免了对同步机制的需要。随着系统运行,过期数据积累越来越多。所以定期需要清理过期数据,这个过程由master控制,称为major compaction。

错误检测与恢复

Tablet Server通过在Chubby获取互斥锁的方式声明自身的存在,终止时释放该锁。所以master也通过获取锁的情况实现错误检测。错误检测的过程如下:

  1. master周期性的询问Tablet Server锁的状态
  2. 如果锁丢失或连接断开,说明发生错误,可能是Tablet Server不可用,但也可能是Chubby不可用
  3. master尝试向Chubby获取锁
  4. 如果成功获取锁,说明Tablet Server错误,则删除该锁文件,并重新分配它管理的Tablets
  5. 如果Chubby错误,master自杀

master的恢复过程如下:

  1. 在Chubby获取全局唯一的master锁,避免出现两个master
  2. master扫描Chubby目录所有Tablet Server的文件
  3. master向发现的Tablet Server询问它们管理的Tablets
  4. master扫描Metadata Tablet发现未分配的Tablets

Tablet Server在网络恢复时会尝试重新获得自己的锁,如果文件已经被删除,则自杀。

限制

BigTable在CAP中无法保证可用性。发生裂脑错误时只能保留与Chubby在同一分区的服务器。此外,BigTable只有行的原子操作,不支持跨行的事务操作。