6.1.6 分裂与合并
随着数据不断写入和删除,某些子表可能太大,某些子表可能太小,需要执行子表分裂与合并操作。顺序分布与哈希分布的区别在于哈希分布往往是静态的,而顺序分布是动态的,需要通过分裂与合并操作动态调整。
Bigtable每个子表的数据分为内存中的MemTable和GFS中的多个SSTable,由于Bigtable中同一个子表只被一台Tablet Server服务,进行分裂时比较简单。Bigtable上执行分裂操作不需要进行实际的数据拷贝工作,只需要将内存中的索引信息分成两份,比如分裂前子表的范围为(起始主键,结束主键],在内存中将索引分成(起始主键,分裂主键]和(分裂主键,结束主键]两个范围。例如,某个子表(1,10]的分裂主键为5,那么,分裂后生成的两个子表的数据范围为:(1,5]和(5,10]。分裂以后两个子表各自写不同的MemTable,等到执行Compaction操作时再根据分裂后的子表范围生成不同的SSTable,无用的数据自然成为垃圾被回收。
分裂操作由Tablet Server发起,需要修改元数据,即用户表的分裂需要修改元数据表,元数据表的分裂需要修改根表。分裂操作需要增加一个子表,相当于在元数据表中增加一行,通过Bigtable的行事务保证原子性。只要修改元数据表成功,分裂操作就算成功。分裂成功后Tablet Server将向Master汇报,如果出现Tablet Server故障,Master可能丢失汇报分裂消息。新的Tablet Server加载这个子表时将发现它已经分裂,并通知Master。
合并操作由Master发起,相比分裂操作要更加复杂。由于待合并的两个子表可能被不同的Tablet Server加载,合并的第一步需要迁移其中一个子表,以使它们在同一个Tablet Server上,接着通知Tablet Server执行子表合并。子表合并操作具体实现时非常麻烦,有兴趣的读者可以自行思考。