Key-Value数据库实现Part 2:使用已有的K-V数据库做模型

这篇文章中,我会解释为什么在项目中使用已有的模型而不是完全从零开始。我会列出一系列选择K-V数据库模型的标准。最后会概述并选择一些广为人知且符合所列标准的K-V数据库。文章将会主要涵盖:

  1. 不要重复造轮子
  2. 可供参考的模型和选择标准
  3. 被选中数据库的概要

1.不要重复造轮子

  K-V数据库已经存在至少30多年了[1]。其中最有纪念意义的项目是DBM,是于1979年由Kenneth Tompson为Unix version 7编写的最初的数据库管理软件[2]。工程师们面对这有关这些数据库的种种情形

和问题,对其设计和数据结构或接纳或反对。他们已经通过实际生产中遇到的问题得到了很多经验,不顾这些前驱们的工作从零开始会显得很蠢,那样只会重复他们已经犯过的错误。

Gall定律,由John Gall提出[3]

  一个能正常工作的复杂系统永远都是从一个能工作的简单系统演化而来的。反之一样成立:一个从零开始设计的复杂系统从来不能正常工作也无法调试到正常工作。你得推倒重来,从一个能工作的简

单系统开始。

  这段引用给我的K-V数据库项目奠定了两个基调:

  1.使用模型。我需要找一些已经存在了一段时间的K-V数据库项目,更理想的情况是找一些成功的K-V数据库的后续项目。因为这些项目通常设计得很牢固,而且在多次的迭代开发过程中不断完善。这些

K-V数据库将会被用作我自己项目的模型。

  2.从小做起。项目的第一个版本应该小巧而简单,这样方便测试和验证。如果需要改进和额外的功能则应该在后续的版本中添加。

2.候选模型和选择标准

  在K-V数据库和NoSQL数据库方面做了一点功课后,我决定在下列数据库里面做更全面的选择:

  • DBM
  • Berkeley DB
  • Kyoto Cabinet
  • Memcached 和 MemcacheDB
  • LevelDB
  • MongoDB
  • Redis
  • OpenLDAP
  • SQLite

  我的选择标准如下:

  • 我想用面向对象编程的方法来实现一个K-V数据库,所以需要从OOP语言编写的数据库中获得灵感。
  • 对于底层的数据结构,我想基于硬盘上的hash table实现,所以候选者们需要提供对硬盘进行读写的方法。
  • 数据库需要支持网络访问
  • 不需要查询引擎或者结构化访问数据
  • 不需要支持完整的ACID规范
  • 鉴于项目需要我独自完成,我想找一些小团队的实现,一两个人的最好

3.最后敲定的K-V数据库的概述

  最后的三大赢家是Berkeley DB,Kyoto Cabinet和LevelDB。Berkeley DB和Kyoto Cabinet都是DBM的继任项目。除此之外,这两者都不是初始版本,而是其作者的第N个版本了。这通常意味着他们

比其他初次完成的项目更可靠。LevelDB年代更近,底层数据结构基于LSM Tree而不是hash table。但是他的代码是我见过所有代码中最干净的。上述三个项目都是一或两个人开发的,下面是他们的详细信

息。

Berkeley DB

  该项目始于1986年,距离我写这篇文章已有26年之久了。Berkeley DB是DBM的后续项目,底层由hash table实现。第一个版本由Margo Seltzer[22]和Ozan Yigit[23]实现,他们当时还在UCB。其后由

Oracle接手并继续开发。

  Berkeley DB最初用C语言实现,至今仍然纯C语言开发。整个开发过程逐步推进,每个主要版本会添加一些新特性。现在已经支持concurrency, transaction, recovery和replication[4]. Berkeley DB已经

广泛的用于部署中[5],证明了其架构的高度可靠。关于其设计的更多信息可以参考“Berkeley DB Programmer‘s Reference Guide”[6]以及“The Architecture of Open Source Applications, Volume 1”[5]

Kyoto Cabinet

  Kyoto Cabinet于2009年由Mikio Hirabayashi[24]发布,现在仍然活跃。这个项目是作者发布的Tokyo Cabinet (2007)和QDBM (2003)的后续项目。QDBM曾作为高性能DBM的后续实现[7].。Kyoto Cabinet

因为其纯正的DBM血统和作者超过12年的K-V数据库开发经验而格外让人感兴趣。在实现这三个K-V数据库的这么多年中,作者必然对需要的数据结构有了扎实的理解,更不用说对于性能瓶颈所在的直觉。

  Kyoto Cabinet用C++实现,并实现了hash table,B+ Tree和一些比较深奥的数据结构。其提供了相当出色的性能表现[16]。虽然如此,他似乎还是存在一些初始化参数导致的性能问题。正如很多人反馈的

