LevelDB 入门 —— 全面了解 LevelDB 的功能特性

  • 时间:
  • 浏览:2
  • 来源:5分排列3APP下载_5分排列3APP官方

LevelDB 的磁盘文件是分层存储的,它会先去 Level 0 查找,可是 找也能继续去 Level 1 去找,总爱递归到最底层。全都可是 你去找一另另一个不占据 的 key,就需要全都次磁盘文件读操作,会非常耗费时间。而布隆过滤器需要帮你省去95%以上的磁盘文件搜寻的时间。

布隆过滤器

内存读 miss 意味着 磁盘搜寻是一另另一个比较耗时的操作,LevelDB 为了进一步减少磁盘读的次数,在每个磁盘文件上又加了一层布隆过滤器,它需要消耗一定的磁盘空间,可是 在效果上需要直接将磁盘读次数大幅减少。布隆过滤器的数据存储在磁盘文件中数据块的后面 。

安全写(同步写)

了解 Redis 的同学都知道它的 AOF 写策略有多种配置,取决于日志文件同步磁盘的频率。频率越高,遇到宕机时丢失的数据就越少。操作系统要将内核中文件的脏数据同步到磁盘需要进行磁盘 IO,这会影响访问性能,全都通常全是会同步的太频繁。

快照我我觉得很神奇,可是 实际上它的原理非常简单,你你这俩你这俩人后文再深入讲解。

原文发布时间为:2019-1-3

本文作者: 佬钱

本文来自云栖社区合作妙招妙招 伙伴“ 码洞”,了解相关信息需要关注“codehole”微信公众号

自定义比较器很危险,谨慎使用。比较算法设置不当,会严重影响到存储速度。可是 我我觉得需要要改变排序规则,那就需要提前规划,这里会有一另另一个很重的小技巧,理解它需要了解磁盘存储的细节,全都你这俩人后续再仔细探讨。

打开数据库有全都选项需要配置,比如设置块缓存大小、压缩等

块不宜过小低于 1k,可是 宜过大设置成了好几 M,曾经过激的设置不言而喻会给性能带来多大的提升,反而会大幅增加数据库在不同的读写场合的性能波动。你这俩人要取舍中庸之道,在默认块大小俯近浮动。块大小一经初始化就不可再次更改。

基础 API

LevelDB 用起来就像 HashMap,可是 比 HashMap 要稍微弱你这俩,可是 put 妙招也能返回旧值,delete 操作也告诉我对应的 key 是是不是真的占据 。

小结

经过了你你这俩节的学习,同学们应该需要在脑海中形成下面曾经一张概念图。图中的「热数据」是指最近被修改的键值对,这后面 的键值对读取速度是最为快速的。可是 热数据中读取也能,就会去块缓存中读取。可是 还读也能,就分某种 清况 ,某种 是真的不占据 ,曾经种是占据 于磁盘上。可是 占据 于磁盘上,经过有限层次读取就读取到了,通常越冷的数据越在底层。如岂全是的不占据 就要经过布隆过滤器来大幅减少磁盘搜寻 IO,布隆过滤器的数据和键值对数据一齐放在分层的数据文件中。

默认布隆过滤器那末打开,需要在打开数据库的你会设置 filter_policy 参数才需要生效。布隆过滤器是减少磁盘读操作的最后一层堡垒。布隆过滤器内内外部的位图数据会存储在磁盘文件中,可是 使用是会缓占据 内存后面 。

本节你这俩人将全面了解一下 LevelDB 的各种形态。LevelDB 的开发语言是 C++,考虑到会使用 C++ 语言的同学全是全都,在本节你这俩人将使用 Java 语言来描述 LevelDB 的形态。其它语言栈的同学可是 必担心,可是 不同语言操纵 LevelDB 的接口 API 全是一样的,使用起来大同小异。

打开和关闭

LevelDB 的数据存储在一另另一个特定的目录中,后面 有全都数据文件、日志文件等。使用 LevelDB API 来打开你你这俩目录,就得到了 db 的引用。后续你这俩人就使用你你这俩 db 引用来执行读写操作。下面的代码是 Java 语言描述的伪代码。

可是 对应的指纹需要在集合里找到,这不言而喻能取舍它就一定占据 。可是 不同的 Key 可是 会生成同样的指纹,这可是 布隆过滤器的误判率。误判率越低需要的 Key 指纹信息太少,对应消耗的内存空间也就越大。

在使用布隆过滤器时,你这俩人需要在内存消耗和性能之间做一另另一个折中取舍。可是 你想深入理解布隆过滤器的原理,需要去看《Redis 层厚历险》,后面 有一另另一个单独的章节专门讲解布隆过滤器的内内外部原理。

压缩

LevelDB 的磁盘存储默认是开启压缩的,是业界常用的 Snappy 算法,压缩速度非常高,全都我太少 担心性能损耗间题。可是 你你会使用压缩,也需要动态关闭。关闭压缩开关通常我太少 带来明显的性能提升,全都你这俩人尽可是 不言而喻去动它。

