BigTable 是搭建在 GFS 之上的结构化数据的存储系统,其作用主要是作为分布式的 NoSQL。

在 GFS 和 Chubby 的基础上在工程中实现了 LSM-Tree。

数据结构

实际上就是 KV

Key:row+column+timestamp value:blob

因为需要支持不同的使用场景,所以将列作为查询的 key 的组成之一,以将较大的数据拆成多个小数据

table = tablets tablet = SSTables SSTable = sorted KVs

LSM-Tree 的主要思想是保存一系列在后台自动合并的多层 SSTables 和基于内存的 MemTable。 SSTables 会生成一些比较稀疏的索引,可以依此进行范围查找, 在查找之前想用 Bloom 过滤器过滤请求,防止不存在的键影响 LSM-Tree 的查找效率。 并且还能有不同的策略来确定 SSTables 被压缩和合并的顺序和时间,LevelDB 用的是 leveled compaction(分层压缩),HBase 用的是 size-tiered compaction(大小分级压缩)。 并且因为磁盘写入是连续的,所以 LSM-Tree 可以支持较高的写入吞吐量;读取方面因为有索引,并且 SSTable 内部是有序的,所以也不会很慢; 而更新和删除不太一样,因为落盘的 SSTable 是不能原地修改的,这个时候就在 MemTable 上追加新版本或者写一个删除标记(tombstone)。这个标记在 minor compaction 时就会跟着 MemTable 一起落盘成 SSTable,只是它此刻只负责遮住旧数据;空间要等到 major compaction 把所有输入合成一个 SSTable、顺手丢掉 tombstone 和被它遮住的旧版本,才真正被回收。

Bigtable 细节

Bigtable 由三个组件组成:

  1. 客户端连接库
  2. one master server
  3. many tablet servers

table servers 可以自动被添加或删除;master 需要分配 tablets 到 tablet servers,保持负载均衡和 gfs 的 GC,并且处理表和列族的创建这类 schema 变更——注意 master 不碰行键,行键的分布是 tablet 分裂自然决定的。

每个 tablet server 管理 10 到 1000 个 tablets。

与大部分 single-master 类似,client 的数据传输不会通过 master,而是与 tablet servers 直接交流。

Bigtable cluster 包含很多 tables,每个 table 包含很多 tablets,每个 tablet 装的是某个行区间(row range)内的所有数据。每个 table 最初只有一个 tablet,当其增长的时候,自动按行键分裂成多个 tablets,每个 tablet 大概 100-200MB。

tablet 的位置信息存在一个类似 B+ 树的三层结构里:Chubby 上的一个文件记录 Root Tablet 的位置,Root Tablet 记录 METADATA 表中所有 tablet 的位置,每个 METADATA tablet 再记录一批 user tablet 的位置。

Root Tablet 本身就是 METADATA 表的第一个 tablet,只是被特殊对待——永不分裂。正是这一条把层高钉死,保证定位路径不会超过三层。

层数怎么数容易含混:论文原文把 Chubby 文件算作第一层,Root Tablet 和 METADATA tablet 是后两层,user tablet 是被指向的数据本身。记住「Root Tablet 不分裂 ⇒ 层高固定」这个因果比背层号有用。