目的

动态字典压缩算法在压缩小数据的时候会有问题。在默认的使用下,压缩字典从空白开始,并且通过每次单独的输入数据传递进行构建。因此小的输入会导致一个小的字典,所以无法构建一个好的压缩率。

在RocksDB,每一个机遇块的表(SST文件)里面的块都是独立压缩的。那些不同构建一个合适数据块大小的字典的压缩算法构造的块的大小默认是4KB。字典压缩功能会通过多个块采样,预先设置好字典,这样会在有重复数据的时候提升压缩率。

使用

把rocksdb::CompressionOptions::max_dict_bytes(在include/rocksdb/options.h里面)设置为一个非零的数字,用于声明每个字典文件的最大大小。

rocksdb::CompressionOptions::zstd_max_train_bytes也可被用于设定ZSTD压缩的训练字典的最大Byte数。使用ZSTD的字典训练,可以获得一个比只使用max_dict_bytes更好的压缩率。训练数据会用于生成一个最大大小为max_dict_bytes的字典。

实现

当目标层是最底层的时候,在一个子压缩任务的第一个输出文件会被用于构建字典的采样。每个样本64Byte,并且会统一/随机地从文件中提取。当有间隔的提取样本的时候,我们假设输出文件会达到他的可能的最大大小。否则,某些采样区间会跑到数据文件的区间外面,这样他们就没法被纳入到字典,然后他的大小就会小于max_dict_bytes。

一旦生成结束,这个字典就会在剩下的子压缩流程压缩/解压缩数据块前被加载到压缩库中。字典会被存储在文件的元数据块,这样解压的时候才能找到。

限制

  • 统一随机取样不够优秀
  • 要求每个文件都有这些重复的数据,因为我们是从子压缩流程的第一个文件里面生成字典,并应用于后面的文件。