Skip to content

KAFKA-14491: [6/N] Support restoring RocksDB versioned store from changelog#13189

Merged
mjsax merged 2 commits into
apache:trunkfrom
vcrfxia:kip-889-versioned-store-restore
Feb 14, 2023
Merged

KAFKA-14491: [6/N] Support restoring RocksDB versioned store from changelog#13189
mjsax merged 2 commits into
apache:trunkfrom
vcrfxia:kip-889-versioned-store-restore

Conversation

@vcrfxia

@vcrfxia vcrfxia commented Feb 2, 2023

Copy link
Copy Markdown
Contributor

(This PR is stacked on #13188. Only the last commit (add restore) needs to be reviewed as part of this PR.)

This PR builds on the new RocksDB-based versioned store implementation (see KIP-889) introduced in #13188 by adding code for restoring from changelog. The changelog topic format is the same as for regular timestamped key-value stores: record keys, values, and timestamps are stored in the Kafka message key, value, and timestamp, respectively. The code for actually writing to this changelog will come in a follow-up PR.

Committer Checklist (excluded from commit message)

  • Verify design and implementation
  • Verify test coverage and CI build status
  • Verify documentation (including upgrade notes)

@mjsax mjsax added streams kip Requires or implements a KIP labels Feb 3, 2023
@vcrfxia
vcrfxia force-pushed the kip-889-versioned-store-restore branch from 0ee4bd9 to 4f38854 Compare February 4, 2023 18:53

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this? How?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, I was hoping to ask you about this myself :)

Currently the code restores an entire batch at a time, by reading the relevant values into memory and then writing at all once at the end. If we were able to detect (or catch) a potential out of memory in this process, we could flush the write buffer partway through the batch to skirt the issue.

From reading online, most sources do not recommend trying to catch OutOfMemoryException even though other sources say that if you have a graceful way to recover (which we do in this case) then it could be fine. Another option is we could set a limit on the amount of memory that we want to be available to the restore write buffer, similar to what's done for the Streams ThreadCache today, and flush whenever we exceed the limit (before we hit an actual OOM). This is probably the better/safer option, but figuring out a good default value will be tricky, and we'd probably also want to expose it as a config for advanced users / users with atypical setups. WDYT?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't try to handle OutOfMemoryException so far, thus, I think it's ok to not start (and if we want to start, make a plan and do it everywhere).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the way that the versioned store implementation stores multiple records (for the same key) together in a single RocksDB "segment" entry, the chance that the new versioned store implementation hits an OOM could be significantly higher than for existing stores -- restoring a single changelog entry could require loading multiple records into memory. How high this memory amplification will be is very much dependent on the specific workload and the value of the segment interval parameter.

In light of this, it feels like there's a case to be made that we should handle OOM for versioned stores, but if you don't feel it's urgent I'm happy to defer.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least no reason to block this PR. \cc @guozhangwang WDYT about this question?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we were aware of the risk of OOM since during restoration we need to potentially buffer some records, and made a decision to live with that during the design phase. So I think it’s still okay to not capture OOM explicitly. Admitting the likelihood would be much larger now.

observedStreamTime = Math.max(observedStreamTime, record.timestamp());
}

final VersionedStoreClient<?> restoreClient = restoreWriteBuffer.getClient();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the generic not typed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The VersionedStoreSegment implementation used by the restore client (WriteBufferSegmentWithDbFallback) is currently private to the write buffer class, since the RocksDBVersionedStore doesn't care what the type is; all the outer class needs are the methods provided by the RocksDBVersionedStoreClient interface itself. So I've left the type out in order to avoid polluting the outer class with extra info it doesn't need.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see -- fair enough (in general, I am a fan on strong typing whenever possible, but it's ok I guess).

/**
* @return client for writing to (and reading from) the write buffer
*/
VersionedStoreClient<?> getClient() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not typed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

@mjsax mjsax left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of nits. (Did not look into testing code yet.)

@vcrfxia

vcrfxia commented Feb 9, 2023

Copy link
Copy Markdown
Contributor Author

Thanks for your review, @mjsax ! Responded to your comments inline and also pushed a commit just now containing the requested changes.

@vcrfxia
vcrfxia force-pushed the kip-889-versioned-store-restore branch from dc708c8 to f9e9181 Compare February 11, 2023 18:56
@mjsax
mjsax merged commit 528a777 into apache:trunk Feb 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kip Requires or implements a KIP streams

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants