facebook / facebook/rocksdb

[question] Is efficient merge-or-put semantics possible?

Open
#9,297 4 comments 0 reactions 0 assignees View on GitHub
design discussion up-for-grabs
Dominant language
C++
Stars
32.1k
Forks
6.9k
Avg merge
32m
Merged PRs (30d)
1

Description

Hello.

We're using RocksDB to accumulate persistent state based on information coming from kafka. The value in rocksdb database is a list of of items, and updates to that value come in a form of "upsert" or "delete" operations. We're using `merge` to apply that updates with custom merge operator, but we never `put` anything into that column family. Generally speaking, when we receive an update from kafka, we have no idea if we have have any data for that specific key.

So it turned out that we have only `PartialMergeMulti` invoked for our updates and the obvious problem is an infinitely growing number of "delete" operations in that merge lists. We're going to convert our database to always have `put` operation so that deletes could be actually applied to state instead of being copied all over the place during compactions.

But there is still one performance-related issue that is unclear to me: when we have first update for specific `key` coming from kafka, we need to decide whenever to perform `put` or `merge` operation depending on if we already have that `key` in rocks database. The obvious way to do that is to call `get`, but this is an expensive operation, as for "already-existing" keys it will invoke merges and possible would read a lot of data from disk — this is what we would like to avoid as there are a dozens of thousand updates per second coming from kafka.

Does any cheaper way to implement "put if we know nothing about this key or merge otherwise" semantics exist?

Ideally it would be nice to have some kind of "default value" for column family that could be supplied to FullMerge during compaction/get phase in case the were no put/delete operations for that key ever.

Contributor guide

Open the contributing guide

Research direction

Begin with the merge operator entry points named in the report, especially PartialMergeMulti and FullMerge, and trace how compaction and get handle keys with no put or delete record. Compare that behavior with the requested put-if-unknown-or-merge semantics; done means establishing whether an existing API or a design change can avoid the expensive get and unbounded delete accumulation.

Written by the indexing model from the issue text.

Assessment

Tech stack
kafka
Domain
databases, stream-processing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.