那样,当数据量小于一个跟bucket array大小成比例的阈值(其由创建数据库文件的初始化参数确定)时,性能很好没有问题。一旦超过阈值,性能将会急剧下降[18][19]。同样的问题也在Tokyo Cabinet[20][21]

中出现。这意味着使用这两者时,一旦项目的需求发生了变动,可能会导致很严重的后果。大家也都懂软件领域中真正不变的东西到底有多少......

LevelDB

  LevelDB是一个由谷歌员工Jeffrey Dean (译者:这位强到不是人))[8]和Sanjay Ghemawat[9]实现,他们都曾参与Google的Mythical Infrastructure项目:MapReduce和BigTable。鉴于这两位在Google工

作时遇到的大规模问题的经验,他们很大程度上是清楚自己在做什么的。LevelDB不同于其他K-V数据库的很有趣的一点是他没有用hash table或者B-Tree做底层数据结构,而是基于Log-Structured Merge Tree[12]。

LSM据称对SSD做了优化[13]。你可以在High Scalability blog上找到一堆关于LevelDB的资料[17].

  LevelDB发布于2011年,基于C++实现,并被设计为更高层存储系统的基础模块[10]。Chrome未来版本中的IndexedDB HTML5 API将会使用LevelDB[10][11]。根据作者提供的测试[14],其性能表现在一定

的数据量以下是炸裂级别的。然而,另一项由Acunu的Andy Twigg在商用SSD上做的测试表明,当数据量超过1M并朝着1B的级别发展时,性能会剧烈下降[15]。所以对于真正对数据规模有要求的后端项目来说,

LevelDB可能不是最好的选择。

  但其实这不是什么大问题,因为对于我来说LevelDB最好的部分不在于他的性能而在于它的架构。看看源代码中各个部分的组织方式之后,你就会理解什么叫纯粹的美。所有东西都那么清楚,简洁,合理。接

触LevelDB的源码并用他做模型是一个绝佳的写出好代码的机会。

剩下那些落选的K-V数据库怎么办?

  事实上我没选他们不代表我会把他们完全抛掉。我可能偶尔会用到他们架构中的一些元素。但是他们不会像选中的那三个数据库一样对我的项目产生很大的影响。

引用

[1] http://blog.knuthaugen.no/2010/03/a-brief-history-of-nosql.html
[2] http://en.wikipedia.org/wiki/Dbm
[3] http://en.wikipedia.org/wiki/Systemantics
[4] http://en.wikipedia.org/wiki/Berkeley_DB#Origin
[5] http://www.aosabook.org/en/bdb.html
[6] http://docs.oracle.com/cd/E17076_02/html/programmer_reference/intro.html
[7] http://fallabs.com/qdbm/
[8] http://research.google.com/people/jeff/
[9] http://research.google.com/pubs/SanjayGhemawat.html
[10] http://google-opensource.blogspot.com/2011/07/leveldb-fast-persistent-key-value-store.html
[11] http://www.w3.org/TR/IndexedDB/
[12] http://www.igvita.com/2012/02/06/sstable-and-log-structured-storage-leveldb/
[13] http://www.acunu.com/2/post/2011/04/log-file-systems-and-ssds-made-for-each-other.html
[14] http://leveldb.googlecode.com/svn/trunk/doc/benchmark.html
[15] http://www.acunu.com/2/post/2011/08/benchmarking-leveldb.html
[16] http://blog.creapptives.com/post/8330476086/leveldb-vs-kyoto-cabinet-my-findings
[17] http://highscalability.com/blog/2011/8/10/leveldb-fast-and-lightweight-keyvalue-database-from-the-auth.html
[18] http://stackoverflow.com/questions/13054852/kyoto-cabinet-berkeley-db-hash-table-size-limitations
[19] https://groups.google.com/forum/#!topic/tokyocabinet-users/Bzp4fLbmcDw/discussion
[20] http://stackoverflow.com/questions/1051847/why-does-tokyo-tyrant-slow-down-exponentially-even-after-adjusting-bnum
[21] https://groups.google.com/forum/#!topic/tokyocabinet-users/1E06DFQM8mI/discussion
[22] http://www.eecs.harvard.edu/margo/
[23] http://www.cse.yorku.ca/~oz/
[24] http://fallabs.com/mikio/profile.html

原文地址:https://www.cnblogs.com/fangqi96/p/9126501.html

时间: 2024-10-14 16:53:43

Key-Value数据库实现Part 2:使用已有的K-V数据库做模型的相关文章

SharePoint 2010 数据库xxx的事务日志已满

http://www.cnblogs.com/sygwin/p/6222428.html 接到领导安排,说客户有问题 请求协助解决,对方给我展示的错误日志,如下: 数据库'WSS_Content_xxxx'的事务日志已满.若要查明无法重用日志中的空间的原因,请参阅sy.databases中的log_reuse_wait_dec列 导致的结果是用户再也无法上传文件到文档库了. 看来一下对应的数据库文件,日志文件大的惊人,已经超过1.8T 作为老司机,理论上解决这样的问题,就是收缩数据库.可是咱是个

