01-leveldb编译和使用

在github下载开源代码:git clone --recurse-submodules https://github.com/google/leveldb.git

进入项目根目录,执行以下命令:
mkdir -p build && cd build

cmake -DCMAKE_BUILD_TYPE=Release … && cmake --build .

以上命令运行之后会编译全部代码包括测试程序,windows下编译生成文件在leveldb/build/Release下。同时在leveldb/build目录下可以打开leveldb.sln工程文件,在visual studio中查看工程代码。

一个简单的应用leveldb实现数据写入、查询的例子,依照国际惯例,还是从“hello world”开始:

#include <cassert>
#include "leveldb/db.h"int main()
{//open databaseleveldb::DB* db;leveldb::Options options;options.create_if_missing = true;leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb", &db);if (!status.ok()) {std::cout << "open db failed" << std::endl;return -1;}std::string key = "first_key";std::string value = "hello world";leveldb::Status s = db->Put(leveldb::WriteOptions(), key, value);value.clear();if (s.ok()){s = db->Get(leveldb::ReadOptions(), key, &value);}if(s.ok()){std::out << value << std::endl;}//close databasedelete db;return 0;
}

运行结果:Hello world

02-leveldb的基本操作

1-打开数据库

打开leveldb数据库需要指定一个文件系统目录,数据库的所有文件都存放在该目录下。

#include <cassert>
#include "leveldb/db.h"leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb", &db);
assert(status.ok());
...

2-读写数据

leveldb提供了Get、Put、Delete方法来进行数据的查询、写入和删除操作。没有提供更新接口,直接使用Put接口写入一个新的value即会覆盖之前的值。

std::string value;
leveldb::Status s = db->Get(leveldb::ReadOptions(), key1, &value);
if (s.ok()) s = db->Put(leveldb::WriteOptions(), key2, value);
if (s.ok()) s = db->Delete(leveldb::WriteOptions(), key1);

3-原子更新

如果某个业务的处理需要连续写入多个数据,这些数据会依次写入。如果中途宕机则可能导致部分写入成功,部分失败,从而影响业务的完整性。使用WriteBatch批处理功能,则会保证一个WriteBatch的所有操作要么全部成功,要么全部失败,即保证原子性。

#include "leveldb/write_batch.h"
...
std::string value;
leveldb::Status s = db->Get(leveldb::ReadOptions(), key1, &value);
if (s.ok()) {leveldb::WriteBatch batch;batch.Delete(key1);batch.Put(key2, value);s = db->Write(leveldb::WriteOptions(), &batch);
}

4-同步写

leveldb提供了同步写方式,即每次写入数据后强制刷盘。这种方式能保证机器宕机情况下数据的落盘安全,但会极大地降低数据库写入性能。在实际使用中我们往往不会采用同步写的方式,即允许极端情况下的一些数据丢失,而保证其使用的性能。

leveldb::WriteOptions write_options;
write_options.sync = true;
db->Put(write_options, ...);

5-迭代

以下代码用于迭代数据库的所有数据。

leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
for (it->SeekToFirst(); it->Valid(); it->Next()) {cout << it->key().ToString() << ": "  << it->value().ToString() << endl;
}
assert(it->status().ok());  // Check for any errors found during the scan
delete it;

以下代码用于迭代指定范围内的数据。

leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
for (it->Seek(start);it->Valid() && it->key().ToString() < limit;it->Next()) {...
}
assert(it->status().ok());  // Check for any errors found during the scan
delete it;

以下代码用于倒序迭代所有的数据。

for (it->SeekToLast(); it->Valid(); it->Prev()) {...
}

5-快照

快照提供了整个存储数据状态的一致性只读视图。ReadOptions::snapshot如果不为空,则会在指定的数据库状态版本上进行读取。如果ReadOptions::snapshot为空,则会在当前状态隐式地创建一个快照,即在当前快照上进行读取。

leveldb::ReadOptions options;
options.snapshot = db->GetSnapshot();
... apply some updates to db ...
leveldb::Iterator* iter = db->NewIterator(options);
... read using iter to view the state when the snapshot was created ...
delete iter;
db->ReleaseSnapshot(options.snapshot);

