技术开发 频道

弃用NoSQL数据库 CouchDB再见了

        【IT168 评论】2012年5月10日,Sauce Labs公司的首席架构师Steven Hazel,写了一篇关于弃用NoSQL数据库CouchDB产品,介绍他们将Couch数据库的数据迁移到MySQL数据库平台中。

  在Sauce Lab(酱油实验室)里,我们刚刚庆祝完成一个重大项目—将最后的CouchDB数据库转变为MySQL数据库,以提高服务正常运行时间和可靠性。 由于大部分无故停机的是由于CouchDB数据库宕机引起的,因此完成这种迁移是我们一个重要的里程碑。

  CouchDB数据库开始时,是一个非常宝贵的经验,在1.2版本时它的可靠性还是可以的。 但我们的服务对可靠性要求非常高,于是最终决定:这种转变是前进中最有效的方式。

  一旦决使用MySQL(具体而言,是Percona的基于InnoDB存储引擎的XtraDB存储引擎,),我们就重构了数据库抽象层,并迁移了所有各种类型的数据库。 在过去几个月,迁移完成后,我们的服务正常运行时间大大提高了。

  这篇文章介绍了我们使用CouchDB数据库的经验,以及在哪里遇到了麻烦。我也谈了这方面的经验,如何影响了我们对NoSQL数据库的整体观点,以及在熟悉了NoSQL数据库后,如何积极权衡对MySQL数据库的安装配置。

  首先,我们是如何陷入困境?

  所有的事情都在变的伟大。

  自2008年开始我们第一次启动Sauce Lab,我们认为我们正在建立与当今运行的服务非常不同的东西。我们高兴地尝试NoSQL数据库,使用MySQL关系数据库的设计者多年来从来没有想过的方式。CouchDB的似乎很适合我们的需要。

  我们原来的产品为客户的利益着想而设计了一个有特色的用于存储数据的REST API,该计划彻底废弃了曾有的CouchDB的RESTful API。 这让我们得到了一个原型并匆忙的运行。 CouchDB是新鲜事物且尚未有过什么实际使用,但这并不重要,因为我们数据库I / O需求很少,应用程序自然具有水平扩展性,且产品是容错的。只要保持复制正常且在出错时重试就可以很容易地弥补稳定性的鸿沟。这样难道会出问题吗?

  可能出错的地方

  随着这家小公司的成长,我们逐渐了解到客户所面临的问题,我们的产品也经历了几个重大变化.随着时间的推移严格按照用户对数据进行分区意义不大。我们变得越来越依靠数据库的I/O性能。通常,我们觉得自己使用CouchDB与最初设想非常不同,更与大多数web应用程序使用数据库的方式不同。虽然这仍是一种合理的使用方式,但我们曾经相信的附加安全性正随着产品的升级而慢慢消失,而那恰恰是我们所需要的。

  Sauce Lab比一般web应用程序对可靠性要求更高。 如果我们对一个单一请求处理失败,就代表了对一个客户检验的失败,并影响他们的整个架构。 随着时间的推移,CouchDB数据库的可靠性越来越糟糕。 我们不停的更换硬件设备,改变使用CouchDB数据库的方式。 我们改变了软件架构,使其对数据库和数据库I / O操作减少。不过, 最后我们决定,最好的方法还是更换数据库产品。

  到此为止我都没有讲CouchDB的具体缺点, 这是一个年轻的数据库,可靠性和性能问题是可以预期的。 因为我们对传统的关系型数据库没有偏爱,但在某种程度上,CouchDB数据库还是太糟糕了。 我们深信,NoSQL数据库是未来。 只是我们不相信NoSQL数据库是现在。

  我们真心喜欢CouchDB数据库的一些事

  无模式。 这是美妙的 。,模式甚至有何用? 他们只是毫无理由的把事情变复杂。 有时你需要对数据增加约束,数据库模式改变非常难。 然后CouchDB数据库对文档,增加新的字段非常简单。

  非关系型。 关系型数据库发展出解决问题的原则是:数据的完整性是至关重要的,而可用性则无关紧要。 在很多在现代Web应用程序数据库层中毫无意义的功能。有6种连接方式的事务查询起初是很吸引人的,但是当你需要扩展(scale)时就会令你陷入困境。从一开始阻止这些发生通常是很容易的。

  No SQL。 这是2012年,大多数查询从代码运行,而不是由坐在控制台的人类。为什么我们仍在用非常接近奇怪的COBOL语言构建的代码查询我们的数据库呢?且这些被组建的代码不得不在每一次查询时重新解析。像SQL注入攻击这样的东西根本不应该存在。 他们是将你的数据库API看作编程语言而不是一个协议的后果,它是这个自20世纪70年代起经深思熟虑设计的漏洞的核心;

  HTTP API。 无论在任何地方,只要符合HTTP(或者run curl)协议,就可以方便的查询数据库;

  始终一致性,只追加文件格式。 这样做数据库备份仅作文件复制,简单且无后顾之忧;

  JavaScript是作为一个视图/查询语言,被人熟知且广泛使用;

  任意计算出的值上的索引似乎是一个有巨大潜能的功能。 我们从来没有找到一个真正智慧的方式使用它们,虽然它只是简单的通过电子邮件的域名做用户索引。

  最后值得指出,即使在挑战其查询和维护索引能力的压力之下,CouchDB数据库从未丢失任何数据。

${PageNumber}

  使用CouchDB时我们遇到的问题

  可用性:

  在我们最初的设置中,磁盘缓慢的性能使CouchDB正在运行的查询周期性的失败。 后来用更快的RAID配置后性能会有所改善,但随着负荷的增加,问题回来了。 相比而言,Percona在这一负荷水平完全胜任:mysqld使用CPU资源非常少,几乎没有任何慢查询,cache使用效率足够高以至于几乎没有磁盘读写,在RAID 10下我们的写负载是一个非常舒适的小百分比。

  视图有时会丢失索引,而且在正常工作前还有几次重加索引失败的情况。 偶尔他们会进入一种无休止重加索引的状态,直到我们彻底删除视图文件并重新启动CouchDB。 而对此我们非常痛苦。 最后一件事重新编制索引的惊喜是,我们作为一个小团队已经采取一个巨大的任务列表和战斗力,以打动潜在的大客户的需要。Surprise reindexing exercises were the last thing we needed as a small team already taking on a giant task list and fighting to impress potential big customers.

  损坏的视图(Views)有时会阻止所有工作的视图,直到这个视图文件已被删除,在这个时候,视图索引消耗时间做重启和一些不可靠的工作。 不知道多少次我们中的一员在凌晨4点被监控系统唤醒,因为数据库未经许可因突然变成一个简单的键/值存储而当掉。

  压缩(Compaction)有时会没有任何提示的终止,有时还不得不被删除残留的文件使其重新运行。 这在我们提高了磁盘容量报警上线之前导致了一些可怕的情况,因为我们发现这一点时,由于做压缩,磁盘仅剩下非常小的空间。

  在早期版本中,我们遇到了有关文件句柄使用的三、四个错误。 Bug reports快速修复了他们,并在1.0.2版本中更新了有关代码。

  性能:

  真的还有一件事要在这里说,那个CouchDB的视图查询的性能问题,并没有达到我们曾经期望的与MySQL索引查询大致相等的性能级别。 这不是一个巨大的惊喜或者一个巨大的问题,但是哇塞(but wow),现在很多事情更快了,我们的数据库机器是负担减少了许多。

  维护问题:

  当CouchDB出错时,会使所有正在运行的查询出错。 其中包括复制和压缩,所以我们需要脚本来检查这些进程,并在必要时重新启动它们。

  视图索引仅在查询时才更新–插入操作不会更新索引。 这意味着你必须写一个脚本来定期查看你的视图,除非你想在一段时间无人问津时他们变的出奇的慢。 在实践中,我们总是倾向于不通过插入操作更新索引来获得提高性能的可能。但是写一些可靠的脚本监控数据的索引是机警(tricky)的。

  用于压缩的简单的复制收集器 可以花大量时间查看长期的文档。当一个数据库既有长期文件又有短期文件时这尤其是个坏消息:压缩需要很长时间,但急需控制住磁盘使用率。 另外,你不得不自己运行压缩和监测,以确保它的工作是有意义的。 压缩应该是自动化和分代(generational)的。

  未实现的诺言:

  CouchDB的设计看起来对像自动分片等NoSQL的主要功能非常完美,但事实并不是这样。

  映射化简(MapReduce)只能在一台机器上运行有何意义? 我们原本以为这是为分布式查询而设计的功能。

  我们从来没有清楚过CouchDB开发人员对其核心用途的考虑。 我们看到了发展的重点是集所有功能于一身的应用程序服务,然后是大规模多方向移动应用程序的复制。 两个都是有趣的想法,但不是我们所需要的。

  (我们被告知在最近发布的CouchDB 1.2,这些问题已经解决。)

  我们能够有效发挥CouchDB的性能,并随着时间的推移,我们了解到各种的维修问题的脚本方式。 但我们担心CouchDB好像被和我们不同的用法所吸引着,这是最终最终迫使我们做数据库转换的导火索。 我们谈到了一些可能的选择,和最终的一个典型解决方案。

  MySQL,原始的NoSQL数据库

  那么,为什么不能切换到另一个像MongoDB面向文档的数据库或其他NoSQL数据库呢? 我们曾经对MongoDB非常感兴趣,但在做一些研究和听到褒贬不一的评论后 ,我们得出结论:同CouchDB一样,它也有很多相同的问题使我们的工作受到影响。其他NoSQL数据库往往一样不同的,像CouchDB与MySQL之间一样区别很大。

  ) –因此很难选择 –而且对我们还有很多不熟悉的事情。 鉴于对MySQL的经验,我们知道这它能足够满足我们的需求,很难证明其他的选择同样适合。

  我们很熟悉MySQL的缺点:别的咱不说,光它的配置就很麻烦(提示:优化性能中最重要的设置是innodb_buffer_pool_size),存储引擎的选择,以及除了面向SQl,分析执行查询SQL语句的时间花费。经验丰富的MySQL用户期望写出很多强制索引子句。

  另一方面,InnoDB存储引擎整体来看还是非常强大的。在过去十年中,它已经在一些最大的互联网公司大量使用,而且变得越来越强壮。几乎所有的数据库在底层是都建立在相同的基本B-树算法、散列和类似InnoDB存储引擎的缓存。在尊重基本原理的前提下,任何新的数据库管理系统对在真实环境性能和和靠性的突破都是非常艰难的。 但也许未必一定这样:Percona的前瞻性思维的键/值接口是一个可靠的InnoDB存储引擎如何成为真正的NoSQL架构的很好的例子。

  刚换到MySQL数据库时,我们对它还像原始存储引擎一样。现在我们将使用MySQL,开发出之前NoSQL全部功能的方法。

  我们设法将CouchDB的模型层(model layer)移植到MySQL中且对代码库的影响最小。对 大多数使用模型的代码(model-using code),使用MySQL看起来和使用CouchDB的完全一样。 除了它的速度更快,而且这样的数据库从未出错。

  我们不使用外键,或者多语句事务,到目前为止也未使用join。 一旦我们需时,我们已经准备好横向扩展(horizontally scale)。 (不过,这将需要一段时间!自从分片被发明的时期过后,硬件已经发展的更加强大,而且那些日子你可以仅靠单一的写主库运行很长的时间。)

  我们的所有表都含有一个TEXT的字段用以存储JSON,我们的模型层为了大多数需求而悄悄将对待他们像真正的列一样。这个主意就像Rails 的ActiveRecord ::商店 。虽不是和MySQL的功能设置非常完美融合, MySQL不能真正操作这些JSON列 – 但它仍然是一个伟大的想法,让我们向无模式数据库更加紧密。

  这是一个已证明的可靠的数据库存储引擎和给我们很多NoSQL数据库优点的架构的组合, 这种设置工作过去一两个月了,我们发现它非常难于达到最好的两个世界的途径。

  英文地址:http://saucelabs.com/blog/index.php/2012/05/goodbye-couchdb/

0
相关文章