漫谈RocksDB(一)简介——家有美女初长成,一朝成名天下知

1,953 阅读9分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

经过一段时间的锻炼和适应,加上前段时间的知识整理以及阅读反馈,笔者感觉在未来一段时间内可能会针对某些知识点发布专题。

之前的模式可以帮助大家梳理很多知识点,增加大家的知识广度。但是凡事都有两面性,有利就会有弊,大家在了解了很多零散的知识点后,无法将知识点串联起来形成知识链,就无法很好的转化为生产力,所以基于此以后发文会将专题知识群以及散文知识点结合起来共同推进,希望能给大家带来实质帮助。

接下来的一段时间内就先拿RocksDB来试试手,看看专题的效果如何。另外每个章节的标题会加一句应景的词句或者诗句,给枯燥严谨的技术文章增加点文艺气息,希望大家会喜欢!

正文

Why RocksDB

说到RocksDB很多人可能会感觉到陌生,但是如果你是NoSql领域的从业者或者爱好者,那你肯定或多或少听说过这个数据库。一来是因为这个数据库“家世显赫“,二来是因为这个数据库已经被国内很多的数据库厂商拿来做底层数据存储,并基于该数据库扩展各种各样的应用,下面将会详细说明。

家世显赫的富家大小姐

RocksDB出身显赫,父母皆是呼风唤雨的人物,还有一个牛逼的老师。下面来介绍下RocksDB的家庭情况:

老妈levelDB

老妈是Google的levelDB,Google是超级豪门我就不多说了,而levelDB的作者则是Google的元老,唯二的十一级Senior Fellow(高级研究员):Jeaf Dean和Sanjay Ghemawat,关于这两位的丰功伟绩我这里就不赘述了,这两位可以算得上是黄金搭档了,绝对是结对编程登峰造极的存在,大家感兴趣的可以去查一下。如果想偷懒也行,我就随便说几个这两位的作品:Mapreduce、BigTable、Spanner、TensorFlow。搞过大数据以及人工智能的肯定都用过或者听说过。

有这样的老妈,RocksDB的起点就是很多人遥不可及的存在。在levelDB源码基础上进行的封装与优化使得RocksDB青出于蓝而胜于蓝,在遗传了老妈所有优点的前提下又有了很多新的突破,这个暂且不表,下文详细说明。

老爸FaceBook

提到"非死不可",大家都会想到扎克伯格和脸书,这个我就不过多介绍了,美国互联网新贵,已经成为漂亮国举足轻重的科技公司,技术能力毋庸置疑,经过“老爸”和“老妈”的共同努力下,一个漂亮的大美女就诞生了。

老师HBase

提到HBase,前文已经讲了很多关于HBase的知识了,这是第一代分布式NOSQL数据库的代表,是上文Google二老的作品BigTable的开源实现,作者是Doug Cutting,另一位大数据大神,现任Apache基金会董事长,Apache基金会的开源项目遍布我们编程工作的每个角落,也是他基于Google的论文中Mapreduce、BigTable的模型进行了开源实现,才有了今天的Hadoop以及HBase。

所以在这个老师的帮助和教育下,RocksDB发展突飞猛进,功能也日臻完善。

综上,在父母优良基因的加成下,在HBase这个名师的悉心指导下,一个新星就冉冉升起了。让我想起了一句古话:“家有美女初长成”,但是下一句却不是待字闺中无人知,而是一朝成名天下知!

What RocksDB

上面介绍了RocksDB的出身以及血统,下面就来详细介绍一下RocksDB。

RocksDB简介

RocksDB是FaceBook起初作为实验性质开发的一个高效数据库软件,旨在充分实现快存上存储数据的服务能力。

RocksDB是一个c++库,可以用来存储keys和values,且keys和values可以是任意的字节流,支持原子的读和写。

除此外,RocksDB深度支持各种配置,可以在不同的生产环境(纯内存、Flash、hard disks or HDFS)中调优,支持不同的数据压缩算法、和生产环境debug的完善工具。

RocksDB的主要设计点是在快存和高服务压力下性能表现优越,所以该db需要充分挖掘Flash和RAM的读写速率。

RocksDB需要支持高效的point lookup和range scan操作,需要支持配置各种参数在高压力的随机读、随机写或者二者流量都很大时性能调优。

介绍完RocksDB后,我们来回答下上面的问题:

RocksDB比老妈levelDB哪里更优秀

