0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

持久化数据到硬盘上并采用RocksDB作为存储引擎

工程师邓生 来源:coding到灯火阑珊 作者:李明 2022-09-29 10:00 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在上一篇文章中,我们使用内存做数据的存储。在这一篇文章中,我们持久化数据到硬盘上,采用RocksDB作为存储引擎。同时也增加了一个service层,将命令解析和存储逻辑提取到这一层中。

RocksDB 先在Cargo.toml文件中加入rocksdb依赖:

poYBAGM0_GqAZhS6AAAXGsoUAAs416.jpg

然后,在src/storage目录下创建rocksdb_storage.rs文件。代码如下:

 1#[derive(Debug)]
 2pubstructRocksDbStorage(DB);
 3
 4implRocksDbStorage{
 5pubfnnew(path:implAsRef)->Self{
 6Self(DB::open_default(path).unwrap())
 7}
 8}
 9
10implStorageforRocksDbStorage{
11fnget(&self,key:&str)->Result,Box>{
12letv=self.0.get(key)?.unwrap();
13Ok(Some(v.into()))
14}
15
16fnset(&self,key:&str,value:bytes::Bytes)->Result,Box>{
17self.0.put(key,value.clone()).unwrap();
18Ok(Some(value))
19}
20}
Service层 创建src/service目录,然后创建mod.rs文件及cmd_service.rs文件。在mod.rs文件中加入如下代码:
1pubmodcmd_service;
2
3pubtraitCmdService{
4//解析命令,返回Response
5fnexecute(self,store:&implStorage)->CmdResponse;
6}
在cmd_service.rs文件中为命令实现CmdService trait,代码如下:
 1usecrate::{CmdResponse,CmdService,Get,Set};
 2
 3//为GET实现execute
 4implCmdServiceforGet{
 5fnexecute(self,store:&implcrate::Storage)->CmdResponse{
 6//从存储中获取数据,返回CmdResponse
 7matchstore.get(&self.key){
 8Ok(Some(value))=>value.into(),
 9Ok(None)=>"Notfound".into(),
10Err(e)=>e.into(),
11}
12}
13}
14
15//为SET实现execute
16implCmdServiceforSet{
17//存储数据
18fnexecute(self,store:&implcrate::Storage)->CmdResponse{
19matchstore.set(&self.key,self.value){
20Ok(Some(value))=>value.into(),
21Ok(None)=>"Setfail".into(),
22Err(e)=>e.into(),
23}
24}
25}
在src/pb/mod.rs中实现从Bytes、&str、Box转换为CmdResponse:
 1implFromforCmdResponse{
 2fnfrom(v:Bytes)->Self{
 3Self{
 4status:200u32,
 5message:"success".to_string(),
 6value:v,
 7}
 8}
 9}
10
11implFrom<&str>forCmdResponse{
12fnfrom(s:&str)->Self{
13Self{
14status:400u32,
15message:s.to_string(),
16..Default::default()
17}
18}
19}
20
21implFrom>forCmdResponse{
22fnfrom(e:Box)->Self{
23Self{
24status:500u32,
25message:e.to_string(),
26..Default::default()
27}
28}
29}
然后在src/service/mod.rs中加入service代码:
 1//设置默认存储为RocksDB
 2pubstructService{
 3store_svc:Arc>,
 4}
 5
 6//在多线程中进行clone
 7pubstructStoreService{
 8store:Store,
 9}
10
11implService{
12pubfnnew(store:Store)->Self{
13Self{
14store_svc:Arc::new(StoreService{store}),
15}
16}
17
18//执行命令
19pubasyncfnexecute(&self,cmd_req:CmdRequest)->CmdResponse{
20println!("===ExecuteCommandBefore===");
21letcmd_res=process_cmd(cmd_req,&self.store_svc.store).await;
22println!("===ExecuteCommandAfter===");
23cmd_res
24}
25}
26
27//实现Clonetrait
28implCloneforService{
29fnclone(&self)->Self{
30Self{
31store_svc:self.store_svc.clone(),
32}
33}
34}
35
36//处理请求命令,返回Response
37asyncfnprocess_cmd(cmd_req:CmdRequest,store:&implStorage)->CmdResponse{
38matchcmd_req.req_data{
39//处理GET命令
40Some(ReqData::Get(cmd_get))=>cmd_get.execute(store),
41//处理SET命令
42Some(ReqData::Set(cmd_set))=>cmd_set.execute(store),
43_=>"Invalidcommand".into(),
44}
45}

配置 我们修改配置,在conf/server.conf中加入RocksDB路径
......[rocksdb_path]path = '/tmp/kvserver'
在src/config.rs中加入如下代码:
 1//Server端配置
 2#[derive(Debug,Serialize,Deserialize)]
 3pubstructServerConfig{
 4......
 5pubrocksdb_path:RocksdbPath,
 6}
 7
 8......
 9
