-
Notifications
You must be signed in to change notification settings - Fork 2.2k
feat(persistence): implement RocksDB provider #20071
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
Conversation
0dabfd4 to
127daf4
Compare
971e7e8 to
c96f5c8
Compare
3787628 to
239301e
Compare
|
RocksDB does not work for cross compile on Windows currently, specially using mingw toolchain. Might be msvc can work (worth to try) I recommend temporarily disabling RocksDB support on Windows and using libmdbx as the fallback. Improving Windows compatibility for RocksDB can be considered future work, wdyt ? error log: https://github.com/paradigmxyz/reth/actions/runs/19861648226/job/56913064304?pr=20071#step:8:21555 related issue: |
mattsse
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a few (early and pedantic) comments
Cargo.toml
Outdated
| toml = "0.8" | ||
|
|
||
| # database | ||
| rocksdb = { version = "0.24", default-features = false, features = ["bindgen-runtime", "lz4", "zstd", "jemalloc"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think enabling these by default is okay
| /// Puts a value into the specified table. | ||
| pub fn put<T: Table>(&self, key: T::Key, value: T::Value) -> ProviderResult<()> { | ||
| self.execute_metered(RocksDBOperation::Put, T::NAME, || { | ||
| let encoded_key = key.encode(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we likely also want put_encoded I think
| } | ||
|
|
||
| /// Puts a value into the specified table. | ||
| pub fn put<T: Table>(&self, key: T::Key, value: T::Value) -> ProviderResult<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like these can be accepted by ref?
| #[derive(Debug)] | ||
| struct RocksDBProviderInner { | ||
| db: DB, | ||
| metrics: Option<Arc<RocksDBMetrics>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume we don't actually need the arc wrapper here?
| /// Converts Reth's [`LogLevel`] to `RocksDB`'s [`rocksdb::LogLevel`]. | ||
| const fn convert_log_level(level: LogLevel) -> rocksdb::LogLevel { | ||
| match level { | ||
| LogLevel::Fatal => rocksdb::LogLevel::Fatal, | ||
| LogLevel::Error => rocksdb::LogLevel::Error, | ||
| LogLevel::Warn => rocksdb::LogLevel::Warn, | ||
| LogLevel::Notice | LogLevel::Verbose => rocksdb::LogLevel::Info, | ||
| LogLevel::Debug | LogLevel::Trace | LogLevel::Extra => rocksdb::LogLevel::Debug, | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we move this to end of file
This makes sense to me |
Rjected
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense to me but left some nits
| impl RocksDBBuilder { | ||
| /// Creates a new builder with optimized default options. | ||
| pub fn new(path: impl AsRef<Path>) -> Self { | ||
| let cache = Cache::new_lru_cache(128 << 20); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would create a default cache size const and use it here
| let mut table_options = rocksdb::BlockBasedOptions::default(); | ||
| table_options.set_block_size(16 * 1024); | ||
| table_options.set_cache_index_and_filter_blocks(true); | ||
| table_options.set_pin_l0_filter_and_index_blocks_in_cache(true); | ||
| // Shared block cache for all column families. | ||
| table_options.set_block_cache(cache); | ||
| // Bloom filter: 10 bits/key = ~1% false positive rate, full filter for better read | ||
| // performance. this setting is good trade off a little bit of memory for better | ||
| // point lookup performance. see https://github.com/facebook/rocksdb/wiki/RocksDB-Bloom-Filter#configuration-basics | ||
| table_options.set_bloom_filter(10.0, false); | ||
| table_options.set_optimize_filters_for_memory(true); | ||
|
|
||
| let mut options = Options::default(); | ||
| options.set_block_based_table_factory(&table_options); | ||
| options.create_if_missing(true); | ||
| options.create_missing_column_families(true); | ||
| options.set_max_background_jobs(6); | ||
| options.set_bytes_per_sync(1_048_576); | ||
|
|
||
| options.set_bottommost_compression_type(rocksdb::DBCompressionType::Zstd); | ||
| options.set_bottommost_zstd_max_train_bytes(0, true); | ||
| options.set_compression_type(rocksdb::DBCompressionType::Lz4); | ||
| options.set_compaction_pri(rocksdb::CompactionPri::MinOverlappingRatio); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'd import DBCompressionType, CompactionPri, BlockBasedOptions at the top of the file
| // Follow recommend tuning guide from RocksDB wiki, see https://github.com/facebook/rocksdb/wiki/Setup-Options-and-Basic-Tuning | ||
| let mut table_options = rocksdb::BlockBasedOptions::default(); | ||
| table_options.set_block_size(16 * 1024); | ||
| table_options.set_cache_index_and_filter_blocks(true); | ||
| table_options.set_pin_l0_filter_and_index_blocks_in_cache(true); | ||
| table_options.set_block_cache(cache); | ||
| // Bloom filter: 10 bits/key = ~1% false positive rate, full filter for better read | ||
| // performance. this setting is good trade off a little bit of memory for better | ||
| // point lookup performance. see https://github.com/facebook/rocksdb/wiki/RocksDB-Bloom-Filter#configuration-basics | ||
| table_options.set_bloom_filter(10.0, false); | ||
| // Optimize filters for memory. | ||
| table_options.set_optimize_filters_for_memory(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we could have a fn default_table_options(cache: &Cache) -> BlockBasedOptions? So that we don't have to repeat this in both default_column_family_options and default_options.
| impl<'a> fmt::Debug for RocksDBBatch<'a> { | ||
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| f.debug_struct("RocksDBBatch") | ||
| .field("provider", &self.provider) | ||
| .field("batch", &"<WriteBatch>") | ||
| .field("length", &self.inner.len()) | ||
| .field("size_in_bytes", &self.inner.size_in_bytes()) | ||
| .finish() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add some comments for what length and size_in_bytes represent w.r.t. the WriteBatch
Hi sir @Rjected, For reference, here are the steps in case we decide to support this on Windows in the future:
|
a2bf641 to
0111d9c
Compare
0111d9c to
412314a
Compare
412314a to
8ffebcb
Compare
| partition: [1, 2] | ||
| total_partitions: [2] | ||
| timeout-minutes: 30 | ||
| timeout-minutes: 60 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: https://github.com/paradigmxyz/reth/actions/runs/19922208464/job/57115796165?pr=20071
I think because we add more dependency so this check is take longer
|
The conditional compilation has been updated, and the changes are ready for review. |
Rjected
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just have one nit otherwise this looks good to me, think we can start implementing providers pretty easily after this
Co-authored-by: Dan Cline <[email protected]>
a09759c to
fbe1b12
Compare
mattsse
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this lgtm, with one pedantic suggestion
pending @Rjected
|
|
||
| /// Some types don't support compression (eg. B256), and we don't want to be copying them to the | ||
| /// allocated buffer when we can just use their reference. | ||
| macro_rules! compress_to_buf_or_ref { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this makes sense
| /// Creates a new `RocksDB` provider. | ||
| pub fn new(path: impl AsRef<Path>) -> ProviderResult<Self> { | ||
| RocksDBBuilder::new(path).build() | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be nice to also have a fn builder convenience fn here, then you don't need to import two types
| table: &'static str, | ||
| f: impl FnOnce(&Self) -> T, | ||
| ) -> T { | ||
| let start = std::time::Instant::now(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this start is redundant if no metrics, so we can make this an optional as well and then simply do a match over both options for recording
11e8a60 to
9fbb6f2
Compare
Rjected
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Resolve #20005
Changes: