初识:LevelDB

上篇文章缘起:BigTable可以说是已经把论文Bigtable: A Distributed Storage System for Structured Data中的内容掰扯的明明白白,如果哪位小伙伴感觉还有不理解的点,可以点连接进去再反复琢磨几遍,说不定就顿悟了呢~

之所以先花时间把BigTable掰扯了一篇,就是为了引出今天的主人公,LevelDB,接下来呢,我会一点点分享自己阅读LevelDB源码遇到的问题和学习到的一些技术,希望大家多多关注,如有问题,也请大家多多留言,一起学习,一起Happy~

LevelDB是个啥?

LevelDB是对BigTable中KV存储分片Tablet的高度复刻,是由Jeff DeanSanjay Ghemawat,这两位大牛也是BigTable论文的作者,尽管我们不能对BigTable的底层实现一探究竟,不过,开源的LevelDB还是可以让我们对其管中窥豹呢~

简而言之,LevelDB就是一个由Google开源的高效的单机Key/Value存储系统,该存储系统提供了Key到Value的有序映射。

LevelDB有啥特点

  • LevelDB中Key/Value可以是任意长度的字节数组
  • LevelDB中的数据是按Key有序存储的,也就是说,范围查询效率会很高
  • LevelDB支持用户提供自定义Key排序规则
  • 与其他KV存储系统类似,提供Put(key, value)Get(key)Delete(key)这些基本操作
  • LevelDB支持在一个原子批量操作中对同一个Key执行多次修改操作
  • LevelDB通过瞬时快照(Transient Snapshot)为用户提供一致的数据视图
  • LevelDB支持数据的前向/后向迭代遍历
  • LevelDB底层使用Snappy压缩算法自动对数据进行压缩
  • LevelDB将外部活动(例如,文件系统操作)抽象为虚拟接口,为用户自定义这些操作系统交互方式提供了便利,也就是说,用户可以自定义底层到底是与Linux系统交互,还是与Windows系统交互,甚至于HDFS/GFS等分布式文件系统~

LevelDB有哪些限制

  • LevelDB不是SQL数据库,不存在关系数据模型,也不支持SQL查询,同样不支持索引
  • 给定LevelDB数据库,同一时刻,该数据库只能由单进程(可能是多线程)访问
  • LevelDB库本身不是基于C/S(Client/Server)模型的,也就是说,如果你想要像MySQL等各种其他数据库那样,通过客户端连接远程服务器的方式访问LevelDB的话,那么,你需要自己将LevelDB包装成服务端,然后再实现相应的客户端才可以

这部分呢,先简单介绍了LevelDB的特性以及使用限制,其实呢,也从侧面给出了LevelDB的使用场景,比较适合单机KV存储。

LevelDB快速上手

