暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【Rust每周一库】sled - 嵌入式数据库

Rust语言中文社区 2021-05-16
2340

简介

Sled是基于Bw树构建的嵌入式KV数据库,其API接近于一个线程安全的BTreeMap<[u8], [u8]>。而其Bw树的数据结构加上包括crossbeam-epoch的“GC”等技术,使得Sled成为一个lock-free的数据库而在并发环境中傲视群雄。忘记那些慢吞吞的锁吧~ 而官方宣称在一台16核的机器上,在一个小数据集上可以达到每分钟10亿次操作(95%读核5%写)
要使用sled,只需要在Cargo.toml中加入
    sled = "0.32"

    例子

    基础用法
      打开数据库
      let tree = sled::open("/tmp/welcome-to-sled").expect("open");


      // 插入KV,读取Key对应的值
      tree.insert("KEY1", "VAL1");
      assert_eq!(tree.get(&"KEY1"), Ok(Some(sled::IVec::from("VAL1"))));


      // 范围查询
      for kv in tree.range("KEY1".."KEY9") {
      ...
      }


      // 删除
      tree.remove(&"KEY1");


      // atomic compare and swap,可以用在并发编程中
      tree.compare_and_swap("KEY1", Some("VAL1"), Some("VAL2"));


      // 阻塞直到所有修改都写入硬盘
      tree.flush();

      处理结构体
        use {
        byteorder::{BigEndian, LittleEndian},
        zerocopy::{
        byteorder::U64, AsBytes, FromBytes, LayoutVerified, Unaligned,
        },
        };


        // 键结构体
        // zerocopy::byteorder::U64保证了数据对齐问题
        #[derive(FromBytes, AsBytes, Unaligned)]
        #[repr(C)]
        struct Key {
        a: U64<BigEndian>,
        b: U64<BigEndian>,
        }


        // 值结构体
        #[derive(FromBytes, AsBytes, Unaligned)]
        #[repr(C)]
        struct Value {
        count: U64<LittleEndian>,
        whatever: [u8; 16],
        }


        let key = Key { a: U64::new(21), b: U64::new(890) };


        // 取得键所对应的值,并对其施加给定函数灿做
        db.update_and_fetch(key.as_bytes(), |value_opt| {
        if let Some(existing) = value_opt {
        let mut backing_bytes = sled::IVec::from(existing);


        // 验证数据对齐(这里其实不是必须的,因为我们使用了U64)
        let layout: LayoutVerified<&mut [u8], Value> =
        LayoutVerified::new_unaligned(&mut *backing_bytes)
        .expect("bytes do not fit schema");


        // 得到底层数据的可变引用
        let value: &mut Value = layout.into_mut();


        let new_count = value.count.get() + 1;


        println!("incrementing count to {}", new_count);


        value.count.set(new_count);


        Some(backing_bytes)
        } else {
        println!("setting count to 0");


        // 初始化一个Value
        Some(sled::IVec::from(
        Value { count: U64::new(0), whatever: [0; 16] }.as_bytes(),
        ))
        }
        })?;

        小结

        Sled是当前Rust嵌入式数据库中有力的候选人之一。当然,除了还处于beta版这一问题外,sled有时还会消耗较多的存储(这一点是比起RocksDB的不足之处)。人无完人嘛,让我们一起期待其稳定版早日上线~

        文章转载自Rust语言中文社区,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论