ToplingZipTable Key Value 分离存储

(一)背景ToplingDB 是 topling 开发的 KV 存储引擎,fork 自 RocksDB,进行了很多改造,其中最重要的部件是 ToplingZipTable, 是 BlockBasedTable 的代替品,性能更高而内存占用更低!(二)Key Value 存储方式
ToplingZipTable Key Value 分离存储_第1张图片
KV 相邻存储是最常见的存储方式,其优点是结构简单,逻辑内聚性高,易于理解,便于实现,原版 RocksDB 用的就是这种方案。RocksDB 中的 Blob Key Vaue 分离是一个更上层的概念,对应到上图 K, V 分离存储中,RocksDB 的 Blob 并没有 ID 这个概念,它通过更复杂的方式访问 Blob(分离后的大 Value)。KV 分离存储在实践中往往通过“平行数组”的方式体现出来,例如,Windows PE 文件的 INT 与 IAT,ENT 与 EAT,就是 KV 分离存储的典范:
ToplingZipTable Key Value 分离存储_第2张图片

ToplingZipTable Key Value 分离存储_第3张图片
导入表的主要成分是 INT 和 IAT,INT (Import Name Table) 相当于 Key Index,IAT (Import Address Table) 相当于 Value,导出表 Export Table 的结构也类似。Loader 加载程序时,相当于对导出表和导入表进行 join,把 join 的结果填入 IAT。join 中使用二分搜索(有序的) ENT(Export Name Table),得到函数名在 ENT 数组中的索引(数组下标),用该索引从 Ordinal Table 中得到 ordinal,再用 ordinal 到 EAT 中访问相应的函数地址(填入 IAT),程序运行时则直接访问 IAT 中相应的目标函数。Loader 是操作系统加载可执行文件、动态库的加载器,程序加载完成后才能执行Loader 是操作系统的重要组成部分,其性能非常重要,所以设计者锱铢必较,但凡哪怕有提高那么一丁点性能的机会,他们也绝不放过。那么,为什么这样的 KV 分离设计可以提高性能呢?是因为这样的设计可以提高 CPU Cache 的利用率:二分搜索中只需要访问 ENT(Key),不需要访问其它程序运行中只需要访问 IAT,不需要访问其它如果按照通常的方式将 Key Value 相邻放在一起,就浪费了一倍的 CPU Cache,从而降低性能。此外,这种分离存储的方式还有另一个好处:每个分离的成分都是可选的,例如 ENT 就是可选的(比如 1000 个函数中,只有 10 个有 Name)。(三)ToplingZipTable在 ToplingZipTable 中,我们把这种 KV 分离进行了泛化:COIndex(Key) 与 BlobStore(Value),这个泛化依赖两种必不可少的关键能力:COIndex 可以高效地从 ByteArray Key 映射(搜索)到整数索引(数组下标)BlobStore 可以高效地用整数索引访问 Value(逻辑上相当于一个 ByteArray 数组)这两种关键能力最通用的实现在 topling-zip 中,早已开源,具体到相应的源文件:NestTrieDAWG(基于 NestLoudsTrie)DictZipBlobStore这两种算法都具有(1)很高的压缩率,(2)直接在压缩的数据上执行操作,(3)性能很高。(四)UserKey & InternalKeyRocksDB 通过 (UserKey, Tag) 来实现 MVCC,其中 Tag 分为 (SeqNum, Op) 两部分,
ToplingZipTable Key Value 分离存储_第4张图片
相同的 UserKey 可以有多个不同的 Tag,RocksDB 把 Tag 拼接到 UserKey 后面,构成 InternalKey,从而数据库的逻辑结构就是 Map。这种设计极大地简化了各种处理逻辑,同时也为性能的极致优化埋下了隐患:需要构造 Internal Key(例如 LookupKey,PasedInternalKey ...),来回在 UserKey 与 Internal Key 之间切换遍历相同 UserKey 的所有 {Tag, Value} 需要 ComparatorIterator 反向扫描极有可能引发性能灾难(五)InternalKey 本质是二维结构我们仔细分析下,其实 InternalKey 是个二维结构,从抽象的层次看,Map 其实是摊平后的 Map >,二维结构逻辑上更加复杂一点,但对性能的极致优化非常有利。从一维的角度看,ToplingZipTable 是 InternalKey 和 Value 是平行数组分离存储的,但实际上是这种更加复杂的二维结构,只是第二维很短。在 ToplingDB 中,ToplingZipTable, CSPPMemTable,SingleFastTable, CSPP_WBWI 都是这样的二维结构,并且第二维 List 是 ArrayList。WBWI 是 WriteBatchWidthIndex 的缩写,是 TransactionDB 的重要组件,原版 RocksDB 的 WBWI 是用 SkipList 实现的,跟 SkipListMemTable 类似。在 ToplingZipTable 中,通过 RankSelect 来表达这种二维结构,紧凑且高效地将这种“第二维很短”的 InternalKey 映射为一维整数,然后访问 Value。同时,因为分离存储的每个成分都是“可选的”,在 ToplingZipTable 中,TagArray 就是可选的,而 RankSelect 则更进一步:根据统计特征使用不同的实现。(详情参考 ToplingZipTable: 把 Succinct 进行到底)所以,ToplingDB 之所以性能远高于 RocksDB,不光是底层算法的贡献,还有这种二维结构的贡献。【完】

你可能感兴趣的:(后端mysql数据库redis)