6.1.7 单机存储
如图6-4所示,Bigtable采用Merge-dump存储引擎。数据写入时需要先写操作日志,成功后应用到内存中的MemTable中,写操作日志是往磁盘中的日志文件追加数据,很好地利用了磁盘设备的特性。当内存中的MemTable达到一定大小,需要将MemTable转储(Dump)到磁盘中生成SSTable文件。由于数据同时存在MemTable和可能多个SSTable中,读取操作需要按从旧到新的时间顺序合并SSTable和内存中的MemTable数据。数据在SSTable中连续存放,因此可以同时满足随机读取和顺序读取两种需求。为了防止磁盘中的SSTable文件过多,需要定时将多个SSTable通过compaction过程合并为一个SSTable,从而减少后续读操作需要读取的文件个数。一般情况下,如果写操作比较少,我们总是能够使得对每一份数据同时只存在一个SSTable和一个MemTable,也就是说,随机读取和顺序读取都只需要访问一次磁盘,这对于线上服务基本上都是成立的。
图 6-4 Bigtable单机存储引擎
插入、删除、更新、增加(Add)等操作在Merge-dump引擎中都看成一回事,除了最早生成的SSTable外,SSTable中记录的只是操作,而不是最终的结果,需要等到读取(随机或者顺序)时才合并得到最终结果。
Bigtable中包含三种Compaction策略:Minor Compaction、Merging Compaction和Major Compaction。其中,Minor Compaction把内存中的MemTable转储到GFS中,Merging Compaction和Major Compaction合并GFS中的多个SSTable文件生成一个更大的SSTable。Minor Compaction主要是为了防止内存占用过多,Merging和Major Compaction则是为了防止读取文件个数过多。Major Compaction与Merging Compaction的区别在于Major Compaction会合并所有的SSTable文件和内存中的MemTable,生成最终结果;而Merging Compaction生成的SSTable文件可能包含一些操作,比如删除、增加等。
数据在SSTable中按照主键有序存储,每个SSTable由若干个大小相近的数据块(Block)组成,每个数据块包含若干行。数据块的大小一般在8~64KB之间,允许用户配置。Tablet Server的缓存包括两种:块缓存(Block Cache)和行缓存(Row Cache)。其中,块缓存的单位为SSTable中的数据块,行缓存的单位为一行记录。随机读取时,首先查找行缓存;如果行缓存不命中,接着再查找块缓存。另外,Bigtable还支持布隆过滤器(Bloom Filter),如果读取的数据行在SSTable中不存在,可以通过布隆过滤器发现,从而避免一次读取GFS文件操作。