Rust日志记录库value-log的使用,value-log为高效日志存储和检索提供轻量级解决方案

Rust日志记录库value-log的使用,value-log为高效日志存储和检索提供轻量级解决方案

value-log logo

value-log是一个通用的键值分离存储实现,灵感来源于RocksDB的BlobDB和Titan,使用安全稳定的Rust实现。

主要特性

  • 线程安全API
  • 100%安全且稳定的Rust实现
  • 支持通用的KV索引结构(LSM-tree等)
  • 可选的对每个blob进行通用压缩
  • 热数据的内存blob缓存(可以在多个value log之间共享以限制内存使用)
  • 在线垃圾回收

键大小限制为65536字节,值大小限制为2^32字节。

功能标志

serde

启用serde派生。 默认禁用。

bytes

使用bytes作为底层Slice类型。 默认禁用。

稳定磁盘格式

从1.0.0版本开始,磁盘格式已稳定。

完整使用示例

use value_log::{ValueLog, ValueLogOptions};
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建或打开value log
    let path = Path::new("my_value_log");
    let options = ValueLogOptions::default();
    let value_log = ValueLog::open(path, options)?;
    
    // 写入数据
    let key = b"test_key";
    let value = b"test_value";
    value_log.put(key, value)?;
    
    // 读取数据
    if let Some(retrieved_value) = value_log.get(key)? {
        println!("Retrieved value: {:?}", retrieved_value);
    }
    
    // 删除数据
    value_log.delete(key)?;
    
    // 确保所有操作都持久化到磁盘
    value_log.sync()?;
    
    Ok(())
}

高级使用示例

use value_log::{ValueLog, ValueLogOptions};
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 配置value log选项
    let options = ValueLogOptions {
        max_file_size: 1024 * 1024, // 1MB
        sync_writes: true,          // 每次写入后同步
        ..Default::default()
    };
    
    // 打开value log
    let path = Path::new("advanced_value_log");
    let value_log = ValueLog::open(path, options)?;
    
    // 批量写入
    let batch = vec![
        (b"key1", Some(b"value1")),  // 插入/更新
        (b"key2", Some(b"value2")),  // 插入/更新
        (b"key3", None),             // 删除
    ];
    
    value_log.batch(batch)?;
    
    // 迭代所有键值对
    let iter = value_log.iter();
    for item in iter {
        let (key, value) = item?;
        println!("Key: {:?}, Value: {:?}", key, value);
    }
    
    Ok(())
}

完整示例demo

下面是一个结合基本和高级功能的完整示例:

use value_log::{ValueLog, ValueLogOptions};
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 配置value log选项
    let options = ValueLogOptions {
        max_file_size: 1024 * 1024 * 10, // 10MB
        sync_writes: false,              // 不立即同步以提高性能
        compress: true,                  // 启用压缩
        ..Default::default()
    };

    // 创建或打开value log
    let path = Path::new("demo_value_log");
    let value_log = ValueLog::open(path, options)?;

    // 基础CRUD操作
    let key1 = b"user:1001";
    let value1 = b"{name: \"Alice\", age: 30}";
    value_log.put(key1, value1)?;

    // 读取数据
    if let Some(data) = value_log.get(key1)? {
        println!("User data: {:?}", data);
    }

    // 更新数据
    let updated_value = b"{name: \"Alice\", age: 31}";
    value_log.put(key1, updated_value)?;

    // 批量操作
    let batch_data = vec![
        (b"config:theme", Some(b"dark")),
        (b"config:language", Some(b"zh-CN")),
        (b"temp:session", Some(b"abc123")),
        (b"temp:cache", None), // 删除操作
    ];
    value_log.batch(batch_data)?;

    // 迭代所有键值对
    println!("All entries:");
    for entry in value_log.iter() {
        let (key, value) = entry?;
        println!("{:?} => {:?}", key, value);
    }

    // 同步到磁盘
    value_log.sync()?;

    // 关闭value log (通过Drop trait自动处理)
    Ok(())
}

许可证

所有源代码均采用MIT OR Apache-2.0许可证。 所有贡献也必须采用MIT OR Apache-2.0许可证。


1 回复

Rust日志记录库value-log使用指南

介绍

value-log是一个轻量级的Rust日志存储和检索库,专为高效日志处理而设计。它提供了简单的键值存储接口,适合需要快速写入和检索日志数据的应用场景。

value-log的主要特点:

  • 高性能的日志写入
  • 紧凑的存储格式
  • 简单的检索接口
  • 轻量级实现,无复杂依赖

