From 252752c4b4c654d7397f96aa391e647a02cee747 Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 5 Aug 2024 15:44:06 -0700 Subject: [PATCH 1/4] feat: supports auto as default value for several numeric configurations in mito2 config --- config/config.md | 30 ++++--- config/datanode.example.toml | 29 ++++-- config/frontend.example.toml | 3 +- config/metasrv.example.toml | 3 +- config/standalone.example.toml | 29 ++++-- src/cmd/src/standalone.rs | 14 ++- src/cmd/tests/load_config_test.rs | 11 --- src/common/config/src/config.rs | 2 +- src/common/config/src/lib.rs | 1 + src/mito2/src/config.rs | 138 ++++++++++------------------- src/mito2/src/engine/basic_test.rs | 2 +- src/mito2/src/sst/index.rs | 4 +- src/mito2/src/worker.rs | 8 +- 13 files changed, 133 insertions(+), 141 deletions(-) diff --git a/config/config.md b/config/config.md index b2a96860ecf7..a2dedc705d2e 100644 --- a/config/config.md +++ b/config/config.md @@ -106,11 +106,12 @@ | `region_engine.mito.compress_manifest` | Bool | `false` | Whether to compress manifest and checkpoint file by gzip (default false). | | `region_engine.mito.max_background_jobs` | Integer | `4` | Max number of running background jobs | | `region_engine.mito.auto_flush_interval` | String | `1h` | Interval to auto flush a region if it has not flushed yet. | -| `region_engine.mito.global_write_buffer_size` | String | `1GB` | Global write buffer size for all regions. If not set, it's default to 1/8 of OS memory with a max limitation of 1GB. | -| `region_engine.mito.global_write_buffer_reject_size` | String | `2GB` | Global write buffer size threshold to reject write requests. If not set, it's default to 2 times of `global_write_buffer_size` | -| `region_engine.mito.sst_meta_cache_size` | String | `128MB` | Cache size for SST metadata. Setting it to 0 to disable the cache.
If not set, it's default to 1/32 of OS memory with a max limitation of 128MB. | -| `region_engine.mito.vector_cache_size` | String | `512MB` | Cache size for vectors and arrow arrays. Setting it to 0 to disable the cache.
If not set, it's default to 1/16 of OS memory with a max limitation of 512MB. | -| `region_engine.mito.page_cache_size` | String | `512MB` | Cache size for pages of SST row groups. Setting it to 0 to disable the cache.
If not set, it's default to 1/16 of OS memory with a max limitation of 512MB. | +| `region_engine.mito.global_write_buffer_size` | String | `auto` | Global write buffer size for all regions. If not set, it's default to 1/8 of OS memory with a max limitation of 1GB.
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `1GB`: fixed size | +| `region_engine.mito.global_write_buffer_reject_size` | String | `auto` | Global write buffer size threshold to reject write requests. If not set, it's default to 2 times of `global_write_buffer_size`
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `2GB`: fixed size | +| `region_engine.mito.sst_meta_cache_size` | String | `auto` | Cache size for SST metadata. Setting it to 0 to disable the cache.
If not set, it's default to 1/32 of OS memory with a max limitation of 128MB.
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `128MB`: fixed size | +| `region_engine.mito.vector_cache_size` | String | `auto` | Cache size for vectors and arrow arrays. Setting it to 0 to disable the cache.
If not set, it's default to 1/16 of OS memory with a max limitation of 512MB.
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `512MB`: fixed size | +| `region_engine.mito.page_cache_size` | String | `auto` | Cache size for pages of SST row groups. Setting it to 0 to disable the cache.
If not set, it's default to 1/8 of OS memory.
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `1GB`: fixed size | +| `region_engine.mito.selector_result_cache_size` | String | `auto` | Cache size for time series selector (e.g. `last_value()`). Setting it to 0 to disable the cache.
If not set, it's default to 1/16 of OS memory with a max limitation of 512MB.
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `512MB`: fixed size | | `region_engine.mito.enable_experimental_write_cache` | Bool | `false` | Whether to enable the experimental write cache. | | `region_engine.mito.experimental_write_cache_path` | String | `""` | File system path for write cache, defaults to `{data_home}/write_cache`. | | `region_engine.mito.experimental_write_cache_size` | String | `512MB` | Capacity for write cache. | @@ -152,7 +153,7 @@ | `export_metrics` | -- | -- | The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.
This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. | | `export_metrics.enable` | Bool | `false` | whether enable export metrics. | | `export_metrics.write_interval` | String | `30s` | The interval of export metrics. | -| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommend to collect metrics generated by itself | +| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommend to collect metrics generated by itself
You must create the database by yourself. | | `export_metrics.self_import.db` | String | `None` | -- | | `export_metrics.remote_write` | -- | -- | -- | | `export_metrics.remote_write.url` | String | `""` | The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=information_schema`. | @@ -237,7 +238,7 @@ | `export_metrics` | -- | -- | The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.
This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. | | `export_metrics.enable` | Bool | `false` | whether enable export metrics. | | `export_metrics.write_interval` | String | `30s` | The interval of export metrics. | -| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommend to collect metrics generated by itself | +| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommend to collect metrics generated by itself
You must create the database by yourself. | | `export_metrics.self_import.db` | String | `None` | -- | | `export_metrics.remote_write` | -- | -- | -- | | `export_metrics.remote_write.url` | String | `""` | The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=information_schema`. | @@ -299,7 +300,7 @@ | `export_metrics` | -- | -- | The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.
This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. | | `export_metrics.enable` | Bool | `false` | whether enable export metrics. | | `export_metrics.write_interval` | String | `30s` | The interval of export metrics. | -| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommend to collect metrics generated by itself | +| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommend to collect metrics generated by itself
You must create the database by yourself. | | `export_metrics.self_import.db` | String | `None` | -- | | `export_metrics.remote_write` | -- | -- | -- | | `export_metrics.remote_write.url` | String | `""` | The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=information_schema`. | @@ -395,11 +396,12 @@ | `region_engine.mito.compress_manifest` | Bool | `false` | Whether to compress manifest and checkpoint file by gzip (default false). | | `region_engine.mito.max_background_jobs` | Integer | `4` | Max number of running background jobs | | `region_engine.mito.auto_flush_interval` | String | `1h` | Interval to auto flush a region if it has not flushed yet. | -| `region_engine.mito.global_write_buffer_size` | String | `1GB` | Global write buffer size for all regions. If not set, it's default to 1/8 of OS memory with a max limitation of 1GB. | -| `region_engine.mito.global_write_buffer_reject_size` | String | `2GB` | Global write buffer size threshold to reject write requests. If not set, it's default to 2 times of `global_write_buffer_size` | -| `region_engine.mito.sst_meta_cache_size` | String | `128MB` | Cache size for SST metadata. Setting it to 0 to disable the cache.
If not set, it's default to 1/32 of OS memory with a max limitation of 128MB. | -| `region_engine.mito.vector_cache_size` | String | `512MB` | Cache size for vectors and arrow arrays. Setting it to 0 to disable the cache.
If not set, it's default to 1/16 of OS memory with a max limitation of 512MB. | -| `region_engine.mito.page_cache_size` | String | `512MB` | Cache size for pages of SST row groups. Setting it to 0 to disable the cache.
If not set, it's default to 1/16 of OS memory with a max limitation of 512MB. | +| `region_engine.mito.global_write_buffer_size` | String | `auto` | Global write buffer size for all regions. If not set, it's default to 1/8 of OS memory with a max limitation of 1GB.
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `1GB`: fixed size | +| `region_engine.mito.global_write_buffer_reject_size` | String | `auto` | Global write buffer size threshold to reject write requests. If not set, it's default to 2 times of `global_write_buffer_size`
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `2GB`: fixed size | +| `region_engine.mito.sst_meta_cache_size` | String | `auto` | Cache size for SST metadata. Setting it to 0 to disable the cache.
If not set, it's default to 1/32 of OS memory with a max limitation of 128MB.
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `128MB`: fixed size | +| `region_engine.mito.vector_cache_size` | String | `auto` | Cache size for vectors and arrow arrays. Setting it to 0 to disable the cache.
If not set, it's default to 1/16 of OS memory with a max limitation of 512MB.
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `512MB`: fixed size | +| `region_engine.mito.page_cache_size` | String | `auto` | Cache size for pages of SST row groups. Setting it to 0 to disable the cache.
If not set, it's default to 1/8 of OS memory.
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `1GB`: fixed size | +| `region_engine.mito.selector_result_cache_size` | String | `auto` | Cache size for time series selector (e.g. `last_value()`). Setting it to 0 to disable the cache.
If not set, it's default to 1/16 of OS memory with a max limitation of 512MB.
- `auto`: automatically determine the value based on the system memory size (default)
- `[size]` e.g. `512MB`: fixed size | | `region_engine.mito.enable_experimental_write_cache` | Bool | `false` | Whether to enable the experimental write cache. | | `region_engine.mito.experimental_write_cache_path` | String | `""` | File system path for write cache, defaults to `{data_home}/write_cache`. | | `region_engine.mito.experimental_write_cache_size` | String | `512MB` | Capacity for write cache. | @@ -439,7 +441,7 @@ | `export_metrics` | -- | -- | The datanode can export its metrics and send to Prometheus compatible service (e.g. send to `greptimedb` itself) from remote-write API.
This is only used for `greptimedb` to export its own metrics internally. It's different from prometheus scrape. | | `export_metrics.enable` | Bool | `false` | whether enable export metrics. | | `export_metrics.write_interval` | String | `30s` | The interval of export metrics. | -| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommend to collect metrics generated by itself | +| `export_metrics.self_import` | -- | -- | For `standalone` mode, `self_import` is recommend to collect metrics generated by itself
You must create the database by yourself. | | `export_metrics.self_import.db` | String | `None` | -- | | `export_metrics.remote_write` | -- | -- | -- | | `export_metrics.remote_write.url` | String | `""` | The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=information_schema`. | diff --git a/config/datanode.example.toml b/config/datanode.example.toml index 97e4fae1d503..6fbd388ac16e 100644 --- a/config/datanode.example.toml +++ b/config/datanode.example.toml @@ -348,22 +348,38 @@ max_background_jobs = 4 auto_flush_interval = "1h" ## Global write buffer size for all regions. If not set, it's default to 1/8 of OS memory with a max limitation of 1GB. -global_write_buffer_size = "1GB" +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `1GB`: fixed size +global_write_buffer_size = "auto" ## Global write buffer size threshold to reject write requests. If not set, it's default to 2 times of `global_write_buffer_size` -global_write_buffer_reject_size = "2GB" +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `2GB`: fixed size +global_write_buffer_reject_size = "auto" ## Cache size for SST metadata. Setting it to 0 to disable the cache. ## If not set, it's default to 1/32 of OS memory with a max limitation of 128MB. -sst_meta_cache_size = "128MB" +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `128MB`: fixed size +sst_meta_cache_size = "auto" ## Cache size for vectors and arrow arrays. Setting it to 0 to disable the cache. ## If not set, it's default to 1/16 of OS memory with a max limitation of 512MB. -vector_cache_size = "512MB" +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `512MB`: fixed size +vector_cache_size = "auto" ## Cache size for pages of SST row groups. Setting it to 0 to disable the cache. +## If not set, it's default to 1/8 of OS memory. +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `1GB`: fixed size +page_cache_size = "auto" + +## Cache size for time series selector (e.g. `last_value()`). Setting it to 0 to disable the cache. ## If not set, it's default to 1/16 of OS memory with a max limitation of 512MB. -page_cache_size = "512MB" +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `512MB`: fixed size +selector_result_cache_size = "auto" ## Whether to enable the experimental write cache. enable_experimental_write_cache = false @@ -516,9 +532,10 @@ enable = false write_interval = "30s" ## For `standalone` mode, `self_import` is recommend to collect metrics generated by itself +## You must create the database by yourself. [export_metrics.self_import] ## +toml2docs:none-default -db = "information_schema" +db = "greptime_metrics" [export_metrics.remote_write] ## The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=information_schema`. diff --git a/config/frontend.example.toml b/config/frontend.example.toml index 8f6a1c859ee4..26ee3d20ca09 100644 --- a/config/frontend.example.toml +++ b/config/frontend.example.toml @@ -200,9 +200,10 @@ enable = false write_interval = "30s" ## For `standalone` mode, `self_import` is recommend to collect metrics generated by itself +## You must create the database by yourself. [export_metrics.self_import] ## +toml2docs:none-default -db = "information_schema" +db = "greptime_metrics" [export_metrics.remote_write] ## The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=information_schema`. diff --git a/config/metasrv.example.toml b/config/metasrv.example.toml index 494e89a1c2f2..faa74505ac35 100644 --- a/config/metasrv.example.toml +++ b/config/metasrv.example.toml @@ -159,9 +159,10 @@ enable = false write_interval = "30s" ## For `standalone` mode, `self_import` is recommend to collect metrics generated by itself +## You must create the database by yourself. [export_metrics.self_import] ## +toml2docs:none-default -db = "information_schema" +db = "greptime_metrics" [export_metrics.remote_write] ## The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=information_schema`. diff --git a/config/standalone.example.toml b/config/standalone.example.toml index 36a46e9ed9d0..4a2d3fbe2566 100644 --- a/config/standalone.example.toml +++ b/config/standalone.example.toml @@ -371,22 +371,38 @@ max_background_jobs = 4 auto_flush_interval = "1h" ## Global write buffer size for all regions. If not set, it's default to 1/8 of OS memory with a max limitation of 1GB. -global_write_buffer_size = "1GB" +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `1GB`: fixed size +global_write_buffer_size = "auto" ## Global write buffer size threshold to reject write requests. If not set, it's default to 2 times of `global_write_buffer_size` -global_write_buffer_reject_size = "2GB" +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `2GB`: fixed size +global_write_buffer_reject_size = "auto" ## Cache size for SST metadata. Setting it to 0 to disable the cache. ## If not set, it's default to 1/32 of OS memory with a max limitation of 128MB. -sst_meta_cache_size = "128MB" +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `128MB`: fixed size +sst_meta_cache_size = "auto" ## Cache size for vectors and arrow arrays. Setting it to 0 to disable the cache. ## If not set, it's default to 1/16 of OS memory with a max limitation of 512MB. -vector_cache_size = "512MB" +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `512MB`: fixed size +vector_cache_size = "auto" ## Cache size for pages of SST row groups. Setting it to 0 to disable the cache. +## If not set, it's default to 1/8 of OS memory. +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `1GB`: fixed size +page_cache_size = "auto" + +## Cache size for time series selector (e.g. `last_value()`). Setting it to 0 to disable the cache. ## If not set, it's default to 1/16 of OS memory with a max limitation of 512MB. -page_cache_size = "512MB" +## - `auto`: automatically determine the value based on the system memory size (default) +## - `[size]` e.g. `512MB`: fixed size +selector_result_cache_size = "auto" ## Whether to enable the experimental write cache. enable_experimental_write_cache = false @@ -545,9 +561,10 @@ enable = false write_interval = "30s" ## For `standalone` mode, `self_import` is recommend to collect metrics generated by itself +## You must create the database by yourself. [export_metrics.self_import] ## +toml2docs:none-default -db = "information_schema" +db = "greptime_metrics" [export_metrics.remote_write] ## The url the metrics send to. The url example can be: `http://127.0.0.1:4000/v1/prometheus/write?db=information_schema`. diff --git a/src/cmd/src/standalone.rs b/src/cmd/src/standalone.rs index efa360713ff9..e7d7841fcff7 100644 --- a/src/cmd/src/standalone.rs +++ b/src/cmd/src/standalone.rs @@ -178,6 +178,13 @@ impl Configurable for StandaloneOptions { } } +#[allow(clippy::from_over_into)] +impl Into for StandaloneOptions { + fn into(self) -> FrontendOptions { + self.frontend_options() + } +} + impl StandaloneOptions { pub fn frontend_options(&self) -> FrontendOptions { let cloned_opts = self.clone(); @@ -510,7 +517,7 @@ impl StartCommand { .build(), ); let wal_options_allocator = Arc::new(WalOptionsAllocator::new( - opts.wal.into(), + opts.wal.clone().into(), kv_backend.clone(), )); let table_meta_allocator = Arc::new(TableMetadataAllocator::new( @@ -561,7 +568,7 @@ impl StartCommand { let (tx, _rx) = broadcast::channel(1); - let servers = Services::new(fe_opts, Arc::new(frontend.clone()), plugins) + let servers = Services::new(opts, Arc::new(frontend.clone()), plugins) .build() .await .context(StartFrontendSnafu)?; @@ -878,6 +885,9 @@ mod tests { let options = StandaloneOptions::load_layered_options(None, "GREPTIMEDB_STANDALONE").unwrap(); let default_options = StandaloneOptions::default(); + let json_str = serde_json::to_string(&default_options).unwrap(); + let default_options: StandaloneOptions = serde_json::from_str(&json_str).unwrap(); + assert_eq!(options.mode, default_options.mode); assert_eq!(options.enable_telemetry, default_options.enable_telemetry); assert_eq!(options.http, default_options.http); diff --git a/src/cmd/tests/load_config_test.rs b/src/cmd/tests/load_config_test.rs index a6a632805951..1959ee3ce0fc 100644 --- a/src/cmd/tests/load_config_test.rs +++ b/src/cmd/tests/load_config_test.rs @@ -16,7 +16,6 @@ use std::time::Duration; use cmd::options::GreptimeOptions; use cmd::standalone::StandaloneOptions; -use common_base::readable_size::ReadableSize; use common_config::Configurable; use common_grpc::channel_manager::{ DEFAULT_MAX_GRPC_RECV_MESSAGE_SIZE, DEFAULT_MAX_GRPC_SEND_MESSAGE_SIZE, @@ -76,11 +75,6 @@ fn test_load_datanode_example_config() { num_workers: 8, auto_flush_interval: Duration::from_secs(3600), scan_parallelism: 0, - global_write_buffer_size: ReadableSize::gb(1), - global_write_buffer_reject_size: ReadableSize::gb(2), - sst_meta_cache_size: ReadableSize::mb(128), - vector_cache_size: ReadableSize::mb(512), - page_cache_size: ReadableSize::mb(512), max_background_jobs: 4, ..Default::default() }), @@ -212,11 +206,6 @@ fn test_load_standalone_example_config() { num_workers: 8, auto_flush_interval: Duration::from_secs(3600), scan_parallelism: 0, - global_write_buffer_size: ReadableSize::gb(1), - global_write_buffer_reject_size: ReadableSize::gb(2), - sst_meta_cache_size: ReadableSize::mb(128), - vector_cache_size: ReadableSize::mb(512), - page_cache_size: ReadableSize::mb(512), max_background_jobs: 4, ..Default::default() }), diff --git a/src/common/config/src/config.rs b/src/common/config/src/config.rs index e0816fbd5671..7c6292075bc3 100644 --- a/src/common/config/src/config.rs +++ b/src/common/config/src/config.rs @@ -88,7 +88,7 @@ pub trait Configurable: Serialize + DeserializeOwned + Default + Sized { /// Serialize the configuration to a TOML string. fn to_toml(&self) -> Result { - toml::to_string(&self).context(TomlFormatSnafu) + toml::to_string(self).context(TomlFormatSnafu) } } diff --git a/src/common/config/src/lib.rs b/src/common/config/src/lib.rs index d6fb9abb4526..484af5c93d09 100644 --- a/src/common/config/src/lib.rs +++ b/src/common/config/src/lib.rs @@ -14,6 +14,7 @@ pub mod config; pub mod error; +pub mod macros; pub mod utils; use common_base::readable_size::ReadableSize; diff --git a/src/mito2/src/config.rs b/src/mito2/src/config.rs index 5f0917688f35..3ce7a669fb08 100644 --- a/src/mito2/src/config.rs +++ b/src/mito2/src/config.rs @@ -19,6 +19,7 @@ use std::path::Path; use std::time::Duration; use common_base::readable_size::ReadableSize; +use common_config::define_mem_size_enum; use common_telemetry::warn; use object_store::util::join_dir; use serde::{Deserialize, Serialize}; @@ -48,6 +49,30 @@ const PAGE_CACHE_SIZE_FACTOR: u64 = 8; /// Use `1/INDEX_CREATE_MEM_THRESHOLD_FACTOR` of OS memory size as mem threshold for creating index const INDEX_CREATE_MEM_THRESHOLD_FACTOR: u64 = 16; +define_mem_size_enum!( + /// Global write buffer size threshold to trigger flush. + GlobalWriteBufferSize, GLOBAL_WRITE_BUFFER_SIZE_FACTOR, ReadableSize::gb(1), Some(ReadableSize::gb(1))); + +define_mem_size_enum!( + /// Global write buffer size threshold to reject write requests. + GlobalWriteBufferRejectSize, GLOBAL_WRITE_BUFFER_SIZE_FACTOR/2, ReadableSize::gb(2), Some(ReadableSize::gb(2))); + +define_mem_size_enum!( + /// Cache size for SST metadata. + SstMetaCacheSize, SST_META_CACHE_SIZE_FACTOR, ReadableSize::mb(128), Some(ReadableSize::mb(128))); + +define_mem_size_enum!( + /// Cache size for vectors and arrow arrays. + VectorCacheSize, MEM_CACHE_SIZE_FACTOR, ReadableSize::mb(512), Some(ReadableSize::mb(512))); + +define_mem_size_enum!( + /// Cache size for time series selector (e.g. `last_value()`). + SelectorResultCacheSize, MEM_CACHE_SIZE_FACTOR, ReadableSize::mb(512), Some(ReadableSize::mb(512))); + +define_mem_size_enum!( + /// Cache size for pages of SST row groups. + PageCacheSize, PAGE_CACHE_SIZE_FACTOR, ReadableSize::mb(512), None::); + /// Configuration for [MitoEngine](crate::engine::MitoEngine). #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] #[serde(default)] @@ -77,19 +102,19 @@ pub struct MitoConfig { #[serde(with = "humantime_serde")] pub auto_flush_interval: Duration, /// Global write buffer size threshold to trigger flush. - pub global_write_buffer_size: ReadableSize, + pub global_write_buffer_size: GlobalWriteBufferSize, /// Global write buffer size threshold to reject write requests. - pub global_write_buffer_reject_size: ReadableSize, + pub global_write_buffer_reject_size: GlobalWriteBufferRejectSize, // Cache configs: /// Cache size for SST metadata. Setting it to 0 to disable the cache. - pub sst_meta_cache_size: ReadableSize, + pub sst_meta_cache_size: SstMetaCacheSize, /// Cache size for vectors and arrow arrays. Setting it to 0 to disable the cache. - pub vector_cache_size: ReadableSize, + pub vector_cache_size: VectorCacheSize, /// Cache size for pages of SST row groups. Setting it to 0 to disable the cache. - pub page_cache_size: ReadableSize, + pub page_cache_size: PageCacheSize, /// Cache size for time series selector (e.g. `last_value()`). Setting it to 0 to disable the cache. - pub selector_result_cache_size: ReadableSize, + pub selector_result_cache_size: SelectorResultCacheSize, /// Whether to enable the experimental write cache. pub enable_experimental_write_cache: bool, /// File system path for write cache, defaults to `{data_home}/write_cache`. @@ -126,7 +151,7 @@ pub struct MitoConfig { impl Default for MitoConfig { fn default() -> Self { - let mut mito_config = MitoConfig { + Self { num_workers: divide_num_cpus(2), worker_channel_size: 128, worker_request_batch_size: 64, @@ -134,12 +159,12 @@ impl Default for MitoConfig { compress_manifest: false, max_background_jobs: DEFAULT_MAX_BG_JOB, auto_flush_interval: Duration::from_secs(30 * 60), - global_write_buffer_size: ReadableSize::gb(1), - global_write_buffer_reject_size: ReadableSize::gb(2), - sst_meta_cache_size: ReadableSize::mb(128), - vector_cache_size: ReadableSize::mb(512), - page_cache_size: ReadableSize::mb(512), - selector_result_cache_size: ReadableSize::mb(512), + global_write_buffer_size: GlobalWriteBufferSize::default(), + global_write_buffer_reject_size: GlobalWriteBufferRejectSize::default(), + sst_meta_cache_size: SstMetaCacheSize::default(), + vector_cache_size: VectorCacheSize::default(), + page_cache_size: PageCacheSize::default(), + selector_result_cache_size: SelectorResultCacheSize::default(), enable_experimental_write_cache: false, experimental_write_cache_path: String::new(), experimental_write_cache_size: ReadableSize::mb(512), @@ -152,14 +177,7 @@ impl Default for MitoConfig { inverted_index: InvertedIndexConfig::default(), fulltext_index: FulltextIndexConfig::default(), memtable: MemtableConfig::default(), - }; - - // Adjust buffer and cache size according to system memory if we can. - if let Some(sys_memory) = common_config::utils::get_sys_total_memory() { - mito_config.adjust_buffer_and_cache_size(sys_memory); } - - mito_config } } @@ -184,8 +202,11 @@ impl MitoConfig { self.max_background_jobs = DEFAULT_MAX_BG_JOB; } - if self.global_write_buffer_reject_size <= self.global_write_buffer_size { - self.global_write_buffer_reject_size = self.global_write_buffer_size * 2; + if self.global_write_buffer_reject_size.as_bytes() + <= self.global_write_buffer_size.as_bytes() + { + self.global_write_buffer_reject_size = + ReadableSize(self.global_write_buffer_size.as_bytes() * 2).into(); warn!( "Sanitize global write buffer reject size to {}", self.global_write_buffer_reject_size @@ -223,31 +244,6 @@ impl MitoConfig { Ok(()) } - fn adjust_buffer_and_cache_size(&mut self, sys_memory: ReadableSize) { - // shouldn't be greater than 1G in default mode. - let global_write_buffer_size = cmp::min( - sys_memory / GLOBAL_WRITE_BUFFER_SIZE_FACTOR, - ReadableSize::gb(1), - ); - // Use 2x of global write buffer size as global write buffer reject size. - let global_write_buffer_reject_size = global_write_buffer_size * 2; - // shouldn't be greater than 128MB in default mode. - let sst_meta_cache_size = cmp::min( - sys_memory / SST_META_CACHE_SIZE_FACTOR, - ReadableSize::mb(128), - ); - // shouldn't be greater than 512MB in default mode. - let mem_cache_size = cmp::min(sys_memory / MEM_CACHE_SIZE_FACTOR, ReadableSize::mb(512)); - let page_cache_size = sys_memory / PAGE_CACHE_SIZE_FACTOR; - - self.global_write_buffer_size = global_write_buffer_size; - self.global_write_buffer_reject_size = global_write_buffer_reject_size; - self.sst_meta_cache_size = sst_meta_cache_size; - self.vector_cache_size = mem_cache_size; - self.page_cache_size = page_cache_size; - self.selector_result_cache_size = mem_cache_size; - } - /// Enable experimental write cache. #[cfg(test)] pub fn enable_write_cache( @@ -351,19 +347,9 @@ impl Mode { } } -/// Memory threshold for performing certain actions. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] -#[serde(rename_all = "snake_case")] -pub enum MemoryThreshold { - /// Automatically determine the threshold based on internal criteria. - #[default] - Auto, - /// Unlimited memory. - Unlimited, - /// Fixed memory threshold. - #[serde(untagged)] - Size(ReadableSize), -} +define_mem_size_enum!( + /// Memory threshold for performing certain actions. + MemoryThreshold, INDEX_CREATE_MEM_THRESHOLD_FACTOR, ReadableSize::mb(64), None::); /// Configuration options for the inverted index. #[serde_as] @@ -426,22 +412,6 @@ impl Default for InvertedIndexConfig { } } -impl InvertedIndexConfig { - pub fn mem_threshold_on_create(&self) -> Option { - match self.mem_threshold_on_create { - MemoryThreshold::Auto => { - if let Some(sys_memory) = common_config::utils::get_sys_total_memory() { - Some((sys_memory / INDEX_CREATE_MEM_THRESHOLD_FACTOR).as_bytes() as usize) - } else { - Some(ReadableSize::mb(64).as_bytes() as usize) - } - } - MemoryThreshold::Unlimited => None, - MemoryThreshold::Size(size) => Some(size.as_bytes() as usize), - } - } -} - /// Configuration options for the full-text index. #[serde_as] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] @@ -471,22 +441,6 @@ impl Default for FulltextIndexConfig { } } -impl FulltextIndexConfig { - pub fn mem_threshold_on_create(&self) -> usize { - match self.mem_threshold_on_create { - MemoryThreshold::Auto => { - if let Some(sys_memory) = common_config::utils::get_sys_total_memory() { - (sys_memory / INDEX_CREATE_MEM_THRESHOLD_FACTOR).as_bytes() as _ - } else { - ReadableSize::mb(64).as_bytes() as _ - } - } - MemoryThreshold::Unlimited => usize::MAX, - MemoryThreshold::Size(size) => size.as_bytes() as _, - } - } -} - /// Divide cpu num by a non-zero `divisor` and returns at least 1. fn divide_num_cpus(divisor: usize) -> usize { debug_assert!(divisor > 0); diff --git a/src/mito2/src/engine/basic_test.rs b/src/mito2/src/engine/basic_test.rs index 9179d8a07411..aa8c5e4bd613 100644 --- a/src/mito2/src/engine/basic_test.rs +++ b/src/mito2/src/engine/basic_test.rs @@ -634,7 +634,7 @@ async fn test_cache_null_primary_key() { let mut env = TestEnv::new(); let engine = env .create_engine(MitoConfig { - vector_cache_size: ReadableSize::mb(32), + vector_cache_size: ReadableSize::mb(32).into(), ..Default::default() }) .await; diff --git a/src/mito2/src/sst/index.rs b/src/mito2/src/sst/index.rs index b73bd0df7ee6..da5fd1c5cefa 100644 --- a/src/mito2/src/sst/index.rs +++ b/src/mito2/src/sst/index.rs @@ -228,7 +228,7 @@ impl<'a> IndexerBuilder<'a> { self.file_id, self.metadata, self.intermediate_manager.clone(), - self.inverted_index_config.mem_threshold_on_create(), + self.inverted_index_config.mem_threshold_on_create.into(), segment_row_count, &self.index_options.inverted_index.ignore_column_ids, ); @@ -250,7 +250,7 @@ impl<'a> IndexerBuilder<'a> { return None; } - let mem_limit = self.fulltext_index_config.mem_threshold_on_create(); + let mem_limit = self.fulltext_index_config.mem_threshold_on_create.into(); let creator = FulltextIndexer::new( &self.metadata.region_id, &self.file_id, diff --git a/src/mito2/src/worker.rs b/src/mito2/src/worker.rs index 82b48bcebb29..594646392e2c 100644 --- a/src/mito2/src/worker.rs +++ b/src/mito2/src/worker.rs @@ -157,10 +157,10 @@ impl WorkerGroup { .await?; let cache_manager = Arc::new( CacheManager::builder() - .sst_meta_cache_size(config.sst_meta_cache_size.as_bytes()) - .vector_cache_size(config.vector_cache_size.as_bytes()) - .page_cache_size(config.page_cache_size.as_bytes()) - .selector_result_cache_size(config.selector_result_cache_size.as_bytes()) + .sst_meta_cache_size(config.sst_meta_cache_size.as_bytes() as _) + .vector_cache_size(config.vector_cache_size.as_bytes() as _) + .page_cache_size(config.page_cache_size.as_bytes() as _) + .selector_result_cache_size(config.selector_result_cache_size.as_bytes() as _) .index_metadata_size(config.inverted_index.metadata_cache_size.as_bytes()) .index_content_size(config.inverted_index.content_cache_size.as_bytes()) .write_cache(write_cache) From 43bb7bc1da8603a2d6ba03fba28d7035950cfc6e Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 5 Aug 2024 16:23:58 -0700 Subject: [PATCH 2/4] fix: config api test failure and wrong configurations --- config/config.md | 16 ++++++++++------ config/datanode.example.toml | 11 +++++++++++ config/frontend.example.toml | 30 +++++++++++++++--------------- src/servers/src/export_metrics.rs | 2 +- tests-integration/tests/http.rs | 3 +-- 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/config/config.md b/config/config.md index a2dedc705d2e..7db249740fcc 100644 --- a/config/config.md +++ b/config/config.md @@ -169,12 +169,6 @@ | Key | Type | Default | Descriptions | | --- | -----| ------- | ----------- | | `default_timezone` | String | `None` | The default timezone of the server. | -| `runtime` | -- | -- | The runtime options. | -| `runtime.global_rt_size` | Integer | `8` | The number of threads to execute the runtime for global read operations. | -| `runtime.compact_rt_size` | Integer | `4` | The number of threads to execute the runtime for global write operations. | -| `heartbeat` | -- | -- | The heartbeat options. | -| `heartbeat.interval` | String | `18s` | Interval for sending heartbeat messages to the metasrv. | -| `heartbeat.retry_interval` | String | `3s` | Interval for retrying to send heartbeat messages to the metasrv. | | `http` | -- | -- | The HTTP server options. | | `http.addr` | String | `127.0.0.1:4000` | The address to bind the HTTP server. | | `http.timeout` | String | `30s` | HTTP request timeout. Set to 0 to disable timeout. | @@ -213,6 +207,12 @@ | `prom_store` | -- | -- | Prometheus remote storage options | | `prom_store.enable` | Bool | `true` | Whether to enable Prometheus remote write and read in HTTP API. | | `prom_store.with_metric_engine` | Bool | `true` | Whether to store the data from Prometheus remote write in metric engine. | +| `runtime` | -- | -- | The runtime options. | +| `runtime.global_rt_size` | Integer | `8` | The number of threads to execute the runtime for global read operations. | +| `runtime.compact_rt_size` | Integer | `4` | The number of threads to execute the runtime for global write operations. | +| `heartbeat` | -- | -- | The heartbeat options. | +| `heartbeat.interval` | String | `18s` | Interval for sending heartbeat messages to the metasrv. | +| `heartbeat.retry_interval` | String | `3s` | Interval for retrying to send heartbeat messages to the metasrv. | | `meta_client` | -- | -- | The metasrv client options. | | `meta_client.metasrv_addrs` | Array | -- | The addresses of the metasrv. | | `meta_client.timeout` | String | `3s` | Operation timeout. | @@ -324,6 +324,10 @@ | `rpc_runtime_size` | Integer | `None` | Deprecated, use `grpc.runtime_size` instead. | | `rpc_max_recv_message_size` | String | `None` | Deprecated, use `grpc.rpc_max_recv_message_size` instead. | | `rpc_max_send_message_size` | String | `None` | Deprecated, use `grpc.rpc_max_send_message_size` instead. | +| `http` | -- | -- | The HTTP server options. | +| `http.addr` | String | `127.0.0.1:4000` | The address to bind the HTTP server. | +| `http.timeout` | String | `30s` | HTTP request timeout. Set to 0 to disable timeout. | +| `http.body_limit` | String | `64MB` | HTTP request body limit.
The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`.
Set to 0 to disable limit. | | `grpc` | -- | -- | The gRPC server options. | | `grpc.addr` | String | `127.0.0.1:3001` | The address to bind the gRPC server. | | `grpc.hostname` | String | `127.0.0.1` | The hostname advertised to the metasrv,
and used for connections from outside the host | diff --git a/config/datanode.example.toml b/config/datanode.example.toml index 6fbd388ac16e..ed10cc0dab1f 100644 --- a/config/datanode.example.toml +++ b/config/datanode.example.toml @@ -39,6 +39,17 @@ rpc_max_recv_message_size = "512MB" ## +toml2docs:none-default rpc_max_send_message_size = "512MB" +## The HTTP server options. +[http] +## The address to bind the HTTP server. +addr = "127.0.0.1:4000" +## HTTP request timeout. Set to 0 to disable timeout. +timeout = "30s" +## HTTP request body limit. +## The following units are supported: `B`, `KB`, `KiB`, `MB`, `MiB`, `GB`, `GiB`, `TB`, `TiB`, `PB`, `PiB`. +## Set to 0 to disable limit. +body_limit = "64MB" + ## The gRPC server options. [grpc] ## The address to bind the gRPC server. diff --git a/config/frontend.example.toml b/config/frontend.example.toml index 26ee3d20ca09..01b5e1af394a 100644 --- a/config/frontend.example.toml +++ b/config/frontend.example.toml @@ -2,21 +2,6 @@ ## +toml2docs:none-default default_timezone = "UTC" -## The runtime options. -[runtime] -## The number of threads to execute the runtime for global read operations. -global_rt_size = 8 -## The number of threads to execute the runtime for global write operations. -compact_rt_size = 4 - -## The heartbeat options. -[heartbeat] -## Interval for sending heartbeat messages to the metasrv. -interval = "18s" - -## Interval for retrying to send heartbeat messages to the metasrv. -retry_interval = "3s" - ## The HTTP server options. [http] ## The address to bind the HTTP server. @@ -128,6 +113,21 @@ enable = true ## Whether to store the data from Prometheus remote write in metric engine. with_metric_engine = true +## The runtime options. +[runtime] +## The number of threads to execute the runtime for global read operations. +global_rt_size = 8 +## The number of threads to execute the runtime for global write operations. +compact_rt_size = 4 + +## The heartbeat options. +[heartbeat] +## Interval for sending heartbeat messages to the metasrv. +interval = "18s" + +## Interval for retrying to send heartbeat messages to the metasrv. +retry_interval = "3s" + ## The metasrv client options. [meta_client] ## The addresses of the metasrv. diff --git a/src/servers/src/export_metrics.rs b/src/servers/src/export_metrics.rs index 36577d99a643..4834940c0e1f 100644 --- a/src/servers/src/export_metrics.rs +++ b/src/servers/src/export_metrics.rs @@ -59,7 +59,7 @@ pub struct SelfImportOption { impl Default for SelfImportOption { fn default() -> Self { Self { - db: "information_schema".to_string(), + db: "greptime_metrics".to_string(), } } } diff --git a/tests-integration/tests/http.rs b/tests-integration/tests/http.rs index db8df835a587..505f2c71859a 100644 --- a/tests-integration/tests/http.rs +++ b/tests-integration/tests/http.rs @@ -850,13 +850,11 @@ write_buffer_size = "8MiB" create_on_flush = "auto" create_on_compaction = "auto" apply_on_query = "auto" -mem_threshold_on_create = "auto" [region_engine.mito.fulltext_index] create_on_flush = "auto" create_on_compaction = "auto" apply_on_query = "auto" -mem_threshold_on_create = "auto" compress = true [region_engine.mito.memtable] @@ -901,6 +899,7 @@ fn drop_lines_with_inconsistent_results(input: String) -> String { "selector_result_cache_size =", "metadata_cache_size =", "content_cache_size =", + "mem_threshold_on_create =", ]; input From 5758a641bc6d531b07244c5a77525ed91c944ff8 Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 5 Aug 2024 16:37:12 -0700 Subject: [PATCH 3/4] fix: forgot macros --- src/common/config/src/macros.rs | 158 ++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 src/common/config/src/macros.rs diff --git a/src/common/config/src/macros.rs b/src/common/config/src/macros.rs new file mode 100644 index 000000000000..1198f7fb69c7 --- /dev/null +++ b/src/common/config/src/macros.rs @@ -0,0 +1,158 @@ +// Copyright 2023 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[macro_export] +macro_rules! define_mem_size_enum { + ($(#[$meta:meta])* + $name:ident, $factor: expr, $default: expr, $max: expr) => { + $(#[$meta])* + #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Default)] + #[serde(rename_all = "snake_case")] + pub enum $name { + /// Automatically determine the threshold based on default value or sys mem + #[default] + Auto, + /// Unlimited size, + Unlimited, + /// Fixed size, + #[serde(untagged)] + Size(common_base::readable_size::ReadableSize), + } + + impl std::fmt::Display for $name { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + $name::Auto => write!(f, "auto"), + $name::Unlimited => write!(f, "unlimited"), + $name::Size(size) => write!(f, "{}", size), + } + } + } + + impl Serialize for $name { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + match self.as_bytes_opt() { + Some(size) => ReadableSize(size).to_string().serialize(serializer), + None => serializer.serialize_str("unlimited"), + } + } + } + + #[allow(dead_code)] + impl $name { + fn default_size() -> u64 { + let size = if let Some(sys_memory) = $crate::utils::get_sys_total_memory() { + (sys_memory / $factor).as_bytes() + } else { + $default.as_bytes() + }; + + if let Some(max) = $max { + std::cmp::min(size, max.as_bytes()) + } else { + size + } + } + + pub fn as_bytes(&self) -> u64 { + match self { + $name::Auto => { + $name::default_size() + } + $name::Unlimited => $max + .map(|s: ReadableSize| s.as_bytes()) + .unwrap_or(u64::MAX), + $name::Size(size) => size.as_bytes(), + } + } + + pub fn as_bytes_opt(&self) -> Option { + match self { + $name::Auto => { + Some($name::default_size()) + } + $name::Unlimited => $max.map(|s: ReadableSize| s.as_bytes()), + $name::Size(size) => Some(size.as_bytes()), + } + } + } + + impl From<$name> for u64 { + fn from(src: $name) -> u64 { + src.as_bytes() + } + } + + impl From<$name> for Option { + fn from(src: $name) -> Option { + src.as_bytes_opt() + } + } + impl From<$name> for usize { + fn from(src: $name) -> usize { + src.as_bytes() as _ + } + } + + impl From for $name { + fn from(size: ReadableSize) -> $name { + $name::Size(size) + } + } + + impl From<$name> for Option { + fn from(src: $name) -> Option { + src.as_bytes_opt().map(|s| s as _) + } + } + + }; +} + +#[cfg(test)] +mod tests { + use common_base::readable_size::ReadableSize; + use serde::{Deserialize, Serialize}; + + #[test] + fn test_define_size_enum() { + define_mem_size_enum!(TestSize, 16, ReadableSize::mb(32), None::); + + let size = TestSize::default(); + assert_eq!(size, TestSize::Auto); + assert_eq!("auto", size.to_string()); + + assert!(size.as_bytes() > 0); + assert!(size.as_bytes_opt().is_some()); + + let size = TestSize::Unlimited; + assert!(size.as_bytes() > 0); + assert!(size.as_bytes_opt().is_none()); + assert_eq!("unlimited", size.to_string()); + + let size = TestSize::Size(ReadableSize::mb(16)); + assert_eq!(size.as_bytes(), ReadableSize::mb(16).as_bytes()); + assert_eq!( + size.as_bytes_opt().unwrap(), + ReadableSize::mb(16).as_bytes() + ); + assert_eq!("16.0MiB", size.to_string()); + + let size: u64 = size.into(); + assert_eq!(size, ReadableSize::mb(16).as_bytes()); + } +} From f55f1de91566c6dcf65a2603546b88ce6e9784ab Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Mon, 5 Aug 2024 16:43:21 -0700 Subject: [PATCH 4/4] chore: revert files --- src/common/config/src/config.rs | 2 +- src/mito2/src/worker.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/common/config/src/config.rs b/src/common/config/src/config.rs index 7c6292075bc3..e0816fbd5671 100644 --- a/src/common/config/src/config.rs +++ b/src/common/config/src/config.rs @@ -88,7 +88,7 @@ pub trait Configurable: Serialize + DeserializeOwned + Default + Sized { /// Serialize the configuration to a TOML string. fn to_toml(&self) -> Result { - toml::to_string(self).context(TomlFormatSnafu) + toml::to_string(&self).context(TomlFormatSnafu) } } diff --git a/src/mito2/src/worker.rs b/src/mito2/src/worker.rs index 594646392e2c..82b48bcebb29 100644 --- a/src/mito2/src/worker.rs +++ b/src/mito2/src/worker.rs @@ -157,10 +157,10 @@ impl WorkerGroup { .await?; let cache_manager = Arc::new( CacheManager::builder() - .sst_meta_cache_size(config.sst_meta_cache_size.as_bytes() as _) - .vector_cache_size(config.vector_cache_size.as_bytes() as _) - .page_cache_size(config.page_cache_size.as_bytes() as _) - .selector_result_cache_size(config.selector_result_cache_size.as_bytes() as _) + .sst_meta_cache_size(config.sst_meta_cache_size.as_bytes()) + .vector_cache_size(config.vector_cache_size.as_bytes()) + .page_cache_size(config.page_cache_size.as_bytes()) + .selector_result_cache_size(config.selector_result_cache_size.as_bytes()) .index_metadata_size(config.inverted_index.metadata_cache_size.as_bytes()) .index_content_size(config.inverted_index.content_cache_size.as_bytes()) .write_cache(write_cache)