打开数据库时默认那末开启强制校验选项,可是 开启了,在遇到校验错误时就会报错。可是 数据真的冒出了间题,LevelDB 还提供了修复数据的妙招 repairDB() 需要帮你这俩人恢复尽可是 多的数据。

原子批处理

对于多个连续的写操作可是 可是 宕机有可是 意味着 这多个连续的写操作只完成了一偏离 。为此 LevelDB 提供了批处理功能,批处理操作就好比事务,LevelDB 确保你你这俩些列写操作的原子性执行,要么详细生效要么详细不生效。

并发

LevelDB 的磁盘文件会放在一另另一个文件目录中,后面 有全都相关的数据和日志文件。它不支持多tcp连接一齐打开你你这俩目录来使用 LevelDB API 进行读写访问。可是 对于同一另另一个tcp连接 LevelDB API 是支持多tcp连接安全读写的。LevelDB 内内外部会使用特殊的锁来控制并发操作。

布隆过滤器例如于一另另一个内存 Set 形态,它后面 存储了指定磁盘文件一定范围内所有 Key 的指纹信息。当它发现某个 key 的指纹在 Set 集合里找也能,它就需要断定你你这俩 key 肯定不占据 。

遍历

LevelDB 中的 Key 全是有序的,按照字典序从小到大整齐排列。LevelDB 提供了遍历 API 需要逐个顺序访问所有的键值对,需要指定从后面 结速遍历。

块缓存

LevelDB 的内存中存储了一笔最近读写的热数据,可是 请求的数据在热数据中查也能就需要去磁盘文件中去查找,速度就会大幅降低。LevelDB 为了降低磁盘文件的搜寻次数,增加了块缓存,缓存了近期频繁使用的数据块解压缩你会的内容。

数据校验

LevelDB 有严格的数据校验机制,它将校验的单位精确到了 4K 字节的数据块。校验和会浪费你这俩存储空间和计算时间,可是 在遇到数据块损坏需要要较为精确地恢复健康的数据。

数据块

LevelDB 的磁盘数据是以数据库块的形式存储的,默认的块大小是 4k。适当提升块大小将促进批量大规模遍历操作的速度,可是 随机读比较频繁,这你会块小点性能又会稍好,这就要求你这俩人当事人去折中取舍。

那末即使宕机占据 了,数据库启动需要要通过日志文件来恢复。

LevelDB 也是例如的,可是 使用前面的非安全写,我我觉得 API 调用成功了,可是 遇到宕机间题,有可是 对应的操作日志会丢失。全都它提供了安全写操作,代价可是 性能会变差。

在安全和性能之间往往需要折中,全都通常你这俩人会定时若干毫秒可是 每隔若干写操作使用一次同步写。曾经需要在兼顾写性能的一齐尽量少丢失数据。

自定义 Key 比较器

LevelDB 的 key 默认使用字典序,不过它也提供了自定义排序规则。你会自定义一另另一个排序函数注册进去,比如按数字排序。需要尽可是 确保排序规则在整个数据库生命周期内保持不变,可是 排序会影响到磁盘键值对的存储顺序,磁盘存储顺序是无法动态改变的。

默认块缓存不开启,打开数据库需要要手动设置选项。块缓存会占据 一偏离 内存,不过这通常需要设置太少,1000M 左右就差太少了,再大你这俩速度提升的可是 明显了。

还需要注意遍历操作对缓存的影响,为了处理遍历操作将全都冷门数据刷到块缓存中,需要在遍历的你会设置一另另一个选项 fill_cache,它用来控制磁盘遍历的数据块有我太少 要同步到缓存。

日志文件

当你这俩人调用 LevelDB 的 put 妙招往库里写数据时,它会先将数据记录到内存中,延后再通过某种 特殊的策略持久化到磁盘。这就占据 一另另一个间题,可是 突发宕机,哪几个来不及写到磁盘的数据就丢失了。全都 LevelDB 也采用了和 Redis AOF 日志例如的策略,先讲修改操作的日志写到磁盘文件中,再进行实际的写操作流程处理。

可是 布隆过滤器能准确知道某个 Key 是是不是占据 ,那就不占据 误判了,这你会也就我太少 占据 白白浪费的磁盘读操作。曾经的极限形式的布隆过滤器可是 HashSet —— 内存里存储了所有的 Key,当然内存空间自然是无法接受的。

快照隔离

LevelDB 支持多tcp连接并发读写,这意味着 连续的另另一个同样 key 的读操作读到的数据可是 不一样,可是 另另一个读操作后面 数据可是 被其它tcp连接修改了。这在数据库理论中称为「重复读」。LevelDB 提供了快照隔离机制,在同一另另一个快照范围内保证连续的读写操作不受其它tcp连接修改操作的影响。