什么是Bigtable
相比于传统的关系型数据库,bigtable 提供了分布式的非结构化的数据存储,但没有提供sql的语义,所以是数据NoSQL的数据库。
事实上它还是一个分布式的多层map的存储的结构。
Building Blocks
在bigtable 用了其他的很多的Google的组件。
使用Google分布式文件系统(GFS)存储日志和数据文件。
BigTable还依赖一个高可用的、持久化的分布式锁服务组件,叫做Chubby。用于选举 master
一般会运行在共享的集群中,依赖于共享集群的任务调度。
Data model
在bigtable 中,还是提供了类似于表的的数据结构,会有数据的row 和colum, 和一般的不同的是,每一个行的列是可以不同的,列的数量也是可以不一致的。对于数据的查找,需要先找到对应的一行,然后再去找这一行中的某一列。同时数据还会有不同版本的相关的信息。
(row:string, column:string, time:int64) → string
如下面的例子,可以通过
(com.cnn.www,anchor:cnnsi.com,t9)来找到CNN。t9是版本,是根据timestamp来构造的。
SSTable
BigTable数据在内部使用google SSTable文件格式存储。SSTable提供一个从键(key)到值(value)的持久化的、已排序、不可更改的映射(Map),这里的key和value 的都是任意的字节(Byte)串。
对SSTable提供了如下操作:查询与一个指定key值相关的value,或者遍历指定key值范围内的所有键值对。从内部看,SSTable是一连串的数据块(通常每个块的大小是64KB,但是这个大小是可以配置的)。SSTable 会使用索引来加速查找,索引一般存储在数据的末尾位置。如图:
Tablet
Tablet 是包含了一个表中多行,一个tablet事实上是存储在一个机器上的一块信息。
其次,对于一个table来说,可能会分为多个tablet,而tablet又是由不同的sstable组成的,多个tablet可以共享一个sstable
对于tablet 的查找,使用的是类似于文件系统的多级的索引结构:
使用一个三层的、类似于B+树[10]的结构存储tablet的位置信息。
其中第一层是存储在chubby file的中,也就是分布式锁的系统。客户程序库会缓存tablet的位置信息。如果客户程序不知道一个tablet的位置信息,或者发现它缓存的地址信息不正确,那么客户程序就递归移动到tablet位置层次;如果客户端缓存是空的,那么寻址算法需要通过三次网络来回通信寻址,这其中包括了一次Chubby读操作。如果客户端缓存的地址信息过期了,那么寻址算法可能进行多达6次(alex注:其中的三次通信发现缓存过期,另外三次更新缓存数据)网络来回通信,因为过期缓存条目只有在没有查到数据(upon misses)的时候才能发现 (假设元数据tablet没有被频繁的移动)。。
为了减少开销,会于读取多个的tablet 一次
基本的服务
Bigtable集群包括三个主要部分:一个供客户端使用的库,一个主服务器(master server),许多片服务器(tablet server)。
每个tablet一次分配给一个tablet服务器。master服务器记录活跃的tablet服务器、当前tablet到tablet服务器的分配、包括哪些tablet还没有被分配。一个tablet 服务器管理着多个tablet。
客户端的操作都是bypass master的
读写操作
当片服务器收到一个写请求,片服务器首先检查请求是否合法。如果合法,先将写请求提交到日志去,然后将数据写入内存中的memtable。memtable相当于SSTable的缓存,当memtable成长到一定规模会被冻结,Bigtable随之创建一个新的memtable,并且将冻结的memtable转换为SSTable格式写入GFS,这个操作称为minor compaction。
当片服务器收到一个读请求,同样要检查请求是否合法。如果合法,这个读操作会查看所有SSTable文件和memtable的合并视图,因为SSTable和memtable本身都是已排序的,所以合并相当快。