可以将一些配置信息已json格式存在数据库中读取的时候序列化。

public partial class json序列化 : System.Web.UI.Page    {        protected void Page_Load(object sender, EventArgs e)        {            StringBuilder builder = new StringBuilder(); builder.Append("{");            builder.Append("    \"C

SQL server触发器、存储过程操作远程数据库插入数据,解决服务器已存在的问题

近期弄了一个小项目,也不是非常复杂,须要将一个数据库的一些数据备份到另外一个库.不是本地,可能是网络上其它的数据库.想了一下,用了存储过程和触发器. 也不是非常复杂,首先我须要操作远程数据库,于是写了一个存储过程: CREATE PROCEDURE sendInfoToRemoteDb @CardNo varchar(50), @CardStyle varchar(20), @userId varchar(20), @UserName varchar(30), @passDate datetim

php从mysql数据库中获取数据乱码(已解决)

问题: 数据库里是中文,在网页上通过查找数据库显示如下: img/??.png 数据库里面数据为: img/我的.png 解决: 首先你的php网页要是UTF-8 <?php header("Content-Type:text/html;charset=UTF-8"); ?> 连接数据库之后插入如下代码: $program_char = "utf8" ; mysqli_set_charset( $con , $program_char ); 如果你是其他

云计算下的数据库 分析 以及部分互联网公司目前采用的新型数据库总结

云计算下的新型数据库技术 摘要:在这个信息化的时代,我们的一举一动都离不开与数据打交道,特别是云计算和大数据时代的到来,使得传统数据库的性能已无法满足海量数据的实时交易查询需求,在性能和成本的双重压力之下,云计算下的数据库需要寻找突破之路. 1.简介: 云计算通过整合,管理和调配分布在互联网中的所有计算资源,以统一的界面同时向用户提供服务.互联网提供的各种计算形式的应用以及提供这些服务的数据中心和软硬件基础设施.提供的服务成为软件即服务(SaaS),数据中心的软硬件基础设施即为云,这种虚拟化资源

数据库水平切分的原理探讨、设计思路--数据库分库,分表,集群,负载均衡器

本文转载:http://www.cnblogs.com/olartan/archive/2009/12/02/1615131.html 第1章  引言 数据量巨大时,首先把多表分算到不同的DB中,然后把数据根据关键列,分布到不同的数据库中.库分布以后,系统的查询,io等操作都可以有多个机器组成的群组共同完成了.本文主要就是针对,海量数据库,进行分库.分表.负载均衡原理,进行探讨,并提出解决方案. 随着互联网应用的广泛普及,海量数据的存储和访问成为了系统设计的瓶颈问题.对于一个大型的互联网应用,每

SQL Server中使用数据库快照的方式来完成测试环境中数据库的轻量级备份还原操作

原文:SQL Server中使用数据库快照的方式来完成测试环境中数据库的轻量级备份还原操作 在开发或者测试环境的数据库中,经常会发现有开发或者测试人员误删除表或者数据的情况,对于开发或者测试库,一般都没有安排定时的备份任务去备份数据库,一方面是由于存储资源有限,不太可能给开发或者测试环境准备大量的存储空间,二是必要性不是很强,开发或者测试库的数据库对象变化太多,通过还原备份的方式又有可能冲掉其最近新建的数据库对象.但是不得不面对的问题就是个别人在执行update或者delete操作的时候“忘了加

【巨杉数据库SequoiaDB】助力金融科技升级,巨杉数据库闪耀金融展

11月4日,以"科技助创新 开放促改革 发展惠民生"为主题的2019中国国际金融展和深圳国际金融博览会在深圳会展中心盛大开幕. 金融分布式数据库成为关注焦点巨杉数据库作为金融行业广泛应用的自研分布式数据库产品,亮相金融展,成为本次展会金融科技领域的焦点之一.同时,在展会的"金融科技发展趋势研讨会"上,巨杉数据库分享了"自研金融级分布式数据库应用与实践"专题,介绍巨杉数据库8年的自研技术发展历程以及深耕银行8年以来的规模应用场景案例.金融科技是技术

定时从一个数据库表中的数据存储到另外一个数据库中的表,而且怎么处理重复的数据?

原文:http://www.iteye.com/problems/77856 定时从一个数据库表中的数据存储到另外一个数据库中的表,而且怎么处理重复的数据? 表结构肯定是不能破坏,但是临时表如果是自己的数据库还行,问题是这个Oracle数据库是客户的数据库呢,你不能在他的数据库做任何多余的操作吧?还有别的更好的方法吗? 这个真的是比较困难. 首先,你要从客户机oracle取数据,因为这1分钟间隔之内不知道用户机新增加了哪些数据(大部分情况下是用户使用别的系统插入数据,而你又没有这个系统的程序接口