10//RocksDB存储目录
11#[derive(Debug,Serialize,Deserialize)]
12pubstructRocksdbPath{
13pubpath:String,
14}
修改kv_server 在kv_server.rs中使用service执行命令,删除process_cmd函数:
 1#[tokio::main]
 2asyncfnmain()->Result<(), Box>{
 3......
 4
 5//初始化Service及存储
 6letservice=Service::new(RocksDbStorage::new(rocksdb_path));
 7
 8loop{
 9......
10letsvc=service.clone();
11
12tokio::spawn(asyncmove{
13//使用Frame的LengthDelimitedCodec进行编解码操作
14letmutstream=Framed::new(stream,LengthDelimitedCodec::new());
15whileletSome(Ok(mutbuf))=stream.next().await{
16......
17
18//执行请求命令
19letcmd_res=svc.execute(cmd_req).await;
20
21......
22}
23info!("Client{:?}disconnected",addr);
24});
25}
26}

审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据存储
    +关注

    关注

    5

    文章

    1014

    浏览量

    52608
  • 编解码
    +关注

    关注

    1

    文章

    149

    浏览量

    20442
  • Rust
    +关注

    关注

    1

    文章

    240

    浏览量

    7481

原文标题:用Rust实现KV Server-4 持久化存储及service层

文章出处:【微信号:Rust语言中文社区,微信公众号:Rust语言中文社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    SAS固态硬盘存储技术

    SAS固态硬盘存储技术是一种介于传统硬盘和内存之间的存储技术,在IOPS上,相比普通机械硬盘存储速度快50
    发表于 06-18 05:00

    Docker持久数据存储方案

    Docker持久存储数据共享
    发表于 03-23 11:17

    硬盘是怎么来存储数据的?

    存储是模拟格式的音乐,而硬盘上存储的是数字格式的数据。写入时,磁头线圈上加电,在周围产生磁场,磁化其下的磁性材料;电流的方向不同,所以磁场的方向也不同,可以表示 0 和 1 的区别。
    发表于 07-07 08:03

    硬盘上数据是如何组织与管理的呢?

    硬盘的外部物理结构是由哪些部分组成的?硬盘的内部物理结构是由哪些部分组成的?硬盘存储的逻辑结构是由哪些部分组成的?硬盘上数据是如何组织与管
    发表于 07-13 07:00

    OpenHarmony持久存储UI状态:PersistentStorage

    最好是小于2kb的数据,不要大量的数据持久,因为PersistentStorage写入磁盘的操作是同步的,大量的数据本地
    发表于 10-19 14:34

    HarmonyOS数据管理与应用数据持久(一)

    为应用提供Key-Value键值型的数据处理能力,支持应用持久轻量级数据对其修改和查询。当用户希望有一个全局唯一
    发表于 11-01 16:27

    Rocksdb原理简介

    Rocksdb作为当下nosql中性能的代表被各个存储组件(mysql、tikv、pmdk、bluestore)作为存储
    的头像 发表于 06-01 17:17 1546次阅读
    <b class='flag-5'>Rocksdb</b>原理简介

    如何开启RDB持久方式

      RDB快照(Redis DataBase) RDB是一种快照存储持久方式,具体就是将Redis某一时刻的内存数据保存到硬盘的文件当中,
    的头像 发表于 06-25 11:52 1427次阅读
    如何开启RDB<b class='flag-5'>持久</b><b class='flag-5'>化</b>方式

    Redis持久RDB方式介绍

    时Redis会自动将内存中的数据进行快照持久硬盘。 触发快照的时机 符合自定义配置的快照规
    的头像 发表于 10-09 14:56 1024次阅读
    Redis<b class='flag-5'>持久</b><b class='flag-5'>化</b>RDB方式介绍

    redis两种持久方式的区别

    Redis是一款高性能、开源的键值存储数据库,它支持多种数据结构,并且具有高效的内存读写以及持久功能。Redis的
    的头像 发表于 12-04 11:12 988次阅读

    redis持久机制和如何实现持久

    File)。 RDB是Redis默认采用持久方式,它通过在指定时间间隔内将内存中的数据集快照写入磁盘的二进制文件中,实现
    的头像 发表于 12-05 10:02 893次阅读

    redis持久机制优缺点

    Redis是一个基于内存的高性能键值存储系统,它提供了多种持久机制来保证数据的可靠性。本文将详细介绍Redis的持久
    的头像 发表于 12-05 10:03 1278次阅读

    redis里数据什么时候持久

    Redis是一种开源的高性能、非关系型内存数据库,它使用了键值对存储数据,并且支持多种数据结构。 Redis提供了持久
    的头像 发表于 12-05 10:05 836次阅读

    EEPROM存储器:实现数据持久存储的关键组件

    在计算机系统中,存储器是用于存储数据和程序指令的关键部件。其中,EEPROM(电可擦除可编程只读存储器)作为一种非易失性
    的头像 发表于 05-27 16:36 3132次阅读

    硬盘擦除遇到硬盘上锁怎么解决?完整指南告诉你

    本文深入探讨硬盘上锁原因及解决方案,提供PSID解锁硬盘的详细指南。了解硬盘加密、密码遗失、Secure Erase中断等导致硬盘锁定的问题,
    的头像 发表于 12-17 16:32 8362次阅读
    <b class='flag-5'>硬盘</b>擦除遇到<b class='flag-5'>硬盘上</b>锁怎么解决?完整指南告诉你