需要注意当快照不再使用时,需要调用ReleaseSnapshot释放快照,以免需要维护其状态而占用资源。

6-缓存

当block_cache不为空时,最常使用的数据块会进行缓存,这些块是未进行压缩的。使用缓存有利用优化查询性能,尤其是对于频繁查询相同数据的场景。

#include "leveldb/cache.h"leveldb::Options options;
options.block_cache = leveldb::NewLRUCache(100 * 1048576);  // 100MB cache
leveldb::DB* db;
leveldb::DB::Open(options, name, &db);
... use the db ...
delete db
delete options.block_cache;

7-布隆过滤器

leveldb的查询可能要进行多次磁io,为了减少磁盘IO,提升查询性能,可以开户布隆过滤器。

leveldb::Options options;
options.filter_policy = NewBloomFilterPolicy(10);
leveldb::DB* db;
leveldb::DB::Open(options, "/tmp/testdb", &db);
... use the database ...
delete db;
delete options.filter_policy;

03-leveldb参数介绍

leveldb的主要参数通过Options设置,其在options.h文件中定义。下面就介绍下其主要参数及含义:

  • const Comparator* comparator;比较函数,主要用于key的大小比较。如果传入NULL则使用默认字节序进行比较。
  • bool create_if_missing = false;如果数据库不存在,则创建。
  • bool error_if_exists = false;如果数据库存在,返回错误。
  • bool paranoid_checks = false;如果开启,则在读取数据时进行严格的检查,若发现数据损坏,则立即结束。
  • Env* env;用户定义环境,用于文件读写、后台线程等,默认Env::Default()。
  • Logger* info_log;日志对象指针,如果传入为空,则使用默认定义的日志对象。
  • size_t write_buffer_size = 4 * 1024 * 1024;写缓冲区的大小,对应于memtable的空间大小,会影响并发写入性能,原理部分会进行详细说明。
  • int max_open_files = 1000;最大打开文件数,也会关系到tablecache的大小.
  • Cache* block_cache = nullptr;data block缓存,如果为nullptr则数据块不进行缓存。
  • size_t block_size = 4 * 1024;数据块的大小,默认为4k,一般不需修改。
  • int block_restart_interval = 16;重启点的间隔,即每16个key进行前缀压缩。
  • size_t max_file_size = 2 * 1024 * 1024;文件最大大小,根据存储数据大小进行调整。
  • CompressionType compression = kSnappyCompression;是否对数进行压缩。
  • const FilterPolicy* filter_policy = nullptr;布隆过滤器,使用布隆过滤器有利于提高查询效率。

以上只是对参数做简单介绍,对于初学者,如果只是运行个demo,则不用太多理解即可使用。若是在实际项目中使用,则需要根据情况进行设置,以保证其性能等需求。

如果希望对参数充分理解,则需要对leveldb的原理进行深入了解,甚至阅读和分析源码。这对于想要充分利用和改造leveldb是必需的。下一章将会详细讲解leveldb的原理,随着对leveldb原理的深入,这些参数的具体含义也都会迎刃而解。

