Skip to content

Commit 5e51942

Browse files
authored
feat: cf support compress type (#259)
* feat: cf support compress type * fix Signed-off-by: happy-v587 <code4happy@gmail.com> --------- Signed-off-by: happy-v587 <code4happy@gmail.com>
1 parent 3ed48fa commit 5e51942

5 files changed

Lines changed: 107 additions & 3 deletions

File tree

rust-toolchain.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
# limitations under the License.
1717

1818
[toolchain]
19-
channel = "stable"
19+
channel = "nightly-2025-08-20"
2020
components = ["rustfmt", "clippy", "rust-src", "miri", "rust-analyzer"]

src/conf/kiwi.conf

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,4 +266,14 @@ rocksdb-level-compaction-dynamic-level-bytes yes
266266
rocksdb-max-open-files 10000
267267

268268
# Target file size for level-1 and above
269-
rocksdb-target-file-size-base 67108864
269+
rocksdb-target-file-size-base 67108864
270+
271+
# Compression algorithm for RocksDB column families.
272+
# Applies to all column families (default, hash_data_cf, set_data_cf, list_data_cf, zset_data_cf, zset_score_cf).
273+
# Supported values: none, lz4, snappy, zstd, zlib, bz2
274+
# Default: lz4 (good balance of speed and compression ratio)
275+
# - lz4: fast compression/decompression, moderate ratio (recommended for most workloads)
276+
# - snappy: similar to lz4, slightly lower ratio but very fast
277+
# - zstd: best compression ratio, moderate speed (recommended for storage-constrained environments)
278+
# - none: no compression (highest performance, largest disk usage)
279+
rocksdb-compression-type lz4

src/conf/src/config.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,72 @@
1414
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1515
// See the License for the specific language governing permissions and
1616
// limitations under the License.
17+
use rocksdb::DBCompressionType;
18+
use serde::{Deserialize, Serialize};
1719
use snafu::ResultExt;
20+
use std::fmt::Formatter;
1821
use validator::Validate;
1922

2023
use crate::de_func::{parse_bool_from_string, parse_memory, parse_redis_config};
2124
use crate::error::Error;
2225

26+
/// Compression algorithm for RocksDB column families.
27+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
28+
pub enum CompressionType {
29+
None,
30+
Snappy,
31+
Lz4,
32+
Zstd,
33+
Zlib,
34+
Bz2,
35+
}
36+
37+
impl CompressionType {
38+
pub fn to_rocksdb(&self) -> rocksdb::DBCompressionType {
39+
match self {
40+
CompressionType::None => rocksdb::DBCompressionType::None,
41+
CompressionType::Snappy => rocksdb::DBCompressionType::Snappy,
42+
CompressionType::Lz4 => rocksdb::DBCompressionType::Lz4,
43+
CompressionType::Zstd => rocksdb::DBCompressionType::Zstd,
44+
CompressionType::Zlib => rocksdb::DBCompressionType::Zlib,
45+
CompressionType::Bz2 => rocksdb::DBCompressionType::Bz2,
46+
}
47+
}
48+
}
49+
50+
impl std::fmt::Display for CompressionType {
51+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
52+
let s = match self {
53+
CompressionType::None => "none",
54+
CompressionType::Snappy => "snappy",
55+
CompressionType::Lz4 => "lz4",
56+
CompressionType::Zstd => "zstd",
57+
CompressionType::Zlib => "zlib",
58+
CompressionType::Bz2 => "bz2",
59+
};
60+
write!(f, "{}", s)
61+
}
62+
}
63+
64+
impl std::str::FromStr for CompressionType {
65+
type Err = String;
66+
67+
fn from_str(s: &str) -> Result<Self, Self::Err> {
68+
match s.to_lowercase().as_str() {
69+
"none" | "no" => Ok(CompressionType::None),
70+
"snappy" => Ok(CompressionType::Snappy),
71+
"lz4" => Ok(CompressionType::Lz4),
72+
"zstd" => Ok(CompressionType::Zstd),
73+
"zlib" => Ok(CompressionType::Zlib),
74+
"bz2" => Ok(CompressionType::Bz2),
75+
_ => Err(format!(
76+
"unknown compression type '{}', valid values: none, snappy, lz4, zstd, zlib, bz2",
77+
s
78+
)),
79+
}
80+
}
81+
}
82+
2383
const DEFAULT_BINDING: &str = "127.0.0.1";
2484
const DEFAULT_PORT: u16 = 7379; // Redis-compatible port (7xxx variant of 6379)
2585
// config struct define - keeping original config items but using Redis-style format
@@ -46,6 +106,9 @@ pub struct Config {
46106
pub rocksdb_level_compaction_dynamic_level_bytes: bool,
47107
pub rocksdb_max_open_files: i32,
48108
pub rocksdb_target_file_size_base: u64,
109+
/// Compression algorithm applied to all column families.
110+
/// Supported values: none, lz4, snappy, zstd, zlib, bz2. Default: lz4.
111+
pub rocksdb_compression_type: CompressionType,
49112

50113
// Additional fields from original config
51114
pub binding: String,
@@ -94,6 +157,7 @@ impl Default for Config {
94157
rocksdb_level_compaction_dynamic_level_bytes: true,
95158
rocksdb_max_open_files: 10000,
96159
rocksdb_target_file_size_base: 64 << 20, // 64MB
160+
rocksdb_compression_type: CompressionType::Lz4,
97161

98162
db_instance_num: 3,
99163
db_path: "./db".to_string(),
@@ -316,6 +380,15 @@ impl Config {
316380
)),
317381
})?;
318382
}
383+
"rocksdb-compression-type" => {
384+
config.rocksdb_compression_type =
385+
value.parse().map_err(|e| Error::InvalidConfig {
386+
source: serde_ini::de::Error::Custom(format!(
387+
"Invalid rocksdb-compression-type: {}",
388+
e
389+
)),
390+
})?;
391+
}
319392
"raft-node-id" => {
320393
raft_node_id = Some(value.parse().map_err(|e| Error::InvalidConfig {
321394
source: serde_ini::de::Error::Custom(format!(
@@ -395,6 +468,14 @@ impl Config {
395468
options.set_max_open_files(self.rocksdb_max_open_files);
396469
options.set_target_file_size_base(self.rocksdb_target_file_size_base);
397470

471+
// Apply compression to all levels (level 0 and 1 use no compression, levels 2+ use configured type)
472+
let compression = self.rocksdb_compression_type.to_rocksdb();
473+
let mut compressions = vec![DBCompressionType::None; 3];
474+
for _ in 3..self.rocksdb_num_levels {
475+
compressions.push(compression);
476+
}
477+
options.set_compression_per_level(&compressions);
478+
398479
if self.rocksdb_periodic_second > 0 {
399480
options.set_periodic_compaction_seconds(self.rocksdb_periodic_second);
400481
}

src/server/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ fn main() -> std::io::Result<()> {
214214
async fn initialize_storage(config: &Config) -> Result<GlobalStorage, DualRuntimeError> {
215215
info!("Initializing storage...");
216216

217-
let storage_options = Arc::new(StorageOptions::default());
217+
let storage_options = Arc::new(StorageOptions::from_config(config));
218218
let db_path = PathBuf::from(&config.db_path);
219219

220220
let mut storage = Storage::new(1, 0);

src/storage/src/options.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,19 @@ impl StorageOptions {
110110
Self::default()
111111
}
112112

113+
/// Build StorageOptions from a loaded [`conf::config::Config`].
114+
pub fn from_config(config: &conf::config::Config) -> Self {
115+
let rocksdb_opts = config.get_rocksdb_options();
116+
Self {
117+
options: rocksdb_opts,
118+
block_cache_size: config.memory as usize,
119+
small_compaction_threshold: config.small_compaction_threshold,
120+
small_compaction_duration_threshold: config.small_compaction_duration_threshold,
121+
db_instance_num: config.db_instance_num,
122+
..Self::default()
123+
}
124+
}
125+
113126
/// Set block cache size
114127
pub fn set_block_cache_size(&mut self, size: usize) -> &mut Self {
115128
self.block_cache_size = size;

0 commit comments

Comments
 (0)