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 由三个组件组成:
- 客户端连接库
- one master server
- 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 不分裂 ⇒ 层高固定」这个因果比背层号有用。