02-leveldb入门相关推荐

  1. MyBatis-学习笔记02【02.Mybatis入门案例】

    Java后端 学习路线 笔记汇总表[黑马程序员] MyBatis-学习笔记01[01.Mybatis课程介绍及环境搭建][day01] MyBatis-学习笔记02[02.Mybatis入门案例] M ...

  2. 02前端入门HTML5 +CSS3+电商网页制作:CSS

    02前端入门HTML5 +CSS3+电商网页制作 0 来源 1 CSS基础 1.1 基础认识 1.1.1 css demo 1.1.1 css的层叠性 1.2 CSS引入方式 1.3 选择器 1.4 ...

  3. axios vue 回调函数_Vue 02 —— Vue 入门小案例~使用 Axios 中的GET、POST请求

    作为后端攻城狮,写前端代码是一种什么体验? 相信不少人和 @Python大星 一样,有写过前端代码的经历. 记录一下,Vue 框架开发中"啼笑皆非"的故事,非专业前端人员,该案例无 ...

  4. leveldb——leveldb入门篇之Linux下编译配置和使用

    1.首先,从github上下载leveldb源码的zip文件 使用命令 #wget https://codeload.github.com/google/leveldb/zip/master 2.下载 ...

  5. 【NodeJS 学习笔记02】入门资源很重要

    前言 在我映像中,异步最早出现与ajax,当时我还在搞.net,然后.net居然出了一个异步的控件...... 虽然我最后知道了他不是异步的......然后,前端异步用得特别多,如果不是异步的程序,你 ...

  6. 02 stata入门【计量经济学及stata应用】

    安装:建议直接在微信搜索,很多公众号有安装包资源及下载教程 不同版本在基本功能上无较大差异,一般为SE,更为专业MP,只是在处理变量个数或容量等存在不同 界面 历史命令:结果窗口&命令窗口:变 ...

  7. day75,爬虫02,webmagic入门程序,组件介绍:Downloader,PageProcess,pipeline,Scheduler,51jop招聘网站综合案例

    一.webmagic入门程序(原理图) 使用方法 1)创建工程 2)添加jar包 <dependencies><!--WebMagic--><dependency> ...

  8. SWMM从入门到实践教程 02 快速入门案例的绘制

    文章目录 1 建模准备 2 设置各类设施 2.1 添加雨量计 2.2 添加子汇水区(正方形) 2.3 绘制节点(圆形) 2.4 绘制管渠 2.5 添加排水口(三角形) 3 画面调节 1 建模准备 建模 ...

  9. 2021全网最全Activiti7教程02(Activiti7入门使用-欢迎收藏)

    全网最详细Activiti系列文章,强烈建议收藏加关注哦! Activiti的入门应用 1Activiti的基本使用 1.1 创建Maven项目   创建一个普通的Maven项目,并添加相关的依赖 & ...

  10. 02.JavaScript入门

    javascript: JavaScript在1995年由Netscape公司的Brendan Eich,在网景导航者浏览器上首次设计实现而成.因为Netscape与Sun合作,Netscape管理层 ...

最新文章

  1. c语言作业扩展名通常为什么,C语言的源程序通常的扩展名是( )
  2. 赠书 | 人工智能识万物:卷积神经网络的前世今生
  3. 修复思维导图mindmanager移动文件位置后打开崩溃
  4. 雅客EXCEL(4)-录入数据、超链接阻断、下拉菜单、横列转数列、alt+向下方向键、定位公式
  5. Hadoop入门(八)Mapreduce高级shuffle之Partitioner
  6. Hibernate和MyBatis的缓存机制和比较
  7. SpringBoot(10)
  8. 解决sublime text3 v3.1.1,Build3176中的汉字形状扭曲问题
  9. mongo go 查询指定字段_使用PyMongo查询MongoDB数据库!
  10. Kernel(核函数)
  11. python二维游戏编程 最强大脑游戏_看完《最强大脑》,我决定用Python做这个游戏...
  12. MyBatis 插件原理与实战
  13. 使用outlook及office assitans实现邮件批量发送
  14. 计算机能力怎么填制作ppt,电脑怎么制作PPT
  15. android 拍照和相册,Android 拍照和从相册选照片
  16. Linux系统设置命令别名
  17. centos7 配置虚拟ip
  18. Python爬取国家数据中心环境数据(全国城市空气质量小时报)并导入csv文件
  19. 如何在Excel中批量新建工作表
  20. pytorch入门学习(四)-----计算图与动态图

热门文章

  1. 希尔伯特变换(Hilbert Transform)的性质
  2. fgets函数的用法
  3. 速度最快的数据库---MEMSQL的安装与部署
  4. flutter学习之二Material Design设计规范
  5. Filament介绍
  6. Oracle创建同义词
  7. 使用Matlab绘制星座图
  8. 任务调度 的常用的基本方式
  9. 简单而有韵味,让你get最浪漫的表白编程代码大全
  10. **06-图3 六度空间 (30 分)**