首先先看一下levelDB的特点:

  1. LevelDB是一个持久化存储的KV系统,和Redis这种内存型的KV系统不同,LevelDB不会像Redis一样狂吃内存,而是将大部分数据存储到磁盘上。
  2. LevleDB在存储数据时,是根据记录的key值有序存储的,就是说相邻的key值在存储文件中是依次顺序存储的,而应用可以自定义key大小比较函数。
  3. LevelDB支持数据快照(snapshot)功能,使得读取操作不受写操作影响,可以在读操作过程中始终看到一致的数据。
  4. LevelDB还支持数据压缩等操作,这对于减小存储空间以及增快IO效率都有直接的帮助。

RocksDB在继承了老妈所有优点的前提下又发展出了自己的很多特点,这些特点有的是弥补老妈身上的缺点,有的则是从老师HBase那里学到的更好的方法:

  1. 增加了column family,这样有利于多个不相关的数据集存储在同一个db中,因为不同column family的数据是存储在不同的sst和memtable中,所以一定程度上起到了隔离的作用。
  2. 采用了多线程同时进行compaction的方法,优化了compact的速度。
  3. 增加了merge operator,优化了modify的效率。
  4. 将flush和compaction分开不同的线程池,能有效的加快flush,防止stall。
  5. 增加了对write ahead log(WAL)的特殊管理机制,这样就能方便管理WAL文件,因为WAL是binlog文件。

Where RocksDB

上面介绍了RocksDB的一些特点,下面通过关键词来看看RocksDB的使用场景。

KV数据库

说到KV数据库,大家第一反应肯定都是redis;再加上高效的point lookup和range scan,我们又想到了RocksDB的老师HBase。那么问题来了,既然RocksDB的特点redis以及HBase都具备一些,那为什么还需要有RocksDB呢?换句话说,RocksDB相对这两者有什么优势呢?

首先来看redis,redis是纯内存式KV数据库,读写效率非常的高,有点很明显,但是缺点同样的明显。和本文讨论相关的主要有两个方面:

  • 成本过高:由于redis所有的数据都存在内存中,考虑到内存的成本,所以大部分场景下都是将热数据放在内存中进行毫秒级查询,冷数据放在NOSQL或者SQL中进行亚秒级或者秒级查询。所以redis不适合做全量的KV存储和查询(土豪除外,毕竟钱能解决的问题都不是问题
  • 事务功能不完善:虽然redis在一定程度上支持事务以及数据的ACID,但是redis不支持rollback,在某些场景下没办法满足客户的需求

再来看看HBase老师,RocksDB和HBase在很多机制上如出一辙,HBase的功能更丰富,但是HBase在某些场景下却不如RocksDB:

  • 框架过重:HBase的功能丰富带来的另外一个副作用就是框架过重,资源占用量过大,对于某些资源有限只想使用高速KV读写的场景来说,RocksDB可能是更好的选择
  • GC之觞:HBase是用java实现的,java应用肯定就绕不过GC,服务可能就会出现毛刺的情况,虽然说新版本的GC配置已经策略让HBase在应对GC问题上已经可以算得上游刃有余,但是GC带来的影响总还是挥之不去的

嵌入式数据库

嵌入式数据库给RocksDB的好处就是不需要单独部署,随应用程序一起部署即可,节省资源且便于管理。但是RocksDB内部没有设计成C/S网络结构,必须和服务部署在同一台服务器。这也限制了RocksDB的使用场景。当前业界一般有两种使用方式:

  • 直接作为单机版KV数据库引擎使用,这种使用方式直接使用开源的RocksDB实现即可。当前比较成熟的实现就是flink采用RocksDBStateBackend来存储状态。如果你对flink的增量checkpoint感兴趣,那RocksDBStateBackend将会是你的唯一选择。
  • 在实际的分布式场景中,可以将Rocksdb作为数据存储系统引擎,在其上面实现分片和多副本,从而实现一个真正的分布式存储系统,以Rocksdb作为其某个副本的存储介质,上层通过Paxos或者Raft协议来保证副本之间的数据一致性。现有的案例有:PingCAP的TiKV,360的pika, zeppelin以及欧若数网的Nebula Graph等。

最后用一张图来表示下RocksDB的血统与社会关系网络,帮助大家了解RocksDB的地位。

总结

总的来说,RocksDB可以作为内嵌式数据库来使用,也可以作为自研数据库的底层存储引擎来使用,其数据结构是LSM tree,保证了读写效率。

RocksDB自从出现到现在时间并不算久,但是其嵌入式的特点以及KV高吞吐的存储特点使得其在很多场景下都能有很好的适用性和扩展性。由此可见,在不久的将来,RocksDB的应用还会进一步扩大,花费一些时间了解下RocksDB的特点以及使用还是很值得的。磨刀不误砍柴工,当你磨好这把刀以后,剩下的就是使用它驰骋疆场建功立业了。