在leveldb中,我们通过调用db->Put(WriteOptions(),&key,&value);来写入数据,而WriteOptions只有一个变量sync,且默认初始值为false,因此leveldb默认的写数据方式是异步,即每将写操作提交将数据写入到内存中就返回,而将数据从内存写到磁盘的方式是异步的。
异步写比同步写的效率高得多,但是当系统故障时,可能导致最近的更新丢失。若将WriteOptions的sync设为true,则每次写入都会将数据写入到磁盘中,速度非常慢。
为此leveldb使用WriteBatch来替代简单的异步写操作,首先将所有的写操作记录到一个batch中,然后执行同步写,这样同步写的开销就被分散到多个写操作中。
利用leveldb的WriteBatch可以进行批量处理,用法如下:
leveldb::WriteBatch batch; batch.Put(key1, value1); batch.Delete(key1); batch.Put(key2, value); s = db->Write(leveldb::WriteOptions(), &batch);即使没有显式使用batch,在调用DB::Put()时,也是将一条记录通过WriteBatch的形式存储到系统中的
2. WriteBatch
WriteBatch的原理是先将所有的操作记录下来,然后再一起操作。
由之前的分析可知,leveldb插入和删除数据并不是直接插入、删除数据,而是插入一条记录(由记录的标志位来确定是要插入数据还是删除数据,具体的插入、删除操作将在Compaction时进行) 因此WriteBatch将会记录许多个操作,每一个操作代表着要插入或删除相应数据。
WriteBatch类的定义如下:
每一个WriteBatch都是以一个固定长度的头部开始,然后后面接着许多连续的记录, 固定头部共12字节,其中前8字节为WriteBatch的序列号,对应rep_[0]到rep_[7],每次处理Batch中的记录时才会更新,后四字节为当前Batch中的记录数,对应rep_[8]到rep_[11];
通过头部我们就可以知道每一个batch的序号了,并能够知道每一个batch中的记录数,将batch写入到文件中后就可以方便的依次获取每一条记录了。
后面的记录结构为: 插入数据时:type(kTypeValue、kTypeDeletion),Key_size,Key,Value_size,Value 删除数据时:type(kTypeValue、kTypeDeletion),Key_size,Key
3. WriteBatch的基本操作
WriteBatch的基本操作是记录一个要插入或删除某个数据的操作,最基本的操作就是Put和Delete
Put:将一条要插入数据的操作写入到rep_中
void WriteBatch::Put(const Slice& key, const Slice& value) {
WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1); //操作总数加1 rep_.push_back(static_cast<char>(kTypeValue)); //写入操作类型 PutLengthPrefixedSlice(&rep_, key); //写入key.size()和key.data() PutLengthPrefixedSlice(&rep_, value); //写入value.size()和value.data()
}
Delete:将一条要删除数据的操作写入到rep_中
void WriteBatch::Delete(const Slice& key) { WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1); //操作总数加1 rep_.push_back(static_cast<char>(kTypeDeletion)); //写入操作类型 PutLengthPrefixedSlice(&rep_, key); //写入待删除数据的key值}
4. 基本示例
WriteBatch wb; wb.Put("key1","hello"); wb.Put("key2","hi"); wb.Delete("key1");
执行上面的代码后,WriteBatch中的rep_如下:
10000000 3000 (前8位为序列号,从1开始,后4位为操作数,共3个操作) 0 4 k e y 1 5 h e l l o (第一个操作,0表示要插入数据) 0 4 k e y 2 2 h i (第二个操作) 1 4 k e y 1 (第三个操作,1表示要删除数据) 共39位--------------------- 作者:禾夕 来源:CSDN 原文:https://blog.csdn.net/u012658346/article/details/45341885 版权声明:本文为博主原创文章,转载请附上博文链接!
[LevelDB] LevelDB之WriteBatch
标签:写入 来替 efi 操作 技术 -- 同步 pac void
小编还为您整理了以下内容,可能对您也有帮助:
java leveldb
java leveldb是什么,让我们一起了解一下?
Leveldb是一个google实现的非常高效的kv数据库, Leveldb高效的kv数据,提供较高性能的本地存储(持久化)的功能,可为应用提供嵌入式的数据存储工作。
使用LevelDB它的特点和局限性是什么?
特点:LevelDB 是单进程的服务,性能非常之高,在一台4核Q6600的CPU机器上,每秒钟写数据超过40w,而随机读的性能每秒钟超过10w。 此处随机读是完全命中内存的速度,如果是不命中速度大大下降。
局限:LevelDB 只是一个 C/C++ 编程语言的库,不包含网络服务封装,所以无法像一般意义的存储服务器(如 MySQL)那样,用客户端来连接它。LevelDB 自己也声明,使用者应该封装自己的网络服务器。
java调用Leveldb是怎么实现的?
因为原生leveldb是基于C++开发,java语言无法直接使用;iq80对leveldb使用JAVA 语言进行了“逐句”重开发,经过很多大型项目的验证(比如ActiveMQ),iq80开发的JAVA版leveldb在性能上损失极少(10%)。对于JAVA开发人员来说,我们直接使用即可,无需额外的安装其他lib。
java maven依赖,代码如下: org.iq80.leveldbleveldb0.7org.iq80.leveldbleveldb-api0.7
java leveldb
java leveldb是什么,让我们一起了解一下?
Leveldb是一个google实现的非常高效的kv数据库, Leveldb高效的kv数据,提供较高性能的本地存储(持久化)的功能,可为应用提供嵌入式的数据存储工作。
使用LevelDB它的特点和局限性是什么?
特点:LevelDB 是单进程的服务,性能非常之高,在一台4核Q6600的CPU机器上,每秒钟写数据超过40w,而随机读的性能每秒钟超过10w。 此处随机读是完全命中内存的速度,如果是不命中速度大大下降。
局限:LevelDB 只是一个 C/C++ 编程语言的库,不包含网络服务封装,所以无法像一般意义的存储服务器(如 MySQL)那样,用客户端来连接它。LevelDB 自己也声明,使用者应该封装自己的网络服务器。
java调用Leveldb是怎么实现的?
因为原生leveldb是基于C++开发,java语言无法直接使用;iq80对leveldb使用JAVA 语言进行了“逐句”重开发,经过很多大型项目的验证(比如ActiveMQ),iq80开发的JAVA版leveldb在性能上损失极少(10%)。对于JAVA开发人员来说,我们直接使用即可,无需额外的安装其他lib。
java maven依赖,代码如下: org.iq80.leveldbleveldb0.7org.iq80.leveldbleveldb-api0.7