暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

[LevelDB] 开篇:初学乍练——LevelDB初识

LevelDB 2021-07-14
2173

开篇:初学乍练——LevelDB初识


LevelDB实际上不是一个功能完备的数据库,而只是一个数据库函数库,提供了接口来操作数据库。LevelDB的代码只有1万多行,精致优雅,可读性高,是LSM Tree的一种实现方式,值得学习。

LevelDB非常简单,实际工程中使用不多,一般会选择RocksDB,它对LevelDB进行了改进,比LevelDB更加强大,比如TiDB就使用了RocksDB作为了底层存储引擎。但是LevelDB技术架构更加简单清晰易于理解,非常适合学习使用。

本系列将介绍LevelDB的内部实现,包括源码分析、工作原理,通过这个系列的学习,可以了解LSM Tree的一些概念,一种实现方式,了解LevelDB的工作原理。

本系列分为4个部分:

  • 概述部分:介绍LevelDB有哪些功能,基本工作原理,编译安装等;

  • 基础部分:介绍LevelDB用到了哪些基础组件,这些组件的实现方式;

  • 存储部分:介绍LevelDB存储数据相关,包括SSTable、MemTable、WAL和Iterator等,重点阐述数据的存储方式;

  • 数据库部分:介绍数据插入、删除和更新接口的实现,以及版本管理和Compaction的实现。

LevelDB的特点

作为一个函数库,LevelDB有以下特点:

  • 键和值都是任意的字节数组;

  • 数据以键的顺序存储;

  • 可以使用定制的比较器定义排序的方式;

  • 基本操作是Put(key,value)
    、 Get(key)
    Delete(key)

  • 一个原子的Batch中可以做多个改变;

  • 支持Snapshot,用户可以建立一个一致性的视图;

  • 可以正向和反向迭代;

  • 支持snappy压缩数据;

  • 操作系统相关操作被抽象,跨平台时可以定制这些接口;

  • 同一时间只能由一个进程访问数据库,但是支持多线程访问。

编译安装函数库

要使用LevelDB,必须先要编译安装函数库。LevelDB使用了cmake,需要安装cmake,可以根据需要,安装snappy、crc32c和tcmalloc。

通过执行以下几个步骤,就可以安装函数库了:

mkdir -p build && cd build
cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build .
make install

写个测试:

// hello.cc

#include <assert.h>
#include <string.h>
#include <leveldb/db.h>
#include <iostream>
using namespace leveldb;

int main(){
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
打开一个数据库,不存在就创建
leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb", &db);
assert(status.ok());

插入一个键值对
status = db->Put(leveldb::WriteOptions(), "hello", "LevelDB");
assert(status.ok());

读取键值对
std::string value;
status = db->Get(leveldb::ReadOptions(), "hello", &value);

assert(status.ok());
std::cout << value << std::endl;

delete db;
return 0;
}

编译执行:

g++ hello.cc -o hello -L. -I./include -lpthread -lleveldb
./hello

用Python来操作LevelDB

LevelDB是一个C函数库,测试的时候,需要使用C编码读取和写入,非常不方便。我们使用一般的数据库的时候,都有shell来操作数据库。好在有Python库可以用来操作LevelDB,达到和shell相同的效果,可以交互式地使用LevelDB。

我们使用plyvel,可以使用pip来安装。

>>> import plyvel
>>> db = plyvel.DB('/tmp/testdb/', create_if_missing=True)
>>> db.put(b'key', b'value')
>>> db.get(b'key')
'value'

这样可以像使用其它数据库一样,交互式地使用LevelDB,非常方便。

项目结构

项目根目录下面有几个主要的目录:

include: 函数库的头文件
port: 可移植性相关的功能
util: 项目用到的一些功能函数
table: SSTable的实现
db: 数据库实现,版本管理,Compaction,WAL和MemTable实现

LevelDB作为函数库,对外提供的接口文件及功能如下:

cache.h: 缓存接口,提供了默认的LRU缓存,也可以自己实现缓存
comparator.h: 定义数据库比较器的接口,用来比较键,可以使用默认的基于字节的比较,可以定义自己的比较器
dumpfile.h: 以可读文本形式导出一个文件,调试使用
export.h: 可移植性相关
iterator.h: 迭代器接口
slice.h: 实现一个字符串,存储指针和长度,指向字符串
table_builder.h: 构造一个SSTable
write_batch.h: 实现批量写入的接口
c.h: 实现C语言相关的接口
db.h: 操作数据库的主要接口
env.h: 定义操作系统相关的功能,如读写文件之类的
filter_policy.h: 定义布隆过滤器接口
options.h: 配置选项
status.h: 定义数据库操作的返回状态
table.h: SSTable相关的接口

小结

这一篇我们简单介绍了LevelDB的特点、编译方式、使用方式和项目结构。

项目结构非常清晰,基本可以望文生义,大家可以先翻翻源代码目录熟悉一下项目的布局以及每个文件的用处,方便以后快速找到源代码。

下一节将会介绍LevelDB的功能特性。


文章转载自LevelDB,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论