Skip to content

读取 Value 数据的一部分

Roy Guo edited this page Jun 8, 2017 · 7 revisions

English

前言

我们计划通过 RocksDB 做一个 Fuse 的实现,该实现将针对大量的小文件进行优化。

一个文件系统中,一般存有两类数据:元数据(Meta Data) 和 文件数据(File Data).

  • 元数据包含文件类型,文件尺寸,更改时间,创建时间等信息
  • 文件数据指文件的内容,即便是对小文件,文件数据也比源数据要大很多

在 DB 中,key 应该是文件的全路径,value 则是文件元数据(meta data)和文件数据(file data)。元数据(meta data)比文件数据(file data)的访问更加频繁,所以我们需要将元数据和文件数据分开来存储。

比较直接的方法是将元数据和文件数据存储与不同的列簇中,或者通过给文件名增加一个额外的前缀作为新的 key来单独标示元数据,但这两种方法都需要额外的存储空间(主要是针对 key)。

我们考虑通过以下的方式来实现这个功能:

  • 元数据和文件数据连接在一起存储在 DB 的 value
  • 从 API 和 ABI 层面支持对 value 的部分读取

让 API 支持对 value 的部分读取

For performance reasons, struct/class data members are aligned, thus introduce paddings between adjacent data members. With careful design, such paddings can be minimized but may lose code readability. rocksdb prefered code readability, so there are enough padding spaces in classes/structures.

If we add new data members at the padding space, we will not break the ABI(Application Binary Interface). We do so for rocksdb::ReadOptions, with this new feature, users can use new librocksdb.so, and all existing application does not need to recompile, the behavior of API will keep unchanged.

If applications changed new data member of rocksdb::ReadOptions, our new feature will take effect. We add two data members on rocksdb::ReadOptions:

struct ReadOptions {
  bool verify_checksums;
  bool fill_cache;
  uint32_t value_data_offset; // read value data from this offset
  const Snapshot* snapshot;
  const Slice* iterate_upper_bound;
  ReadTier read_tier;
  bool tailing;
  bool managed;
  bool total_order_seek;
  bool prefix_same_as_start;
  bool pin_data;
  bool background_purge_on_iterator_cleanup;
  size_t readahead_size;
  bool ignore_range_deletions;
  uint32_t value_data_length; // read at most such length of value data
  ReadOptions();
  ReadOptions(bool cksum, bool cache);
};

We stripped comments in the code snippet, our added new fields are:

  uint32_t value_data_offset; // read value data from this offset
  uint32_t value_data_length; // read at most such length of value data
// These two fields are initialized in constructor:
  value_data_offset = 0;
  value_data_length = UINT32_MAX;

功能支持

  • iteratorDB::Get 均支持该功能.
  • memtable 支持该功能
  • TerarkZipTable 支持该功能
  • 其他 SSTable 不支持
Clone this wiki locally