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

kvdb: no overlay #313

Merged
merged 20 commits into from
Mar 26, 2020
Merged

kvdb: no overlay #313

merged 20 commits into from
Mar 26, 2020

Conversation

ordian
Copy link
Member

@ordian ordian commented Jan 14, 2020

Fixes #310.

/// written can always be read, but may be present in an in-memory buffer. Values which have
/// been flushed have been moved to backing storage, like a RocksDB instance. There are certain
/// operations which are only guaranteed to operate on flushed data and not buffered,
/// although implementations may differ in this regard.
Copy link
Member Author

Choose a reason for hiding this comment

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

Anyone who relies on this semantics shouldn't have done it on the first place, it is not written anywhere (is it?)

@NikVolf ^^^ :P

Copy link
Contributor

Choose a reason for hiding this comment

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

This is probably about iterators? :)

@NikVolf
Copy link
Contributor

NikVolf commented Jan 14, 2020

I wonder if we can get rid of locks on self.db, but it's a minor issue
probably required for safe closing/upgrading

@ordian
Copy link
Member Author

ordian commented Jan 14, 2020

I wonder if we can get rid of locks on self.db, but it's a minor issue
probably required for safe closing/upgrading

I considered using https://docs.rs/arc-swap/0.4.4/arc_swap/, but read locks are usually cheap enough, also not sure if holding a read lock during iteration to prevent the db from closing is a good idea in the end.

pub fn get_by_prefix(&self, col: u32, prefix: &[u8]) -> Option<Box<[u8]>> {
self.iter_from_prefix(col, prefix).next().map(|(_, v)| v)
}

/// Get database iterator for flushed data.
Copy link
Contributor

Choose a reason for hiding this comment

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

it was probably lying before?
since it was interleaved with actual data?

Copy link
Member Author

@ordian ordian Jan 14, 2020

Choose a reason for hiding this comment

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

partially, I guess
in order to support non-flushed data properly, it would have to take flushing into account (see e.g. get)

@ordian
Copy link
Member Author

ordian commented Jan 14, 2020

I wonder if we can get rid of locks on self.db, but it's a minor issue
probably required for safe closing/upgrading

I considered using https://docs.rs/arc-swap/0.4.4/arc_swap/, but read locks are usually cheap enough, also not sure if holding a read lock during iteration to prevent the db from closing is a good idea in the end.

Let's move this conversation to #314.

@NikVolf
Copy link
Contributor

NikVolf commented Jan 14, 2020

Great stuff!

Copy link
Contributor

@dvdplm dvdplm left a comment

Choose a reason for hiding this comment

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

Code looks great, a significant cleanup. I haven't read the audit yet so I'll be back with a proper review.

kvdb-rocksdb/src/lib.rs Outdated Show resolved Hide resolved
kvdb-rocksdb/src/lib.rs Outdated Show resolved Hide resolved
pub fn get_by_prefix(&self, col: u32, prefix: &[u8]) -> Option<Box<[u8]>> {
self.iter_from_prefix(col, prefix).next().map(|(_, v)| v)
}

/// Get database iterator for flushed data.
/// Get database iterator for the data.
/// Will hold a lock until the iterator is dropped
/// preventing the database from being closed.
Copy link
Contributor

Choose a reason for hiding this comment

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

I've probably asked this before, apologies, but why is it bad to close the DB while some thread is iterating over data? Is the assumption that threads iterating over some data must be allowed to complete?

Copy link
Member Author

Choose a reason for hiding this comment

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

this is a good question, but I consider it to be part of the #314

kvdb-rocksdb/src/lib.rs Outdated Show resolved Hide resolved
kvdb/src/lib.rs Outdated Show resolved Hide resolved
kvdb/src/lib.rs Outdated
@@ -118,25 +109,16 @@ pub trait KeyValueDB: Sync + Send + parity_util_mem::MallocSizeOf {
/// Get a value by key.
fn get(&self, col: u32, key: &[u8]) -> io::Result<Option<DBValue>>;

/// Get a value by partial key. Only works for flushed data.
/// Get a value by partial key. Only works for the data.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Get a value by partial key. Only works for the data.
/// Get the first value matching the given prefix.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is it first or any random value?

Copy link
Member Author

Choose a reason for hiding this comment

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

First in the current implementation and I think we're relying on that, but maybe I'm wrong

@dvdplm dvdplm requested a review from arkpar January 14, 2020 21:02
fn iter<'a>(&'a self, col: u32) -> Box<dyn Iterator<Item = (Box<[u8]>, Box<[u8]>)> + 'a>;

/// Iterate over flushed data for a given column, starting from a given prefix.
/// Iterate over the data for a given column, starting from a given prefix.
fn iter_from_prefix<'a>(
Copy link
Member Author

Choose a reason for hiding this comment

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

maybe we want to finally rename it, but let's do it in a separate PR

@dvdplm
Copy link
Contributor

dvdplm commented Feb 7, 2020

So, any progress on this? I'd love to see some benchmarks on both eth and substrate before moving ahead.

* master:
  Add different mode for malloc_size_of_is_0 macro dealing with generics (#334)
  [parity-crypto] Use upstream secp256k1 (#258)
  Bump parking_lot to 0.10 and minor versions (#332)
  Remove libc completely (#333)
  update changelogs (#329)
  bump parity-util-mem to 0.4.2 (#328)
  remove libc feature from fixed-hash (#317)
  kvdb-rocksdb: release 0.4.2 (#327)
  kvdb-rocksdb: fix iter_from_prefix being slow (#326)
  MallocSizeOf for BTreeSet (#325)
  split off primitives (#323)
  travis: disable kvdb-web tests for chrome (#324)
  Expand const fn coverage (#319)
  uint: make zero const fn (#318)
  README: fix appveyor badge (#316)
@ordian
Copy link
Member Author

ordian commented Feb 7, 2020

I did import benchmarks on eth side #310 (comment), but we currently lack some read-heavy benches like RPC load etc. Would be nice if someone could bench it in substrate as well.

* master:
  prepare rlp-derive release (#344)
  Update/change licenses: MIT/Apache2.0 (#342)
  rlp-derive extracted (#343)
  Format for readme and changelog corrected (#341)
  Parity runtime moved to parity common for publication in crates.io (#271)
  Disable cache if explicit memory budget=0 passed (#339)
  [parity-crypto] prepare 0.5.0 (#336)
  [parity crypto]: remove unused depend `rustc_hex` (#337)
  Update doc comment (#335)
* master:
  kvdb-rocksdb: bump version (#348)
  kvdb-rocksdb: expose RocksDB stats (#347)
  Implement Error for FromDecStrErr (#346)
  Fix clippy lints for rlp-derive (#345)
* master:
  parity-util-mem: prepare release for 0.5.2 (#359)
  travis: test parity-util-mem on android (#358)
  parity-util-mem: update mimalloc feature (#352)
  kvdb: remove parity-bytes dependency (#351)
  parity-util-mem: use malloc for usable_size on android (#355)
  CI: troubleshoot macOS build (#356)
* master:
  Memtest example for Rocksdb (#349)
  Prep for release (#361)
@ordian
Copy link
Member Author

ordian commented Mar 26, 2020

Getting back to this, since substrate doesn't use write_buffered method at all, I don't expect this PR to have any effect on substrate. For eth, write_buffered only used in warp-sync, not regular import, so even if it will slow down warp-sync import by 5%, I think it's fine.

@dvdplm let me know what you think

@dvdplm
Copy link
Contributor

dvdplm commented Mar 26, 2020

For eth, write_buffered only used in warp-sync, not regular import, so even if it will slow down warp-sync import by 5%, I think it's fine.

rg "write_buffered\(" | wc -l shows 19 calls in eth. Many of them look like they are not perf sensitive at all, but commit_block() and feed() are pretty important calls to keep fast. A 5% pessimization is probably not ok there. :/

I really like this PR and I want it to land, but I still want to be convinced we have hard data to support the decision.

@ordian
Copy link
Member Author

ordian commented Mar 26, 2020

See #310 (comment) about eth usage of it.

@dvdplm
Copy link
Contributor

dvdplm commented Mar 26, 2020

See #310 (comment) about eth usage of it.

Oops, apologies. K, fine let's do this then. :)

@dvdplm dvdplm merged commit 7093b7e into master Mar 26, 2020
@dvdplm dvdplm deleted the ao-no-overlay branch March 26, 2020 14:18
ordian added a commit that referenced this pull request Mar 26, 2020
* master:
  kvdb: no overlay (#313)
  Ban duplicates of parity-uil-mem from being linked into the same program (#363)
  Use correct license ID (#362)
  Memtest example for Rocksdb (#349)
  Prep for release (#361)
ordian added a commit that referenced this pull request Apr 22, 2020
* master:
  kvdb-rocksdb: optimize and rename iter_from_prefix  (#365)
  bump parity-util-mem (#376)
  parity-util-mem: fix for windows (#375)
  keccak-hash: fix bench and add one for range (#372)
  [parity-crypto] Release 0.6.1 (#373)
  keccak-hash: bump version to 0.5.1 (#371)
  keccak-hash: add keccak256_range and keccak512_range functions (#370)
  Allow pubkey recovery for all-zero messages (#369)
  Delete by prefix operator in kvdb (#360)
  kvdb: no overlay (#313)
  Ban duplicates of parity-uil-mem from being linked into the same program (#363)
  Use correct license ID (#362)
  Memtest example for Rocksdb (#349)
  Prep for release (#361)
  parity-util-mem: prepare release for 0.5.2 (#359)
  travis: test parity-util-mem on android (#358)
  parity-util-mem: update mimalloc feature (#352)
  kvdb: remove parity-bytes dependency (#351)
  parity-util-mem: use malloc for usable_size on android (#355)
  CI: troubleshoot macOS build (#356)
ordian added a commit that referenced this pull request May 5, 2020
* master: (56 commits)
  primitive-types: add no_std support for serde feature (#385)
  Add Rocksdb Secondary Instance Api (#384)
  kvdb-rocksdb: update rocksdb to 0.14 (#379)
  prepare releases for a few crates (#382)
  uint: fix UB in uint::from_big_endian (#381)
  Fix limit prefix delete case (#368)
  Add arbitrary trait implementation (#378)
  kvdb-rocksdb: optimize and rename iter_from_prefix  (#365)
  bump parity-util-mem (#376)
  parity-util-mem: fix for windows (#375)
  keccak-hash: fix bench and add one for range (#372)
  [parity-crypto] Release 0.6.1 (#373)
  keccak-hash: bump version to 0.5.1 (#371)
  keccak-hash: add keccak256_range and keccak512_range functions (#370)
  Allow pubkey recovery for all-zero messages (#369)
  Delete by prefix operator in kvdb (#360)
  kvdb: no overlay (#313)
  Ban duplicates of parity-uil-mem from being linked into the same program (#363)
  Use correct license ID (#362)
  Memtest example for Rocksdb (#349)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

kvdb-rocksdb with no overlay cache
3 participants