diff --git a/config/config.md b/config/config.md
index 76a54469a3..ab3e1255ee 100644
--- a/config/config.md
+++ b/config/config.md
@@ -103,6 +103,7 @@
| `storage` | -- | -- | The data storage options. |
| `storage.data_home` | String | `./greptimedb_data` | The working home directory. |
| `storage.type` | String | `File` | The storage type used to store the data. - `File`: the data is stored in the local file system. - `S3`: the data is stored in the S3 object storage. - `Gcs`: the data is stored in the Google Cloud Storage. - `Azblob`: the data is stored in the Azure Blob Storage. - `Oss`: the data is stored in the Aliyun OSS. |
+| `storage.enable_read_cache` | Bool | `true` | Whether to enable read cache. If not set, the read cache will be enabled by default when using object storage. |
| `storage.cache_path` | String | Unset | Read cache configuration for object storage such as 'S3' etc, it's configured by default when using object storage. It is recommended to configure it when using object storage for better performance. A local file directory, defaults to `{data_home}`. An empty string means disabling. |
| `storage.cache_capacity` | String | Unset | The local file cache capacity in bytes. If your disk space is sufficient, it is recommended to set it larger. |
| `storage.bucket` | String | Unset | The S3 bucket name. **It's only used when the storage type is `S3`, `Oss` and `Gcs`**. |
@@ -494,6 +495,7 @@
| `storage.data_home` | String | `./greptimedb_data` | The working home directory. |
| `storage.type` | String | `File` | The storage type used to store the data. - `File`: the data is stored in the local file system. - `S3`: the data is stored in the S3 object storage. - `Gcs`: the data is stored in the Google Cloud Storage. - `Azblob`: the data is stored in the Azure Blob Storage. - `Oss`: the data is stored in the Aliyun OSS. |
| `storage.cache_path` | String | Unset | Read cache configuration for object storage such as 'S3' etc, it's configured by default when using object storage. It is recommended to configure it when using object storage for better performance. A local file directory, defaults to `{data_home}`. An empty string means disabling. |
+| `storage.enable_read_cache` | Bool | `true` | Whether to enable read cache. If not set, the read cache will be enabled by default when using object storage. |
| `storage.cache_capacity` | String | Unset | The local file cache capacity in bytes. If your disk space is sufficient, it is recommended to set it larger. |
| `storage.bucket` | String | Unset | The S3 bucket name. **It's only used when the storage type is `S3`, `Oss` and `Gcs`**. |
| `storage.root` | String | Unset | The S3 data will be stored in the specified prefix, for example, `s3://${bucket}/${root}`. **It's only used when the storage type is `S3`, `Oss` and `Azblob`**. |
diff --git a/config/datanode.example.toml b/config/datanode.example.toml
index a7cea4a655..07c52bae9b 100644
--- a/config/datanode.example.toml
+++ b/config/datanode.example.toml
@@ -274,6 +274,9 @@ type = "File"
## @toml2docs:none-default
#+ cache_path = ""
+## Whether to enable read cache. If not set, the read cache will be enabled by default when using object storage.
+#+ enable_read_cache = true
+
## The local file cache capacity in bytes. If your disk space is sufficient, it is recommended to set it larger.
## @toml2docs:none-default
cache_capacity = "5GiB"
diff --git a/config/standalone.example.toml b/config/standalone.example.toml
index efc38ffab1..aef9cd0077 100644
--- a/config/standalone.example.toml
+++ b/config/standalone.example.toml
@@ -361,6 +361,9 @@ data_home = "./greptimedb_data"
## - `Oss`: the data is stored in the Aliyun OSS.
type = "File"
+## Whether to enable read cache. If not set, the read cache will be enabled by default when using object storage.
+#+ enable_read_cache = true
+
## Read cache configuration for object storage such as 'S3' etc, it's configured by default when using object storage. It is recommended to configure it when using object storage for better performance.
## A local file directory, defaults to `{data_home}`. An empty string means disabling.
## @toml2docs:none-default
diff --git a/src/cmd/src/standalone.rs b/src/cmd/src/standalone.rs
index 4863f5e6b6..19195b7567 100644
--- a/src/cmd/src/standalone.rs
+++ b/src/cmd/src/standalone.rs
@@ -247,6 +247,7 @@ impl StartCommand {
.context(error::LoadLayeredConfigSnafu)?;
self.merge_with_cli_options(global_options, &mut opts.component)?;
+ opts.component.sanitize();
Ok(opts)
}
@@ -866,4 +867,22 @@ mod tests {
assert_eq!(options.logging, default_options.logging);
assert_eq!(options.region_engine, default_options.region_engine);
}
+
+ #[test]
+ fn test_cache_config() {
+ let toml_str = r#"
+ [storage]
+ data_home = "test_data_home"
+ type = "S3"
+ [storage.cache_config]
+ enable_read_cache = true
+ "#;
+ let mut opts: StandaloneOptions = toml::from_str(toml_str).unwrap();
+ opts.sanitize();
+ assert!(opts.storage.store.cache_config().unwrap().enable_read_cache);
+ assert_eq!(
+ opts.storage.store.cache_config().unwrap().cache_path,
+ "test_data_home"
+ );
+ }
}
diff --git a/src/datanode/src/config.rs b/src/datanode/src/config.rs
index 06f4d50da3..2f2fcd2697 100644
--- a/src/datanode/src/config.rs
+++ b/src/datanode/src/config.rs
@@ -33,8 +33,6 @@ use servers::grpc::GrpcOptions;
use servers::heartbeat_options::HeartbeatOptions;
use servers::http::HttpOptions;
-pub const DEFAULT_OBJECT_STORE_CACHE_SIZE: ReadableSize = ReadableSize::gb(5);
-
/// Storage engine config
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(default)]
@@ -105,6 +103,14 @@ impl DatanodeOptions {
/// Sanitize the `DatanodeOptions` to ensure the config is valid.
pub fn sanitize(&mut self) {
sanitize_workload_types(&mut self.workload_types);
+
+ if self.storage.is_object_storage() {
+ self.storage
+ .store
+ .cache_config_mut()
+ .unwrap()
+ .sanitize(&self.storage.data_home);
+ }
}
}
@@ -242,4 +248,22 @@ mod tests {
_ => panic!("Expected S3 config"),
}
}
+
+ #[test]
+ fn test_cache_config() {
+ let toml_str = r#"
+ [storage]
+ data_home = "test_data_home"
+ type = "S3"
+ [storage.cache_config]
+ enable_read_cache = true
+ "#;
+ let mut opts: DatanodeOptions = toml::from_str(toml_str).unwrap();
+ opts.sanitize();
+ assert!(opts.storage.store.cache_config().unwrap().enable_read_cache);
+ assert_eq!(
+ opts.storage.store.cache_config().unwrap().cache_path,
+ "test_data_home"
+ );
+ }
}
diff --git a/src/datanode/src/store.rs b/src/datanode/src/store.rs
index ec25f84fd1..8d1c8c99dc 100644
--- a/src/datanode/src/store.rs
+++ b/src/datanode/src/store.rs
@@ -14,21 +14,19 @@
//! object storage utilities
-use std::path::Path;
use std::sync::Arc;
use common_telemetry::info;
+use object_store::config::ObjectStorageCacheConfig;
use object_store::factory::new_raw_object_store;
use object_store::layers::LruCacheLayer;
use object_store::services::Fs;
use object_store::util::{clean_temp_dir, join_dir, with_instrument_layers, with_retry_layers};
-use object_store::{
- ATOMIC_WRITE_DIR, Access, OLD_ATOMIC_WRITE_DIR, ObjectStore, ObjectStoreBuilder,
-};
+use object_store::{ATOMIC_WRITE_DIR, Access, ObjectStore, ObjectStoreBuilder};
use snafu::prelude::*;
-use crate::config::{DEFAULT_OBJECT_STORE_CACHE_SIZE, ObjectStoreConfig};
-use crate::error::{self, CreateDirSnafu, Result};
+use crate::config::ObjectStoreConfig;
+use crate::error::{self, Result};
pub(crate) async fn new_object_store_without_cache(
store: &ObjectStoreConfig,
@@ -58,11 +56,15 @@ pub(crate) async fn new_object_store(
.context(error::ObjectStoreSnafu)?;
// Enable retry layer and cache layer for non-fs object storages
let object_store = if store.is_object_storage() {
- let object_store = if let Some(cache_layer) = build_cache_layer(&store, data_home).await? {
- // Adds cache layer
- object_store.layer(cache_layer)
- } else {
- object_store
+ let object_store = {
+ // It's safe to unwrap here because we already checked above.
+ let cache_config = store.cache_config().unwrap();
+ if let Some(cache_layer) = build_cache_layer(cache_config).await? {
+ // Adds cache layer
+ object_store.layer(cache_layer)
+ } else {
+ object_store
+ }
};
// Adds retry layer
@@ -76,94 +78,33 @@ pub(crate) async fn new_object_store(
}
async fn build_cache_layer(
- store_config: &ObjectStoreConfig,
- data_home: &str,
+ cache_config: &ObjectStorageCacheConfig,
) -> Result