LevelDB介绍(非常详细)
从本质上讲,LevelDB 是一个键-值数据库。
键-值数据库主要用于存取、管理关联性的数组。关联性数组又称映射、字典,是一种抽象的数据结构,其数据对象为一个个的 key-value 数据对,且在整个数据库中每个 key 均是唯一的。
20 世纪 80 年代,关系型数据库在软件系统的后端占据绝对统治地位。Oracle、SQL Server 和 DB2 等成熟的商业产品的本质是类似的,均面向结构化的数据,采用 SQL 语言进行相应的查询与事务操作。
然而随着近年来互联网的兴起,云计算、大数据应用越来越广泛,对于数据库来说也出现了一些需要面对的新情况:
在实际应用中,并不是所有环境下的数据都是完整的结构化数据,非结构化数据普遍存在,因此如何实现对灵活多变的非结构化数据的支持是需要考虑的一个问题。
正是在上述情况的催生下,2010 年开始兴起了一场 NoSQL 运动,而键-值数据库作为 NoSQL 中一种重要的数据库也日益繁荣,因此催生出了许多成功的商业化产品,并得到了广泛应用。
键-值数据库可以应用于许多应用场景。例如对于常见的 Web 场景,可以存储用户的个人信息资料、对文章或博客的评论、邮件等。具体到电子商务领域,可以存储购物车中的商品、产品类别、产品评论。键-值数据库甚至可以存储整个网页,其将网页的 URL 作为 key,网页的内容作为 value。不仅如此,键-值数据库还可以用于构建更为复杂的存储系统。
简而言之,键-值数据库给我们提供了一种新的选择,而在实际的软件架构与应用中,究竟是应用键-值数据库,还是使用传统的关系数据库,则需要综合多种因素,由项目架构师最终确定。
Google 在分布式系统领域一直走在当今世界的前沿。早在 2004 年,Google 开始研发一种结构化的分布式存储系统,该分布式存储系统可扩展至 PB 级别的数据和数千台机器,这一系统就是后来风靡全球的 Bigtable。Bigtable 性能强悍,具有高扩展性与高可用性,在 Google 内部已应用到 60 多个产品与项目(截至本文发布时),比如 Google Earth 和 Google Analytics。目前 Bigtable 是公认为的 Google 三大核心技术之一(另外两个分别为 GFS 与 MapReduce)
2006 年,Google 发表了一篇论文——Bigtable: A Distributed Storage System for Structured Data。这篇论文公布了 Bigtable 的具体实现方法(包括基本原理与技术架构),从而揭开了 Bigtable 的技术面纱。Bigtable 虽然也有行、列、表的概念,但不同于传统的关系数据库,从本质上讲,它是一个稀疏的、分布式的、持久化的、多维的排序键-值映射。
虽然 Google 公布了 Bigtable 的实现论文,但 Google 产品中所使用的 Bigtable 依赖于 Google 其他项目所开发的未开源的库,Google 一直没有将 Bigtable 的代码开源。
然而这一切在 2011 年迎来了转机。Sanjay Ghemawat 和 Jeff Dean 这两位来自 Google 的重量级工程师,为了能将 Bigtable 的实现原理与技术细节分享给大众开发者,于 2011 年基于 Bigtable 的基本原理,采用 C++ 开发了一个高性能的键-值数据库——LevelDB。
由于没有历史的产品包袱,LevelDB 结构简单,不依赖于任何第三方库,具有很好的独立性,虽然其有针对性地对 Bigtable 进行了一定程度的简化,然而 Bigtable 的主要技术思想与数据结构均在 LevelDB 予以体现了。因此 LevelDB 可看作 Bigtable 的简化版或单机版。
LevelDB 诞生时,源码托管在 Google 自家的源码管理平台,后来迁移到目前最流行的开源社区 GitHub 上(https://github.com/google/leveldb)。经过多年的发展,LevelDB 已成为 GitHub 上关注人数较多的 C++ 开源项目之一。
截至目前(2021年1月),LevelDB 发布的稳定版为 1.22。在 Google 产品线中,Chrome 浏览器中涉及的 IndexedDB(基于 HTML5 API 的数据库),就是基于 LevelDB 构建而成的。Riak 分布式数据库也采用 LevelDB 作为其节点的存储引擎。
LevelDB 的优点体现在:
LevelDB 的缺点体现在:
读者可以综合 LevelDB 的优缺点,有针对性地评估其是否适用于实际开发的项目/产品,并对最终是否使用进行决定。
正因如此,各知名公司与开发机构,基于 LevelDB 开发了一系列的衍生产品,如 Facebook 开发的 RocksDB、我国开发者基于 LevelDB 开发的类 Redis 的 NoSQL 数据库 SSDB。
RocksDB 设计之初,正值 SSD 硬盘兴起。然而在当时,无论是传统的关系数据库如 MySQL,还是分布式数据库如 HDFS、HBase,均没有充分发挥 SSD 硬盘的数据读写性能。因而 Facebook 当时的目标就是开发一款针对 SSD 硬盘的数据存储产品,从而有了后面的 RocksDB。RocksDB 采用嵌入式的库模式,充分发挥了 SSD 的性能。
RocksDB 兼容 LevelDB 原有的 API,但在开发设计过程中,针对性地对 LevelDB 进行了一系列的优化与完善,具体主要体现在以下几个方面:
RocksDB 适用于对数据存取速度要求高的应用场景,例如:
在 Facebook 内部,RocksDB 已为其大量业务提供服务。Facebook 还将 RocksDB 与 MySQL 进行结合,将 RocksDB 作为 MySQL 的数据引擎,目前这一项目也已开源,有兴趣的读者可访问 https://github.com/facebook/mysql-5.6 了解。
Redis 是一个键-值型内存数据库,其所有数据均在内存中进行操作,因而其数据容易受到内存容量的限制,并且数据不能持久化存储。而 SSDB 不但完全兼容了 Redis 的 API,支持 Redis 客户端的访问,而且提供了与 Redis 一样的集合数据结构,如 list、hash、zset 等。SSDB 底层的数据存储引擎也是基于 LevelDB 开发的,因而实现了数据的持久化存储,且支持的数据容量是 Redis 的 100 倍。
不仅如此,SSDB 还实现了主从同步与负载均衡。可以说,SSDB 是 LevelDB 与 Redis 相结合的产物,其继承了 LevelDB 强大的数据读写性能,也吸取了 Redis 简单易用的操作接口与丰富的数据结构。
SSDB 官网(http://ssdb.io/zh_cn/)公布了其与 Redis 的性能测试对比。在测试中,SSDB 的读性能完全超越了 Redis,而写性能只比 Redis 慢 10%。SSDB 可以将原有的 Redis 数据进行直接迁移。
SSDB 已被数十家公司在多种场景中使用,例如财经类应用用其来存储高速证券行情快照,直播平台用其来存储粉丝关注与在线人数数据、在线广告平台用其来存储实时会话数据、音乐类平台用其来存储专辑封面信息以及评论数据。在这些用户中,许多都是从原来的 Redis 平台迁移而来的,由此可见,SSDB 在性能上的确相当优异,并且可用于许多 Redis 无法胜任的领域。而这一切均归功于底层的数据存储引擎 LevelDB。
本节的目的在于让读者对 LevelDB 有初步的了解,通过本章读者应搞清楚 LevelDB 究竟是什么,其具有的优势与劣势。
键-值数据库主要用于存取、管理关联性的数组。关联性数组又称映射、字典,是一种抽象的数据结构,其数据对象为一个个的 key-value 数据对,且在整个数据库中每个 key 均是唯一的。
20 世纪 80 年代,关系型数据库在软件系统的后端占据绝对统治地位。Oracle、SQL Server 和 DB2 等成熟的商业产品的本质是类似的,均面向结构化的数据,采用 SQL 语言进行相应的查询与事务操作。
然而随着近年来互联网的兴起,云计算、大数据应用越来越广泛,对于数据库来说也出现了一些需要面对的新情况:
- 数据量呈指数级增长,存储也开始实现分布式;
- 查询响应时间要求越来越快,需在 1 秒内完成查询操作;
- 应用一般需要 7×24 小时连续运行,因此对稳定性要求越来越高,通常要求数据库支持热备份,并实现故障下快速无缝切换;
- 在某些应用中,写数据比读数据更加频繁,对数据写的速度要求也越来越高。
在实际应用中,并不是所有环境下的数据都是完整的结构化数据,非结构化数据普遍存在,因此如何实现对灵活多变的非结构化数据的支持是需要考虑的一个问题。
正是在上述情况的催生下,2010 年开始兴起了一场 NoSQL 运动,而键-值数据库作为 NoSQL 中一种重要的数据库也日益繁荣,因此催生出了许多成功的商业化产品,并得到了广泛应用。
键-值数据库可以应用于许多应用场景。例如对于常见的 Web 场景,可以存储用户的个人信息资料、对文章或博客的评论、邮件等。具体到电子商务领域,可以存储购物车中的商品、产品类别、产品评论。键-值数据库甚至可以存储整个网页,其将网页的 URL 作为 key,网页的内容作为 value。不仅如此,键-值数据库还可以用于构建更为复杂的存储系统。
简而言之,键-值数据库给我们提供了一种新的选择,而在实际的软件架构与应用中,究竟是应用键-值数据库,还是使用传统的关系数据库,则需要综合多种因素,由项目架构师最终确定。
LevelDB的诞生过程
LevelDB 是一种为分布式而生的键-值数据库。Google 在分布式系统领域一直走在当今世界的前沿。早在 2004 年,Google 开始研发一种结构化的分布式存储系统,该分布式存储系统可扩展至 PB 级别的数据和数千台机器,这一系统就是后来风靡全球的 Bigtable。Bigtable 性能强悍,具有高扩展性与高可用性,在 Google 内部已应用到 60 多个产品与项目(截至本文发布时),比如 Google Earth 和 Google Analytics。目前 Bigtable 是公认为的 Google 三大核心技术之一(另外两个分别为 GFS 与 MapReduce)
2006 年,Google 发表了一篇论文——Bigtable: A Distributed Storage System for Structured Data。这篇论文公布了 Bigtable 的具体实现方法(包括基本原理与技术架构),从而揭开了 Bigtable 的技术面纱。Bigtable 虽然也有行、列、表的概念,但不同于传统的关系数据库,从本质上讲,它是一个稀疏的、分布式的、持久化的、多维的排序键-值映射。
虽然 Google 公布了 Bigtable 的实现论文,但 Google 产品中所使用的 Bigtable 依赖于 Google 其他项目所开发的未开源的库,Google 一直没有将 Bigtable 的代码开源。
然而这一切在 2011 年迎来了转机。Sanjay Ghemawat 和 Jeff Dean 这两位来自 Google 的重量级工程师,为了能将 Bigtable 的实现原理与技术细节分享给大众开发者,于 2011 年基于 Bigtable 的基本原理,采用 C++ 开发了一个高性能的键-值数据库——LevelDB。
由于没有历史的产品包袱,LevelDB 结构简单,不依赖于任何第三方库,具有很好的独立性,虽然其有针对性地对 Bigtable 进行了一定程度的简化,然而 Bigtable 的主要技术思想与数据结构均在 LevelDB 予以体现了。因此 LevelDB 可看作 Bigtable 的简化版或单机版。
LevelDB 诞生时,源码托管在 Google 自家的源码管理平台,后来迁移到目前最流行的开源社区 GitHub 上(https://github.com/google/leveldb)。经过多年的发展,LevelDB 已成为 GitHub 上关注人数较多的 C++ 开源项目之一。
截至目前(2021年1月),LevelDB 发布的稳定版为 1.22。在 Google 产品线中,Chrome 浏览器中涉及的 IndexedDB(基于 HTML5 API 的数据库),就是基于 LevelDB 构建而成的。Riak 分布式数据库也采用 LevelDB 作为其节点的存储引擎。
LevelDB的特性
LevelDB 是一个 C++ 语言编写的高效键-值嵌入式数据库,目前对亿级的数据也有着非常好的读写性能。虽然 LevelDB 有着许多键-值数据库所不具备的优秀特性,但是与 Redis 等一些主流键-值数据库相比也有缺陷。接下来就对 LevelDB 的优缺点进行具体阐述。LevelDB 的优点体现在:
- key 与 value 采用字符串形式,且长度没有限制;
- 数据能持久化存储,同时也能将数据缓存到内存,实现快速读取;
- 基于 key 按序存放数据,并且 key 的排序比较函数可以根据用户需求进行定制;
- 支持简易的操作接口 API,如 Put、Get、Delete,并支持批量写入;
- 可以针对数据创建数据内存快照;
- 支持前向、后向的迭代器;
- 采用 Google 的 Snappy 压缩算法对数据进行压缩,以减少存储空间;
- 基本不依赖其他第三方模块,可非常容易地移植到 Windows、Linux、UNIX、Android、iOS。
LevelDB 的缺点体现在:
- 不是传统的关系数据库,不支持 SQL 查询与索引;
- 只支持单进程,不支持多进程;
- 不支持多种数据类型;
- 不支持客户端-服务器的访问模式。用户在应用时,需要自己进行网络服务的封装。
读者可以综合 LevelDB 的优缺点,有针对性地评估其是否适用于实际开发的项目/产品,并对最终是否使用进行决定。
LevelDB的衍生产品
尽管 LevelDB 本身具备非常优异的读写性能,然而还有许多需要完善与提高的地方,比如前面介绍过的只支持单实例、单线程操作,不具备相应的客户端访问模式,支持的数据类型不够丰富等。正因如此,各知名公司与开发机构,基于 LevelDB 开发了一系列的衍生产品,如 Facebook 开发的 RocksDB、我国开发者基于 LevelDB 开发的类 Redis 的 NoSQL 数据库 SSDB。
RocksDB
RocksDB(https://github.com/facebook/rocksdb)是基于 LevelDB 开发的,并保留、继承了 LevelDB 原有的基本功能,也是一个嵌入式的键-值数据存储库。RocksDB 设计之初,正值 SSD 硬盘兴起。然而在当时,无论是传统的关系数据库如 MySQL,还是分布式数据库如 HDFS、HBase,均没有充分发挥 SSD 硬盘的数据读写性能。因而 Facebook 当时的目标就是开发一款针对 SSD 硬盘的数据存储产品,从而有了后面的 RocksDB。RocksDB 采用嵌入式的库模式,充分发挥了 SSD 的性能。
RocksDB 兼容 LevelDB 原有的 API,但在开发设计过程中,针对性地对 LevelDB 进行了一系列的优化与完善,具体主要体现在以下几个方面:
- 针对 SSD 硬盘进行优化,支持更多的 IOPS(I/O Operation per Second),并改进数据压缩,减少数据写入,尽可能延长 SSD 的使用寿命。
- 针对多 CPU、多核环境进行优化,从而提升整体性能。一般而言,商用的服务器均采用多核的 CPU,RocksDB 不仅支持多线程合并、多线程内存表的插入,同时采用 MVCC,并将数据库的只读与读写操作分开,减少了锁的使用,从而更适合、进行高并发操作。
- 增加了一系列 LevelDB 不具备的功能,如数据合并、多种压缩算法、按范围查询,以及一些管理统计维护工具。
RocksDB 适用于对数据存取速度要求高的应用场景,例如:
- 垃圾邮件检测应用需要快速获取实时传递的每一封邮件。
- 一个消息队列,需要支持海量的消息插入与删除。
- 作为一个高速缓存,以实现海量数据的实时访问。
在 Facebook 内部,RocksDB 已为其大量业务提供服务。Facebook 还将 RocksDB 与 MySQL 进行结合,将 RocksDB 作为 MySQL 的数据引擎,目前这一项目也已开源,有兴趣的读者可访问 https://github.com/facebook/mysql-5.6 了解。
SSDB
SSDB 是一个高性能、支持丰富数据结构的 NoSQL 数据库,作者在设计时目标就是替代 Redis。Redis 是一个键-值型内存数据库,其所有数据均在内存中进行操作,因而其数据容易受到内存容量的限制,并且数据不能持久化存储。而 SSDB 不但完全兼容了 Redis 的 API,支持 Redis 客户端的访问,而且提供了与 Redis 一样的集合数据结构,如 list、hash、zset 等。SSDB 底层的数据存储引擎也是基于 LevelDB 开发的,因而实现了数据的持久化存储,且支持的数据容量是 Redis 的 100 倍。
不仅如此,SSDB 还实现了主从同步与负载均衡。可以说,SSDB 是 LevelDB 与 Redis 相结合的产物,其继承了 LevelDB 强大的数据读写性能,也吸取了 Redis 简单易用的操作接口与丰富的数据结构。
SSDB 官网(http://ssdb.io/zh_cn/)公布了其与 Redis 的性能测试对比。在测试中,SSDB 的读性能完全超越了 Redis,而写性能只比 Redis 慢 10%。SSDB 可以将原有的 Redis 数据进行直接迁移。
SSDB 已被数十家公司在多种场景中使用,例如财经类应用用其来存储高速证券行情快照,直播平台用其来存储粉丝关注与在线人数数据、在线广告平台用其来存储实时会话数据、音乐类平台用其来存储专辑封面信息以及评论数据。在这些用户中,许多都是从原来的 Redis 平台迁移而来的,由此可见,SSDB 在性能上的确相当优异,并且可用于许多 Redis 无法胜任的领域。而这一切均归功于底层的数据存储引擎 LevelDB。
总结
本节简要介绍了键-值数据库与 LevelDB 数据库的沿革,分析了 LevelDB 的功能、性能与应用场景,并针对性地介绍了 LevelDB 的两种衍生产品——RocksDB 与 SSDB。本节的目的在于让读者对 LevelDB 有初步的了解,通过本章读者应搞清楚 LevelDB 究竟是什么,其具有的优势与劣势。