实验三十二 LevelDB实验:读写LevelDB

26 篇文章 10 订阅
1 篇文章 0 订阅

实验指导:

32.1 实验目的

1.了解LevelDB的使用场景;

2.理解LevelDB数据存储结构;

3.比较LevelDB和redis的区别;

4.能对LevelDB的整体架构有一定的了解;

5.能正确的使用LevelDB并能进行简单使用。

32.2 实验要求

本实验要求同学能够使用C++语言完成对LevelDB库完成以下操作:

1.连接到LevelDB数据库;

2.写入数据;

3.读取数据;

4.删除数据。

32.3 实验原理

LevelDB是Google开源的持久化KV单机数据库,具有很高的随机写,顺序读/写性能,但是随机读的性能很一般,也就是说,LevelDB很适合应用在查询较少,而写很多的场景。LevelDB应用了LSM (Log Structured Merge) 策略,lsm_tree对索引变更进行延迟及批量处理,并通过一种类似于归并排序的方式高效地将更新迁移到磁盘,降低索引插入开销。

特点:

1.key和value都是任意长度的字节数组;

2.entry(即一条K-V记录)默认是按照key的字典顺序存储的,当然开发者也可以重载这个排序函数;

3.提供的基本操作接口:Put()、Delete()、Get()、Batch();

4.支持批量操作以原子操作进行;

5.可以创建数据全景的snapshot(快照),并允许在快照中查找数据;

6.可以通过前向(或后向)迭代器遍历数据(迭代器会隐含的创建一个snapshot);

7.自动使用Snappy压缩数据;

8.可移植性。

限制:

1.非关系型数据模型(NoSQL),不支持sql语句,也不支持索引;

2.一次只允许一个进程访问一个特定的数据库;

3.没有内置的C/S架构,但开发者可以使用LevelDB库自己封装一个server。

整体架构:LevelDB作为存储系统,数据记录的存储介质包括内存以及磁盘文件,如果像上面说的,当LevelDB运行了一段时间,此时我们给LevelDB进行透视拍照,那么您会看到如图32-1所示。

图32-1 LevelDB结构

从图中可以看出,构成LevelDB静态结构的包括六个主要部分:内存中的MemTable和Immutable MemTable以及磁盘上的几种主要文件:Current文件,Manifest文件,log文件以及SSTable文件。当然,LevelDB除了这六个主要部分还有一些辅助的文件,但是以上六个文件和数据结构是LevelDB的主体构成元素。

LevelDB的Log文件和Memtable与Bigtable论文中介绍的是一致的,当应用写入一条Key:Value记录的时候,LevelDB会先往log文件里写入,成功后将记录插进Memtable中,这样基本就算完成了写入操作,因为一次写入操作只涉及一次磁盘顺序写和一次内存写入,所以这是为何说LevelDB写入速度极快的主要原因。

Log文件在系统中的作用主要是用于系统崩溃恢复而不丢失数据,假如没有Log文件,因为写入的记录刚开始是保存在内存中的,此时如果系统崩溃,内存中的数据还没有来得及Dump到磁盘,所以会丢失数据(Redis就存在这个问题)。为了避免这种情况,LevelDB在写入内存前先将操作记录到Log文件中,然后再记入内存中,这样即使系统崩溃,也可以从Log文件中恢复内存中的Memtable,不会造成数据的丢失。

当Memtable插入的数据占用内存到了一个界限后,需要将内存的记录导出到外存文件中,LevelDB会生成新的Log文件和Memtable,原先的Memtable就成为Immutable Memtable,顾名思义,就是说这个Memtable的内容是不可更改的,只能读不能写入或者删除。新到来的数据被记入新的Log文件和Memtable,LevelDB后台调度会将Immutable Memtable的数据导出到磁盘,形成一个新的SSTable文件。SSTable就是由内存中的数据不断导出并进行Compaction操作后形成的,而且SSTable的所有文件是一种层级结构,第一层为Level 0,第二层为Level 1,依次类推,层级逐渐增高,这也是为何称之为LevelDB的原因。

