02-leveldb入门
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入门相关推荐
- MyBatis-学习笔记02【02.Mybatis入门案例】
Java后端 学习路线 笔记汇总表[黑马程序员] MyBatis-学习笔记01[01.Mybatis课程介绍及环境搭建][day01] MyBatis-学习笔记02[02.Mybatis入门案例] M ...
- 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 ...
- axios vue 回调函数_Vue 02 —— Vue 入门小案例~使用 Axios 中的GET、POST请求
作为后端攻城狮,写前端代码是一种什么体验? 相信不少人和 @Python大星 一样,有写过前端代码的经历. 记录一下,Vue 框架开发中"啼笑皆非"的故事,非专业前端人员,该案例无 ...
- leveldb——leveldb入门篇之Linux下编译配置和使用
1.首先,从github上下载leveldb源码的zip文件 使用命令 #wget https://codeload.github.com/google/leveldb/zip/master 2.下载 ...
- 【NodeJS 学习笔记02】入门资源很重要
前言 在我映像中,异步最早出现与ajax,当时我还在搞.net,然后.net居然出了一个异步的控件...... 虽然我最后知道了他不是异步的......然后,前端异步用得特别多,如果不是异步的程序,你 ...
- 02 stata入门【计量经济学及stata应用】
安装:建议直接在微信搜索,很多公众号有安装包资源及下载教程 不同版本在基本功能上无较大差异,一般为SE,更为专业MP,只是在处理变量个数或容量等存在不同 界面 历史命令:结果窗口&命令窗口:变 ...
- day75,爬虫02,webmagic入门程序,组件介绍:Downloader,PageProcess,pipeline,Scheduler,51jop招聘网站综合案例
一.webmagic入门程序(原理图) 使用方法 1)创建工程 2)添加jar包 <dependencies><!--WebMagic--><dependency> ...
- SWMM从入门到实践教程 02 快速入门案例的绘制
文章目录 1 建模准备 2 设置各类设施 2.1 添加雨量计 2.2 添加子汇水区(正方形) 2.3 绘制节点(圆形) 2.4 绘制管渠 2.5 添加排水口(三角形) 3 画面调节 1 建模准备 建模 ...
- 2021全网最全Activiti7教程02(Activiti7入门使用-欢迎收藏)
全网最详细Activiti系列文章,强烈建议收藏加关注哦! Activiti的入门应用 1Activiti的基本使用 1.1 创建Maven项目 创建一个普通的Maven项目,并添加相关的依赖 & ...
- 02.JavaScript入门
javascript: JavaScript在1995年由Netscape公司的Brendan Eich,在网景导航者浏览器上首次设计实现而成.因为Netscape与Sun合作,Netscape管理层 ...
最新文章
- c语言作业扩展名通常为什么,C语言的源程序通常的扩展名是( )
- 赠书 | 人工智能识万物:卷积神经网络的前世今生
- 修复思维导图mindmanager移动文件位置后打开崩溃
- 雅客EXCEL(4)-录入数据、超链接阻断、下拉菜单、横列转数列、alt+向下方向键、定位公式
- Hadoop入门(八)Mapreduce高级shuffle之Partitioner
- Hibernate和MyBatis的缓存机制和比较
- SpringBoot(10)
- 解决sublime text3 v3.1.1,Build3176中的汉字形状扭曲问题
- mongo go 查询指定字段_使用PyMongo查询MongoDB数据库!
- Kernel(核函数)
- python二维游戏编程 最强大脑游戏_看完《最强大脑》,我决定用Python做这个游戏...
- MyBatis 插件原理与实战
- 使用outlook及office assitans实现邮件批量发送
- 计算机能力怎么填制作ppt,电脑怎么制作PPT
- android 拍照和相册,Android 拍照和从相册选照片
- Linux系统设置命令别名
- centos7 配置虚拟ip
- Python爬取国家数据中心环境数据(全国城市空气质量小时报)并导入csv文件
- 如何在Excel中批量新建工作表
- pytorch入门学习(四)-----计算图与动态图