图解|什么是高并发利器NoSQL( 三 )


图解|什么是高并发利器NoSQL文章插图
LevelDB具有很高的随机写 , 顺序读/写性能 , 因此LevelDB很适合应用在写多读少的场景 , 真让人好奇高性能的随机写怎么做到的 。
5.1.1 LSM树
很多数据在逻辑上相近 , 但是在物理存储上却可能相隔很远 , 这样就会造成大量的随机读写问题 , 从而降低性能 。
LevelDB实现高性能随机写的秘密武器在于使用LSM树存储结构 , LSM树又称为日志结构合并树(Log-Structured Merge-Tree) , 它并不是具体的数据结构 , 而是一种设计思想 。
LSM树对于每次写入操作 , 并不是直接将最新的数据驻留在磁盘中 , 而是将数据先放在内存 。
当内存数据达到一定的阈值 , 再将这部分数据真正刷新到磁盘文件中 , 从而将磁盘随机写转换为内存顺序写 , 因而获得了极高的写性能 , 但是这种机制会降低读的性能 , 总体来说降低部分读性能来大幅提升写性能是值得的 。
图解|什么是高并发利器NoSQL文章插图
5.1.2 LevelDB整体架构
图解|什么是高并发利器NoSQL文章插图
LevelDB 存储结构主要由六个部分组成:

  • MemTable:内存数据结构 , 使用SkipList实现 , 新的数据修改会首先在这里写入 , 并且有容量限制 。
  • Immutable MemTable:待落盘的数据库内存结构 , 当 MemTable的大小达到设定的阈值时 , 会变成 Immutable MemTable , 只接受读操作 , 不再接受写操作 , 后续会Flush到磁盘上 。
  • SST Files:Sorted String Table Files , 磁盘数据存储文件 , 分为 Level0 到 LevelN 多层 , 每一层包含多个 SST 文件 , 文件内数据有序 。
  • Manifest Files:leveldb元信息清单文件 。 Manifest记录 SST 文件在不同 Level 的分布 , 相当于SST文件的索引 。
  • Current File:当前正在使用的文件清单文件 。
LevelDB的读写过程和上述的整体架构关系密切 , 也是先内存后磁盘 , 一层层读取搜索数据的 。
5.2 脸书出品RocksDB
青出于蓝而胜于蓝 。
RocksDB在LevelDB的基础上进行了改进和优化 , 也成为后续很多NoSQL所选择的存储引擎 。
RocksDB仍然是采用C++开发的 , 并且完全向后兼容了LevelDB的接口 , 可以说是个平滑升级 。
5.2.1 RocksDB提升点
来看看RocksDB做了哪些优化和提升:
  • RocksDB支持一次获取多个Key , 还支持Key范围查找 , LevelDB只能获取单个Key 。
  • RocksDB支持多线程合并 , 而LevelDB是单线程合并的 , 多核时代前者效率更高 。
  • RocksDB增加了合并时过滤器 , 对不符合条件的Key进行丢弃 。
  • RocksDB可采用多种压缩算法 , 除了LevelDB用的snappy , 还有zlib、bzip2 。
  • RocksDB支持增量备份和全量备份 。
RocksDB支持管道式的Memtable , 使用多个Memtable , LevelDB只有一个Memtable 。
图解|什么是高并发利器NoSQL文章插图
5.2.2 RocksDB整体架构
Rocksdb中引入了Column Family(列族的概念 , 所谓列族也就是一系列kv组成的数据集 , 所有的读写操作都需要先指定列族 。
每个ColumnFamily有自己的Memtable ,SST文件 , 所有ColumnFamily共享WAL、Current、Manifest文件 。
图解|什么是高并发利器NoSQL文章插图
如果说LevelDB是个平民版的NoSQL存储引擎 , 那么RocksDB绝对是尊享版 , 所以很多优秀的NoSQL成品都是基于RocksDB来封装上层协议和代理支持完成的 。


推荐阅读