SSTable中的文件是Key有序的,就是说在文件中小key记录排在大Key记录之前,各个Level的SSTable都是如此,但是这里需要注意的一点是:Level 0的SSTable文件(后缀为.sst)和其它Level的文件相比有特殊性:这个层级内的.sst文件,两个文件可能存在key重叠,比如有两个level 0的sst文件,文件A和文件B,文件A的key范围是:{bar, car},文件B的Key范围是{blue,samecity},那么很可能两个文件都存在key=”blood”的记录。对于其它Level的SSTable文件来说,则不会出现同一层级内.sst文件的key重叠现象,就是说Level L中任意两个.sst文件,那么可以保证它们的key值是不会重叠的。这点需要特别注意,后面您会看到很多操作的差异都是由于这个原因造成的。

SSTable中的某个文件属于特定层级,而且其存储的记录是key有序的,那么必然有文件中的最小key和最大key,这是非常重要的信息,LevelDB应该记下这些信息。Manifest就是干这个的,它记载了SSTable各个文件的管理信息,比如属于哪个Level,文件名称叫啥,最小key和最大key各自是多少。如图32-2是Manifest所存储内容的示意:

图32-2 Manifest存储示意图

图中只显示了两个文件(manifest会记载所有SSTable文件的这些信息),即Level 0的test.sst1和test.sst2文件,同时记载了这些文件各自对应的key范围,比如test.sst1的key范围是“an”到 “banana”,而文件test.sst2的key范围是“baby”到“samecity”,可以看出两者的key范围是有重叠的。

Current文件是干什么的呢?这个文件的内容只有一个信息,就是记载当前的manifest文件名。因为在LevleDb的运行过程中,随着Compaction的进行,SSTable文件会发生变化,会有新的文件产生,老的文件被废弃,Manifest也会跟着反映这种变化,此时往往会新生成Manifest文件来记载这种变化,而Current则用来指出哪个Manifest文件才是我们关心的那个Manifest文件。

以上介绍的内容就构成了LevelDB的整体静态结构。

32.4 实验步骤

在master机上操作:首先进入LevelDB目录。

[root@master ~]# cd /usr/cstor/leveldb
[root@master leveldb]#

然后创建一个code的文件夹作为代码编写的目录。

[root@master leveldb]# mkdir code

进入code目录。

