zoukankan      html  css  js  c++  java
  • 初识:LevelDB

    初识: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++大佬多多指正,多多交流。

    另外,大家可以关注我的微信公众号,博客会同步更新的哟~
    白嫖多不好,关注下再走呗~

  • 相关阅读:
    【MongoDb入门】15分钟让你敢说自己会用MongoDB了
    【干货】基于Owin WebApi 使用OAuth2进行客户端授权服务
    【学习】在Windows10平台使用Docker ToolBox安装docker(一)
    快速搭建WebAPI(Odata+Code-First)附Odata条件查询表~
    使用QuertZ组件来搞项目工作流(一)
    AspNetCore 使用NLog日志,NLog是基于.NET平台开的类库!(又一神器)
    AspNetCore 基于流下载文件与示例代码
    再见了Server对象,拥抱IHostingEnvironment服务对象(.net core)
    AspNetCore 文件上传(模型绑定、Ajax) 两种方式 get到了吗?
    AspNetCore 目前不支持SMTP协议(基于开源组件开发邮件发送,它们分别是MailKit 和 FluentEmail )
  • 原文地址:https://www.cnblogs.com/yizhiweiyan/p/13303056.html
Copyright © 2011-2022 走看看