作者: Emmanuel Goossaert
在本文中,我将会以键值对是什么的一个减短描写叙述開始。然后我将解释本项目之后的一些理由,最后我将说明我打算实现的键值对存储的主要目标。
这里是本文中将会包括内容的列表:
- 键值对存储的概述
- 键值对存储 vs 关系型数据库
- 为什么要实现键值对存储
- 计划
- 引用
1. 键值对存储的概述
基于非常多文章已经有了非常多具体的介绍。本节仅仅是对于键值对存储的一个简短介绍。我已经选择了几篇放在本文底部的引用一节中。
键值对存储是数据库最简单的组织形式。基本上全部的编程语言都带有应用在内存中的键值对存储。C++STL的映射容器(map container)和Java的HashMap以及Python的字典类型都是键值对存储。键值对存储通常都有例如以下接口:
Get( key ):
Set( key, value ):
假设“key”下已经有了一些数据,旧的数据将被替换。
Delete( key ):
大部分低层实现都是使用哈希表或者某种自平衡树(比如B-树或者红黑树)。有时候数据太大而不装不进内存,或者必须维持数据谨防系统由于未知原因而崩溃。在这些情况下。就必须使用到文件系统。
键值对存储是NoSQL运动的一部分。NoSQL将全部不使用基于关系型数据库概念的数据库系统组合在一起。
维基百科上的NoSQL词条非常好的总结了这些数据库的特征。
- 不使用SQL查询语言
- 可不全面支持ACID(原子性、一致性、隔离性、持久性)。
- 可提供分布式、容错强的结构
2. 键值对存储和关系型数据库
不像关系型数据库,键值对存储不须要了解值中的数据,也没有像MySQL或者PostgreSQL中那样的不论什么结构。
这同一时候表示像SQL那样用WHERE语句或者通过不论什么形式的过滤来请求数据中的一部分是无法做到的。假设你不知道去哪找。你必须遍历全部的键。获取它们相应的值,应用某种你须要的过滤,然后保留你想要的东西。
这将会须要大量的运算,也即表示仅仅有当键已知的时候才干体现出最佳性能,否则键值对存储将无法胜任(注意:一些键值对存储可以存储结构化的数据并有字段索引)。
因此。即使键值对存储在訪问速度上常常比关系型数据库系统性能要好数个数量级,但对键已知的需求也限制着其应用。
我開始这个项目主要是作为充电的一种方式,学习和补充一些核心后端基本原理知识。
读书和维基上的文章非常无聊而且没有练习,因此我觉得着手開始做而且实际写一写代码会更好。我要找的是一个能够让我复习例如以下内容的项目:
- C++编程语言
- 面向对象设计
- 算法和数据结构
- 内存管理
- 多进程或或多线程的并发管理
- server/client模式的网络
- 磁盘訪问的I/O问题和文件系统的使用
一个使用文件系统作为永久存储,且提供网络接口的键值对存储将会包括上面列出的所有范围的内容。这个项目刚好可以处理后端project的各个领域。可是让我们面对现实。
市面上已经有了大量的键值对存储,当中一些是由非常聪明的人实现的,而且已经在大公司的生产环境使用了。
这包括Redis, MongoDB, memcached, BerkeleyDB, Kyoto Cabinet 和LevelDB。
除此之外。最近出现了关于键值对存储的潮流。
好像每人都有一个而且想给大家看自己的键值对存储系统有多么出色和高速。这个问题在Leonard Lin博客中关于键值对存储的文章中描写叙述了。这些项目中大多数在那时还不成熟且不能应用于生产环境,但人们仍然想展示出来。在博客文章或会议幻灯片中常常能够看到对一些晦涩键值对存储系统性能的比較。这些图表基本上毫无意义,而且仅仅是在自己的硬件上用自己的数据和应用进行的孤立測试,能够告诉你哪一种键值对存储最适用于解决你的问题。这里是性能所依赖的条件:
- 硬件
- 使用的文件系统
- 实际应用和详细哪些键会被訪问(引用的局部性)
- 数据集,特别是键和值的长度,以及使用哈希表的时候键碰撞的可能性。
因此。编写一个键值对存储系统并有一定的影响力是比較难的。由于其非常有可能由于其他已存在的更好的键值对存储系统的存在而被忽视。或者被简单的淹没在半生不熟的业余项目中而没人关心。
为了差异性,这个项目不能像其它人做的那样为了速度,而必须瞄准于填补现有解决方式间的空隙。这里是我发现的可以让键值对项目脱颖而出的几个方法。
- 适应于某种特定数据类型(比如:图片,地理数据等)
- 适应于某种特定操作(比如读取性能特别好或者写入性能特别好等)
- 适应于某种特定问题 (比如:自己主动參数调节,非常多键值对存储都有非常多选项,而找到一个最好的參数设置有时候非常棘手)
- 提供很多其它数据訪问选项。
以LevelDB为例。数据能够向前或者向后訪问。有迭代器,是依照键排序的。
并非全部的键值对存储都能做到这样。 - 使自己的实现更平易近人:如今。非常少有键值对存储系统有全然的代码。假设你须要高速搭建一个项目,而你必须为其自己定义一个键值对存储。即便不是一个广为人知的项目,有代码的解决方式看起来确实平易近人而且会作为选项之中的一个。
实际上理解代码并相信这个解决方式会弥补这些不足。 - 明白应用。这儿有一个实际问题的样例:非常多网络爬虫框架(网络蜘蛛)有一个粗劣的接口来管理他们须要爬的URL,这常常使得客户使用键值对存储来实现逻辑。全部的网络爬虫框架都能因一个统一的URL优化的键值对存储而受益。
4. 计划
项目的目标是用易于理解的C++代码开发一个轻量级键值对存储。其实。我打算在本项目中遵从Google C++ 代码风格导引。
我将会使用哈希表作为底层数据结构,数据将会存储在硬盘上,同一时候将会实现一个网络接口。我不会项目进度而匆忙完毕。而是要在设计和实现时简洁和清晰。我相同会尽我能力最小化硬盘上数据库文件的空间占用。
我不想又一次发明轮子,所以我会从查看别的C或者C++的键值对存储项目開始,然后从中选取比較出色的。
我会逐渐学习他们的结构和代码,从中获取启发。后端project是我的核心技能之中的一个,我已经有了这个项目所需的大部分知识,但我知道我还要学非常多新东西。这使其对我来说更加有意思。我相同乐于记录下当中的所有东西。
曾经我非常喜欢逛核心技术博客,比如Alexander Sandler和Gustavo Duarte。我也想贡献出一些实用的,尽可能好的东西。
我的研究结果和键值对存储的一些工作将在这个文章系列中记录。不要试图用文章的日期来猜測键值对存储实现的时间:文章可能和实际研究或者做的事之间有相当大的延迟。
在第二部分,我将搜索顶级的键值对存储项目并解释为什么我选择了当中的部分作为參考,而不选还有一些。其它的文章你能够參考本系列的文件夹。
你能够在下边的“引用”一节中找到一些文章和书籍章节来学习很多其它关于键值对存储的知识。在阅读第二节之前,我强烈建议至少读一下The NoSQL Ecosystem和 Key Value Stores: A Practical Overview。
5. 引用
The NoSQL Ecosystem, from the book “Architecture of Open Source Applications, Volume 1″
NoSQL Patterns, by Ricky Ho
NoSQL Databases, referencing all the NoSQL databases that matter at the moment
NoSQL Data Modeling Techniques, by Ilya Katsov
NoSQL databases benchmark: Cassandra, HBase, MongoDB, Riak, and the discussion on Hacker News
Wikipedia article on the ACID paradigm
Key Value Stores: A Practical Overview, by Marc Seeger
Some Notes on Distributed Key Stores, by Leonard Lin