[root@master leveldb# cd code
[root@master code]#

利用vim编写leveldb.cpp代码(请参考32.4.6小节)

编译leveldb.cpp,编译命令如下:

[root@master code]# g++ -o leveldb leveldb.cpp ../out-static/libleveldb.a -lpthread -I../include


核心代码:

32.4.1 使用C++代码建立数据库连接

核心C++代码如下:

// 打开数据库连接
leveldb::Status status = leveldb::DB::Open(options,"./test_level_db", &db);
assert(status.ok());
string key = "weather";
string value = "clearday";

32.4.2 写入数据

写入数据的核心C++代码如下:

status = db->Put(leveldb::WriteOptions(), key, value);
assert(status.ok());

32.4.3 读取数据

读取数据的核心C++代码如下:

status = db->Get(leveldb::ReadOptions(), key, &value);
assert(status.ok());
cout<<"value :"<<value<<endl;

32.4.4 删除数据

删除数据的核心C++代码如下:

status = db->Delete(leveldb::WriteOptions(), key);
assert(status.ok());
status = db->Get(leveldb::ReadOptions(),key, &value);
if(!status.ok()) {
    cerr<<key<<"   "<<status.ToString()<<endl;
} else {
    cout<<key<<"==="<<value<<endl;
} 

32.4.5 关闭连接

关闭连接的核心C++代码如下:

delete db;

32.4.6 完整的代码

#include <iostream>
#include <string>
#include <assert.h>
#include "leveldb/db.h"
using namespace std;
int main(void)
{
    leveldb::DB      *db;
    leveldb::Options  options;
    options.create_if_missing = true;

    // 打开数据库连接
    leveldb::Status status = leveldb::DB::Open(options,"./test_level_db", &db);
    assert(status.ok());
    string key = "weather";
    string value = "clearday";
    // 写入数据
    status = db->Put(leveldb::WriteOptions(), key, value);
    assert(status.ok());
    // 读取数据
    status = db->Get(leveldb::ReadOptions(), key, &value);
    assert(status.ok());
    cout<<"value :"<<value<<endl;
    // 删除数据
    status = db->Delete(leveldb::WriteOptions(), key);
    assert(status.ok());
    status = db->Get(leveldb::ReadOptions(),key, &value);
    if(!status.ok()) {
        cerr<<key<<"   "<<status.ToString()<<endl;
    } else {
        cout<<key<<"==="<<value<<endl;
    }
    // 关闭连接
    delete db;
    return 0;
}

32.5 实验结果

输入 ./leveldb 运行程序查看结果。

[root@master code]# ./leveldb

如图32-3所示:

图32-3

用ls命令查看test_level_db目录如下。如图32-4所示。

[root@master code]# ls test_level_db

如图32-4所示:

图32-4

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
leveldb实现解析 淘宝-核心系统研发-存储 那岩 neveray@gmail.com 2011-12-13 目录 一、 代码目录结构 ....................................................................... 1 1. doc/ ............................................................................ 1 2. include/leveldb/ ................................................................. 1 3. db/ ............................................................................. 1 4. table/........................................................................... 1 5. port/ ........................................................................... 1 6. util/ ........................................................................... 1 7. helper/memenv/ ................................................................... 1 二、 基本概念 .......................................................................... 1 1. Slice (include/leveldb/slice.h) .................................................. 1 2. Option (include/leveldb/option.h) .............................................. 2 3. Env (include/leveldb/env.h util/env_posix.h) .................................... 3 4. varint (util/coding.h) ........................................................... 3 5. ValueType (db/dbformat.h) ...................................................... 3 6. SequnceNnumber (db/dbformat.h) ................................................. 4 7. user key......................................................................... 4 8. ParsedInternalKey (db/dbformat.h) .............................................. 4 9. InternalKey (db/dbformat.h) ...................................................... 4 10. LookupKey (db/dbformat.h) ........................................................ 4 11. Comparator (include/leveldb/comparator.h util/comparator.cc) .................... 4 12. InternalKeyComparator (db/dbformat.h) ............................................ 5 13. WriteBatch (db/write_batch.cc) ................................................. 5 14. Memtable (db/memtable.cc db/skiplist.h) .......................................... 5 15. Sstable (table/table.cc) ......................................................... 5 16. FileMetaData (db/version_edit.h) ............................................... 5 17. block (table/block.cc) ........................................................... 6 18. BlockHandle(table/format.h) ...................................................... 6 19. FileNumber(db/dbformat.h) ...................................................... 6 20. filename (db/filename.cc) ........................................................ 6 21. level-n (db/version_set.h) ....................................................... 7 22. Compact (db/db_impl.cc db/version_set.cc) ........................................ 7 23. Compaction(db/version_set.cc) .................................................... 7 24. Version (db/version_set.cc) ...................................................... 8 25. VersionSet (db/version_set.cc) ................................................. 9 26. VersionEdit(db/version_edit.cc) ................................................. 10 27. VersionSet::Builder (db/version_set.cc) ......................................... 11 28. Manifest(descriptor)(db/version_set.cc)...................................... 12 29. TableBuilder/BlockBuilder(table/table_builder.cc table/block_builder.cc) ......... 12 30. Iterator (include/leveldb/iterator.h) ........................................... 12 三、 存储结构的格式定义与操作 .......................................................... 12 1. memtable (db/skiplist.h db/memtable) ............................................ 12 2. block of sstable (table/block_builder.cc table/block.cc) ......................... 14 3. sstable (table/table_bulder.cc/table.cc) ........................................ 16 4. block of log (db/log_format.h db/log_writer.cc db/log_reader.cc) .............. 18 5. log (db/log_format.h db/log_writer.cc db/log_reader.cc) ........................ 18 6. cache(util/cache.cc) .......................................................... 19 7. Snapshot (include/leveldb/snapshot.h) ......................................... 19 8. Iterator (include/leveldb/iterator.h) ........................................... 19 四、 主要流程 ......................................................................... 24 1. open ........................................................................... 24 2. put ............................................................................ 25 3. get ............................................................................ 25 4. delete.......................................................................... 26 5. snapshot........................................................................ 26 6. NewIterator ..................................................................... 26 7. compact......................................................................... 26 五、 总结 ............................................................................. 30 1. 设计/实现中的优化 ............................................................... 30 2. 可以做的优化 .................................................................... 31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值