ε=(´ο`*)))唉、其实呢,我现在的主语言是Java,并不是C/C++,太久不用C/C++了,如果有啥错误,各位看官多多提点~

Windows下LevelDB从入门到放弃

Windows下编译LevelDB太恶心了,TM有毒,放弃了、我只是想编译调试下而已,各种拦路虎,算了,爱谁谁,真心感觉Windows下除了他自家的全家桶外,别的都不好用,就TM有毒,真是服气了,不搞了,想在Windows下用LevelDB的,自己掂量着办~

Linux下LevelDB快乐地玩耍

LevelDB编译安装

相比于Windows下LevelDB的编译,Linux环境下简直不要太友好,唯一的缺点就是,用Idea用习惯了,调试有点不太在行~

[root@cos leveldb-1.22]# mkdir -p build && cd build
# 注意:为了调试时可以进入LevelDB库源码,这里最好编译成Debug版本
# 编译成Debug版本
[root@cos build]# cmake -DCMAKE_BUILD_TYPE=Debug .. && cmake --build .
# 编译成Release版本
[root@cos build]# cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build .
# 将链接文件拷贝到/usr/local/lib目录下,以便程序调用
[root@cos build]# cp libleveldb.a /usr/local/lib/
# 将头文件拷贝到/usr/local/include中,以便程序引用
[root@cos leveldb-1.22]# cp -r include/leveldb/ /usr/local/include/

LevelDB测试代码

#include <cassert>
#include <iostream>
#include <string>
#include <leveldb/db.h> int main() { leveldb::DB* db;
leveldb::Options options; // 配置项:如果LevelDB数据库目录不存在,则自动创建
options.create_if_missing = true; leveldb::Status status = leveldb::DB::Open(options, "/root/testdb", &db); assert(status.ok()); std::string key = "apple";
std::string value = "Apple"; // 将key/value键值对写入LevelDB数据库
leveldb::Status s = db->Put(leveldb::WriteOptions(), key, value); std::string get;
// 写入成功后,尝试根据key进行检索
if(s.ok()) {
s = db->Get(leveldb::ReadOptions(), key, &get);
}
if(s.ok()) {
std::cout << "读取到Key=" << key << "对应的Value=" << get << "." << std::endl;
} else {
std::cout << "读取失败!" << std::endl;
} delete db; return 0;
}

编译并执行程序,结果如下:

# 对main.cc源文件进行编译
[root@cos leveldb]# g++ -o main main.cc -pthread -lleveldb -std=c++11
# 执行main可执行程序
[root@cos leveldb]# ./main
读取到Key=apple对应的Value=Apple.

Linux下C/C++代码调试

额(⊙o⊙)…前面说了,我不是做C/C++开发的,Linux是最小化安装的,想调试下代码,难为死我了,高手直接跳过就好~

GDB基本介绍

诸如GDB等代码调试器的无外乎两种功能:

  • 帮助程序员看到程序执行时内部到底是个啥样
  • 帮助程序员知道其程序崩溃时程序正在干啥

基本上每种语言都有代码调试器,而调试器的功能也无非就上面说的这两种功能。

GDB能做的事情,大概可以分为四类,这四类功能可以帮助程序员快速定位Bug。

  1. 启动应用程序,同时指定可能影响程序的参数
  2. 在指定条件下停止程序(断点)
  3. 检查程序停止时到底发生了计算(获取程序执行到断点时的状态信息)
  4. 修改程序中的内容,使得程序员可以尝试纠正Bug的影响,从而继续调试代码

通过Shell命令gdb可以启动GDB,一旦GDB启动成功,程序员就可以不断地在终端中输入命令来告知GDB下一步要干嘛,如果想要终止的话,则需要输入quit命令。

用户可以执行gdb命令的同时不输入任何参数,但是,大多数场景下,用户会输入1到2个参数,如下所示。

# 将可执行程序作为参数,程序编译时需要添加-g参数
gdb program
# 将可执行程序以及core文件作为参数
gdb program core
# 如果想要调试正在运行的进程,则需要将进程ID作为第二个参数
gdb program 1234
gdb -p 1234

GDB常用命令

这里只是介绍一些常用的GDB命令,更多的话,大家去看man gdb文档吧

break [file:]functiop:在指定文件[file]functiop方法入口设置断点

run [arglist]:启动程序,参数列表为arglist

bt:Backtrace: 显示程序栈

print expr:计算表达式expr的结果

c:继续执行程序,直到遇到下一个断点

next:执行下一行(除非遇到断点);也就是说,该命令无论下一行调用多少方法,会直接跳过,除非函数内部有断点

edit [file:]function:查看指定文件中的方法的断点信息

list [file:]function:列出当前断点附近的代码

step:执行下一行代码,如果该行代码有方法调用则进入该方法

help name:展示GDB的name命令的帮助信息。

注意:上面命令中,next缩写为nstep缩写为s,分别是按行调试和单步调试,还有c命令,都是非常常用的~

LevelDB代码调试样例

# 对main.cc源文件进行编译,同时加入调试信息,后续可以使用gdb进行调试
[root@cos leveldb]# g++ -o main main.cc -pthread -lleveldb -std=c++11
# 使用gdb对main进行调试
[root@cos leveldb]# gdb -tui main

注意:为了调试方便,最好使用-tui参数,这样的话,调试时,就可以像Idea那样,边看代码边加断点了~

调试时,大概就是下图的样子~

注意:如果在编译LevelDB时未指定为Debug版本,则无法像图2那样进入到LevelDB源码。

初识:LevelDB小结

其实吧,LevelDB的核心源码及架构,我已经看的七七八八了,就是,本身我主语言是Java的,然后,我就一直没有勇气去Debug到源码中仔细瞅一瞅,趁着这次梳理的机会,打算一点点跟进去看看、可能会更新的有点慢,不过,好事多磨,希望大家多多关注,同时也欢迎各位C/C++大佬多多指正,多多交流。

另外,大家可以关注我的微信公众号,博客会同步更新的哟~

白嫖多不好,关注下再走呗~

最新文章

  1. SSH整合简述一
  2. mongodb3.03开启认证
  3. 使用WITH AS 的ROW_NUMBER分页
  4. JVM 运行时内存结构
  5. ASP.NET Web - 开篇
  6. URAL 2037 Richness of binary words (回文子串,找规律)
  7. Linux环境下使用JFS文件系统
  8. 为 IIS 7.0 配置 &lt;system.webServer&gt;
  9. Java实现串口通信的小样例
  10. .NET Core 如何使用Session
  11. mongodb 添加字段并设置默认值
  12. Xamarin Essentials教程使用指南针Compass
  13. JavaBean是什么,POJO是什么
  14. 【转】Python之数据序列化(json、pickle、shelve)
  15. spring boot 中统一异常处理
  16. 用C语言操作MySQL数据库,进行连接、插入、修改、删除等操作
  17. sql左右连接测试
  18. Thinking in Java 之classpath理解
  19. RAC3——RAC原理开始
  20. web开发中兼容性问题(IE8以上含)持续更新~~

热门文章

  1. MFC_VC++_时间获取与保存列表控件内容到文件操作方法
  2. cb14a_c++_顺序容器的操作7_赋值与交换(swap)_vector转list
  3. S7-1200视频教程: S7-1200的功能与特点-跟我做 - 2/112
  4. JDBC——使用JDBC连接MySQL数据库
  5. CSV文件导入到数据库中读取数据详解(接着上个帖子)
  6. Spring中的JDBC API
  7. vue 开发环境的搭建
  8. 观察者模式(Observer Pattern)(二):HeadFirst中的气象站的实现
  9. 微信小程序navigator带参数跳转及接收参数内容
  10. Spring—容器外的Bean使用依赖注入