安装

在Cargo.toml中添加依赖:

[dependencies]
value-log = "0.1"  # 请检查最新版本号

基本使用方法

1. 创建和写入日志

use value_log::ValueLog;

fn main() -> std::io::Result<()> {
    // 创建或打开一个日志文件
    let mut log = ValueLog::create("mylog.vlog")?;
    
    // 写入日志条目
    log.write(b"key1", b"value1")?;
    log.write(b"key2", b"value2")?;
    log.write(b"key3", b"value3")?;
    
    // 确保数据写入磁盘
    log.sync()?;
    
    Ok(())
}

2. 读取日志

use value_log::ValueLog;

fn main() -> std::io::Result<()> {
    // 打开已存在的日志文件
    let log = ValueLog::open("mylog.vlog")?;
    
    // 读取特定键的值
    if let Some(value) = log.read(b"key2")? {
        println!("Found value: {:?}", String::from_utf8_lossy(&value));
    } else {
        println!("Key not found");
    }
    
    Ok(())
}

3. 迭代所有日志条目

use value_log::ValueLog;

fn main() -> std::io::Result<()> {
    let log = ValueLog::open("mylog.vlog")?;
    
    // 迭代所有键值对
    for entry in log.iter() {
        let (key, value) = entry?;
        println!(
            "Key: {:?}, Value: {:?}", 
            String::from_utf8_lossy(&key),
            String::from_utf8_lossy(&value)
        );
    }
    
    Ok(())
}

高级用法

批量写入

use value_log::ValueLog;

fn main() -> std::io::Result<()> {
    let mut log = ValueLog::create("batchlog.vlog")?;
    
    // 准备批量数据
    let entries = vec![
        (b"batch1".to_vec(), b"value1".to_vec()),
        (b"batch2".to_vec(), b"value2".to_vec()),
        (b"batch3".to_vec(), b"value3".to_vec()),
    ];
    
    // 批量写入
    log.write_batch(entries)?;
    
    Ok(())
}

自定义配置

use value_log::{ValueLog, Config};

fn main() -> std::io::Result<()> {
    // 自定义配置
    let config = Config {
        sync_on_write: true,  // 每次写入后同步到磁盘
        max_file_size: 1024 * 1024,  // 1MB最大文件大小
        ..Default::default()
    };
    
    let mut log = ValueLog::with_config("configlog.vlog", config)?;
    
    // 使用自定义配置的日志
    log.write(b"config_key", b"config_value")?;
    
    Ok(())
}

完整示例demo

下面是一个结合了基本使用和高级用法的完整示例:

use value_log::{ValueLog, Config};
use std::io::Result;

fn main() -> Result<()> {
    // 创建自定义配置的日志实例
    let config = Config {
        sync_on_write: false,  // 禁用每次写入同步以提高性能
        max_file_size: 2 * 1024 * 1024,  // 2MB最大文件大小
        ..Default::default()
    };
    
    let mut log = ValueLog::with_config("app_log.vlog", config)?;
    
    // 单条写入示例
    log.write(b"startup", b"application started")?;
    
    // 批量写入示例
    let log_entries = vec![
        (b"event1".to_vec(), b"user logged in".to_vec()),
        (b"event2".to_vec(), b"data processed".to_vec()),
        (b"event3".to_vec(), b"request completed".to_vec()),
    ];
    log.write_batch(log_entries)?;
    
    // 手动同步到磁盘
    log.sync()?;
    
    // 读取示例
    if let Some(value) = log.read(b"event2")? {
        println!("查询结果: {}", String::from_utf8_lossy(&value));
    }
    
    // 迭代所有日志条目
    println!("所有日志条目:");
    for entry in log.iter() {
        let (key, value) = entry?;
        println!(
            "键: {}, 值: {}",
            String::from_utf8_lossy(&key),
            String::from_utf8_lossy(&value)
        );
    }
    
    Ok(())
}

性能提示

  1. 对于高频写入场景,可以设置sync_on_write: false并定期调用sync()方法
  2. 批量写入通常比单条写入性能更好
  3. 考虑使用压缩算法处理大值数据

注意事项

  • value-log目前不支持并发写入,多线程环境下需要加锁
  • 日志文件会随着时间增长,需要定期维护或轮转
  • 删除操作是通过写入特殊标记实现的,不会立即释放磁盘空间

value-log为Rust应用提供了一个简单高效的日志存储解决方案,特别适合需要快速记录和检索结构化日志的场景。

回到顶部