使用RocksDB实现队列服务

许多用户使用RocksDB实现队列服务。在这些服务中,从每个队列中添加具有更高序列ID的新条目,并从最小的序列ID中删除这些条目。

Key Encoding 键编码

您可以简单地将其编码为,其中queue_id编码为固定长度,sequence_id编码为大端点。 在迭代keys时,用户可以创建一个迭代器,并尝试,然后从那里进行迭代。

Old Item Deletion Problem 旧项目删除问题

由于删除了最老的项,所以每个queue_id的开头可能会有大量的”tombstones”。因此,这两个查询可能非常慢:

  1. * Seek(<queue_id, 0>)
  2. * 当您在queue_id的最后一个序列ID中,并尝试调用Next()

为了减轻问题,您可以记住每个queue_id的第一个和最后一个序列ID,而不需要遍历该范围。

作为解决第二个问题的另一种方法,当您在queue_id内迭代时,可以通过允许ReadOptions.iterate_upper_bound 指向 . 我们鼓励您总是设置它,无论您是否看到删除导致的慢速问题。

Checking new sequence IDs of a queue_id 检查queue_id的新序列id

如果用户处理完queue_id的最后一个sequence_id,并继续轮询要创建的新项,只需Seek() 并调用 Next() ,看看下一个键是否仍然是相同的。 确保ReadOptions.iterate_upper_bound 指向 ,以避免项目删除问题的缓慢。

如果想进一步优化这个用例,以避免每次对整个LSM树进行二叉搜索,请考虑使用TailingIteratorr(或在代码的某些部分中调用的ForwardIterator) (https://github.com/facebook/rocksdb/blob/master/include/rocksdb/options.h#L1235-L1241).

Reclaiming space of deleted items faster 更快地回收已删除项的空间

队列服务是CompactOnDeletionCollector的一个很好的用例,它在调度压缩时对范围进行优先排序,删除更多的内容。 将 ImmutableCFOptions::table_properties_collector_factories 设置为这里定义的工厂: https://github.com/facebook/rocksdb/blob/master/include/rocksdb/utilities/table_properties_collectors.h#L23-L27