Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LogServer] Initial implementation for store path #1938

Merged
merged 1 commit into from
Sep 10, 2024
Merged

Conversation

AhmedSoliman
Copy link
Contributor

@AhmedSoliman AhmedSoliman commented Sep 9, 2024

[LogServer] Initial implementation for store path

Note 1: This PR contains many todos an various incomplete bits that will be worked out in later PRs. This is highly experimental code and will be refined in the next iterations but I wanted to avoid accumulating code locally.

Note 2: This enables log-server by default, so it's imperative that this isn't included in v1.1 release.

When looking at this, consider the overall design strategy and don't get hang up on the nits or smaller details as they're likely to change anyway.

What this achieves:

  • Starts log-server by default (role is now enabled by default)
  • Introduces Store/Release network messages for the log-server
  • Implements pipelined Store messages from sequencers, no backfill ability.
  • LogState management
  • Provisional trim infrastructure

Stack created with Sapling. Best reviewed with ReviewStack.

Copy link

github-actions bot commented Sep 9, 2024

Test Results

15 files  ±0  15 suites  ±0   22m 42s ⏱️ +52s
 6 tests ±0   6 ✅ ±0  0 💤 ±0  0 ❌ ±0 
18 runs  ±0  18 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit d0646f3. ± Comparison against base commit 9a48f3d.

♻️ This comment has been updated with latest results.

Copy link
Contributor

@muhamadazmy muhamadazmy left a comment

Choose a reason for hiding this comment

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

Thanks @AhmedSoliman for the PR. This looks good to me but I left couple of questions


use crate::rocksdb_logstore::keys::{KeyPrefixKind, MetadataKey};

pub(super) fn metadata_full_merge(
Copy link
Contributor

Choose a reason for hiding this comment

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

It took me some time to understand what this function do. And I am still not very sure if I got this correctly. Would be nice if you add some doc strings

Copy link
Contributor

Choose a reason for hiding this comment

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

In case it helps, here's a test case from rust-rocksdb that demonstrates the feature (reasonably) concisely: https://github.com/rust-rocksdb/rust-rocksdb/blob/2bbcd68ca229b6ad98e77d87dac9cfe77fc9d961/tests/test_merge_operator.rs#L42-L77

@@ -85,4 +90,259 @@ impl LogStore for RocksDbLogStore {
.map_err(RocksDbLogStoreError::from)?;
Ok(())
}

async fn load_loglet_state(
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see this one being used except in tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's used in LogletStateMap::get_or_load(..) in log-server/src/metadata.rs:76

Note 1: This PR contains many todos an various incomplete bits that will be worked out in later PRs. This is highly experimental code and will be refined in the next iterations but I wanted to avoid accumulating code locally.

Note 2: This enables log-server by default, so it's imperative that this isn't included in v1.1 release.

When looking at this, consider the overall design strategy and don't get hang up on the nits or smaller details as they're likely to change anyway.

What this achieves:
- Starts log-server by default (role is now enabled by default)
- Introduces Store/Release network messages for the log-server
- Implements pipelined Store messages from sequencers, no backfill ability.
- LogState management
- Provisional trim infrastructure
@AhmedSoliman AhmedSoliman merged commit d0646f3 into main Sep 10, 2024
12 checks passed
@AhmedSoliman AhmedSoliman deleted the pr1938 branch September 10, 2024 10:22
Copy link
Contributor

@pcholakov pcholakov left a comment

Choose a reason for hiding this comment

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

Very cool! There's a lot going on here, I could definitely spend longer studying this but timeboxing it for now. All makes sense 👍

// log-store marker
pub(super) const MARKER_KEY: &[u8] = b"storage-marker";

// makes sure that it doesn't go unnoticed if this changed by mistake.
Copy link
Contributor

Choose a reason for hiding this comment

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

🫶


use crate::rocksdb_logstore::keys::{KeyPrefixKind, MetadataKey};

pub(super) fn metadata_full_merge(
Copy link
Contributor

Choose a reason for hiding this comment

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

In case it helps, here's a test case from rust-rocksdb that demonstrates the feature (reasonably) concisely: https://github.com/rust-rocksdb/rust-rocksdb/blob/2bbcd68ca229b6ad98e77d87dac9cfe77fc9d961/tests/test_merge_operator.rs#L42-L77

trace!(key = ?key, "metadata_full_merge");
if key.kind() != KeyPrefixKind::TrimPoint {
error!(key = ?key, "Merge is only supported for trim-points");
return None;
Copy link
Contributor

Choose a reason for hiding this comment

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

I was curious how RocksDB and the Rust layer handles this - merge_cf will return an error like Error { message: "Corruption: Merge operator failed" }. Basically, it's on us to never call merge with an unsupported operand.

.map(LogletOffset::decode)
.unwrap_or(LogletOffset::INVALID);

for op in operands {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice! This is the first time I'm seeing this in the wild :-)

return (Status::OutOfBounds, None);
}

let set_sequncer_in_metadata = if known_sequencer.is_none() {
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: set_seqeuncer_in_metadata

.inner()
.as_raw_db()
.raw_iterator_cf_opt(&data_cf, readopts);
// see to the max key that exists
Copy link
Contributor

Choose a reason for hiding this comment

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

*seek

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants