使用NoSQL数据存储时遇到了哪些可伸缩性问题?

时间:2010-02-17 22:50:25

标签: database nosql key-value-store graph-databases distributed-database

NoSQL指的是打破关系数据库和ACID保证历史的非关系数据存储。流行的开源NoSQL数据存储包括:

  • Cassandra(表格,用Java编写,由Cisco,WebEx,Digg,Facebook,IBM,Mahalo,Rackspace,Reddit和Twitter使用)
  • CouchDB(文档,用Erlang编写,BBC和Engine Yard使用)
  • Dynomite(键值,用Erlang编写,由Powerset使用)
  • HBase(键值,用Java编写,Bing使用)
  • Hypertable(表格,用C ++编写,百度使用)
  • Kai(键值,用Erlang编写)
  • MemcacheDB(键值,用C编写,Reddit使用)
  • MongoDB(文档,用C ++编写,由Electronic Arts,Github,NY Times和Sourceforge使用)
  • Neo4j(图表,用Java编写,一些瑞典大学使用)
  • Project Voldemort(键值,用Java编写,由LinkedIn使用)
  • Redis(键值,用C编写,Craigslist,Engine Yard和Github使用)
  • Riak(键值,用Erlang编写,由Comcast和Mochi Media使用)
  • Ringo(键值,用Erlang编写,诺基亚使用)
  • Scalaris(键值,用Erlang编写,由OnScale使用)
  • Terrastore(文档,用Java编写)
  • ThruDB(文档,用C ++编写,JunkDepot.com使用)
  • Tokyo Cabinet/Tokyo Tyrant(键入值,用C语言编写,由Mixi.jp(日本社交网站)使用)

我想知道您 - SO读者 - 使用数据存储解决的具体问题以及您使用的NoSQL数据存储。

问题:

  • 您使用NoSQL数据存储解决了哪些可扩展性问题?
  • 你使用了什么NoSQL数据存储?
  • 在切换到NoSQL数据存储之前,您使用了哪些数据库?

我正在寻找第一手经验,所以请不要回答,除非你有。

15 个答案:

答案 0 :(得分:50)

我当前的项目。

在规范化结构中存储18,000个对象:8个不同表中的90,000行。花了1分钟检索并将它们映射到我们的Java对象模型,即所有内容都正确索引等。

使用轻量级文本表示将它们存储为键/值对:1个表,18,000行,3秒钟检索它们并重构Java对象。

在商业方面:第一种选择是不可行的。第二个选项意味着我们的应用程序有效。

技术细节:在MySQL上运行SQL和NoSQL!坚持使用MySQL获得良好的事务支持,性能和可靠的跟踪记录,以便不破坏数据,扩展相当好,支持群集等。

我们在MySQL中的数据模型现在只是关键字段(整数)和大“值”字段:基本上只是一个很大的TEXT字段。

我们没有使用任何新玩家(CouchDB,Cassandra,MongoDB等),因为尽管它们各自提供了很好的功能/性能,但我们的情况总是有缺点(例如缺少/不成熟的Java支持)。

使用MySQL的(ab)的额外好处 - 关键工作的模型位可以轻松链接到我们的键/值存储数据。

更新:这是我们如何代表文本内容的示例,而不是我们的实际业务领域(我们不使用“产品”),因为我的老板会拍我,但传达了这个想法,包括递归方面(一个实体,这里是产品,“包含”其他产品)。希望很明显,在标准化结构中,这可能是相当多的表,例如将产品加入到其各种口味中,包含其他产品等

Name=An Example Product
Type=CategoryAProduct
Colour=Blue
Size=Large
Flavours={nice,lovely,unpleasant,foul}
Contains=[
Name=Product2
Type=CategoryBProduct
Size=medium
Flavours={yuck}
------
Name=Product3
Type=CategoryCProduct
Size=Small
Flavours={sublime}
]

答案 1 :(得分:49)

我已经将一个小子项目从MySQL切换到CouchDB,以便能够处理负载。结果太棒了。

大约2年前,我们在http://www.ubuntuusers.de/(可能是德国最大的Linux社区网站)上发布了自编软件。该站点是用Python编写的,我们添加了一个WSGI中间件,它能够捕获所有异常并将它们发送到另一个小型MySQL驱动的网站。这个小网站使用哈希来确定不同的错误并存储出现次数和最后一次出现。

不幸的是,在发布后不久,traceback-logger网站就没有响应了。我们的主站点的生产数据库存在一些锁定问题,几乎每个请求都抛出异常,以及其他一些我们在测试阶段没有探索过的错误。我们主站点的服务器集群,称为traceback-logger提交页面,每秒几次k次。这对于托管回溯记录器的小型服务器来说太过分了(它已经是旧服务器,仅用于开发目的)。

此时CouchDB相当受欢迎,所以我决定试一试并用它编写一个小型的追溯记录器。新的记录器只包含一个python文件,它提供了一个包含排序和过滤器选项的错误列表以及一个提交页面。在后台我开始了CouchDB流程。新软件对所有请求的响应非常快,我们能够查看大量的自动错误报告。

一个有趣的事情是,之前的解决方案是在旧的专用服务器上运行,另一方面,新的基于CouchDB的站点仅在资源非常有限的共享xen实例上运行。我甚至没有使用键值存储的强度来横向扩展。 CouchDB / Erlang OTP处理并发请求而不锁定任何内容的能力已足以满足需求。

现在,快速编写的CouchDB-traceback记录器仍在运行,是探索主网站上的错误的有用方法。无论如何,大约每月一次数据库变得太大而CouchDB进程被杀死了。但是,CouchDB的compact-db命令再次将大小从几GB减少到一些KB,并且数据库再次启动并运行(也许我应该考虑在那里添加一个cronjob ... 0)。

总结一下,CouchDB肯定是这个子项目的最佳选择(或者至少是比MySQL更好的选择),并且它的工作做得很好。

答案 2 :(得分:22)

托德霍夫的highscalability.com有很多关于NoSQL的报道,包括一些案例研究。

商业Vertica柱状DBMS可能适合您的目的(即使它支持SQL):与传统的关系DBMS相比,它与分析查询相比非常快。参见Stonebraker等人的recent CACM paper对比Vertica和map-reduce。

更新:和其他几个人一样Twitter's selected Cassandra,包括HBase,Voldemort,MongoDB,MemcacheDB,Redis和HyperTable。

更新2:Rick Cattell刚刚发布了High Performance Data Stores中几个NoSQL系统的比较。而highscalability.com对Rick的论文是here

答案 3 :(得分:8)

我们将部分数据从mysql移动到mongodb,不仅仅是为了扩展性,而是因为它更适合文件和非表格数据。

在生产中,我们目前存储:

  • 25,000个文件(60GB)
  • 1.3亿其他“文件”(350GB)

每日营业额约为10GB。

使用mongodb python api(pymongo),使用apache / wsgi / python客户端在两个节点(6x450GB sas raid10)上以“配对”配置部署数据库。磁盘设置可能有点过分,但这就是我们用于mysql的内容。

除了pymongo线程池的一些问题和mongodb服务器的阻塞性质之外,它还是一个很好的体验。

答案 4 :(得分:5)

我为违反您的大胆文本而道歉,因为我没有任何第一手经验,但这组博客文章是解决CouchDB问题的一个很好的例子。

CouchDB: A Case Study

基本上,textme应用程序使用CouchDB来处理爆炸性数据问题。他们发现SQL处理大量存档数据的速度太慢,并将其移至CouchDB。这是一个很好的阅读,他讨论了整个过程,找出CouchDB可以解决的问题以及他们最终如何解决这些问题。

答案 5 :(得分:5)

我们将用于存储在Postgresql和Memcached中的一些数据移动到Redis。键值存储更适合存储分层对象数据。与使用ORM将blob映射到RDBMS相比,您可以更快地存储blob数据,并且开发时间和精力更少。

我有一个open source c# redis client,可让你用1行存储和检索任何POCO对象:

var customers = redis.Lists["customers"]; //Implements IList<Customer>
customers.Add(new Customer { Name = "Mr Customer" });

键值存储也更容易“向外扩展”,因为您可以添加新服务器,然后均匀地分配负载以包含新服务器。重要的是,没有中央服务器会限制您的可扩展性。 (尽管您仍然需要一种策略来进行一致性散列来分发您的请求)。

我认为Redis是类固醇的“托管文本文件”,为多个客户端提供快速,并发和原子访问,因此我以前使用文本文件或嵌入式数据库的任何东西现在都使用Redis。例如为了获得我们所有服务的实时组合滚动错误日志(这对我们来说一直是一项艰巨的任务),现在只需几行就可以完成,只需将错误预先挂起到Redis服务器端列表然后修剪列表,只保留最后1000个,例如:

var errors = redis.List["combined:errors"];
errors.Insert(0, new Error { Name = ex.GetType().Name, Message = ex.Message, StackTrace = ex.StackTrace});
redis.TrimList(errors, 1000);

答案 6 :(得分:4)

我没有第一手经验。但我发现this博客条目非常有趣。

答案 7 :(得分:3)

我发现将软件域对象(例如aSalesOrder,aCustomer ...)映射到二维关系数据库(行和列)的努力需要大量代码来保存/更新,然后再次实例化域对象实例来自多个表。更不用说拥有所有这些连接的性能损失,所有这些磁盘读取......只是为了查看/操作域对象,例如销售订单或客户记录。

我们已切换到对象数据库管理系统(ODBMS)。它们超出了列出的noSQL系统的功能。 GemStone / S(用于Smalltalk)就是这样一个例子。还有其他ODBMS解决方案,可以使用多种语言的驱动程序。一个关键的开发人员利益,您的类层次结构自动是您的数据库模式,子类和所有。只需使用面向对象的语言使对象持久化到数据库。 ODBMS系统提供ACID级别的交易完整性,因此它也适用于金融系统。

答案 8 :(得分:3)

我从MySQL(InnoDB)切换到cassandra用于M2M系统,该系统基本上为每个设备存储传感器的时间序列。每个数据都由(device_id,date)和(device_id,type_of_sensor,date)索引。 MySQL版本包含2000万行。

MySQL的:

  • 在主 - 主同步中设置。围绕失去同步几乎没有出现问题。这很紧张,特别是在开始时可能需要数小时才能修复。
  • 插入时间不是问题,但随着数据的增长,查询需要越来越多的内存。问题是索引被视为一个整体。就我而言,我只使用了加载到内存中所需的非常薄的索引部分(只有少数设备经常被监控,并且它是在最新的数据上)。
  • 难以备份。 Rsync无法对大型InnoDB表文件进行快速备份。
  • 很快就发现无法更新繁重的表架构,因为它占用了太多时间(小时)。
  • 导入数据需要数小时(即使最后完成索引)。最好的救援计划是始终保留一些数据库副本(数据文件+日志)。
  • 从一家托管公司迁移到另一家非常重要。必须非常小心地处理复制。

卡桑德拉:

  • 比MySQL更容易安装。
  • 需要大量内存。一个2GB的实例无法让它在第一个版本中运行,现在它可以在1GB的实例上工作,但它不是想法(太多的数据刷新)。在我们的情况下,给它8GB就足够了。
  • 一旦了解了如何组织数据,就可以轻松存储。请求有点复杂。但是一旦你解决它,它真的很快(除非你真的想要,否则你真的不会犯错)。
  • 如果上一步做得正确,那就是并保持超快速。
  • 几乎看起来数据被组织为备份。每个新数据都将添加为新文件。我个人而言,每次晚上和每次关机之前(通常用于升级)刷新数据并不是一件好事,因此恢复所需的时间更少,因为我们阅读的日志更少。如果它们被压缩,它不会创建太多文件。
  • 导入数据的速度很快。你拥有的主机越多越快。导出和导入千兆字节的数据不再是问题。
  • 没有架构是一件非常有趣的事情,因为您可以让您的数据发展以满足您的需求。这可能意味着在同一列族中同时拥有不同版本的数据。
  • 添加主机很简单(虽然不是很快),但我还没有在多数据中心设置上完成。

注意:我还使用了elasticsearch(基于lucene的文档),我认为它应该被视为NoSQL数据库。它是分布式的,可靠的并且通常很快(一些复杂的查询可以执行得非常糟糕)。

答案 9 :(得分:2)

我没有。我想使用一个简单的免费键值存储,我可以在进程中调用,但这种东西在Windows平台上不存在。现在我使用Sqlite,但我想使用像Tokyo Cabinet这样的东西。 BerkeleyDB拥有许可证“问题”。

但是,如果您想使用Windows操作系统,您选择的NoSQL数据库是有限的。而且并不总是有一个C#提供者

我确实尝试过MongoDB,它比Sqlite快40倍,所以也许我应该使用它。但我仍然希望有一个简单的过程解决方案。

答案 10 :(得分:2)

我使用redis在机器上存储日志消息。它非常容易实现,非常有用。 Redis真的很摇滚

答案 11 :(得分:2)

我们用CouchDB文档数据库替换了postgres数据库,因为没有固定模式对我们来说是一个很大的优势。每个文档都有可变数量的索引用于访问该文档。

答案 12 :(得分:1)

我过去使用过Couchbase,遇到了重新平衡问题和其他问题。目前我在几个生产项目中使用Redis。我正在使用redislabs.com这是Redis的托管服务,负责扩展您的Redis群集。我在http://thomasjaeger.wordpress.com的博客上发布了一个关于对象持久性的视频,展示了如何在提供者模型中使用Redis以及如何将C#对象存储到Redis中。看一看。

答案 13 :(得分:1)

我鼓励任何阅读此内容的人再次尝试使用Couchbase,因为3.0已经出门了。首发有200多个新功能。 Couchbase Server的性能,可用性,可扩展性和易管理功能使数据库非常灵活,高度可用。管理UI是内置的,API自动发现集群节点,因此不需要从应用程序到数据库的负载均衡器。 虽然我们目前没有托管服务,但您可以在AWS,RedHat Gears,Cloudera,Rackspace,DockS Containers(如CloudSoft等)上运行couchbase等等。关于重新平衡,取决于您具体指的是什么,但Couchbase在节点故障后没有按照设计自动重新平衡,但管理员可以为第一个节点故障设置自动故障转移并使用我们的API您也可以在使其活动或使用RestAPI之前,可以访问副本vbuckets以进行读取,您可以通过监视工具强制执行故障转移。这是一个特例,但可以做到。

我们倾向于不在几乎任何模式下重新平衡,除非节点完全脱机并且永远不会返回或者新节点已准备好自动平衡。以下是一些指南,可以帮助任何有兴趣了解NoSQL数据库性能最高的人。

  1. Couchbase Server 3.0
  2. Administration Guide
  3. REST API
  4. Developer Guides
  5. 最后,我还建议您查看N1QL以进行分布式查询:

    1. N1QL Tutorial
    2. N1QL Guide
    3. 感谢阅读,让我或其他人知道您是否需要更多帮助!

      奥斯汀

答案 14 :(得分:0)

我过去使用过Vertica,它依靠列压缩并加快磁盘读取速度并降低存储需求,以充分利用您的硬件。更快的数据加载和更高的并发性使您能够以最小的延迟为更多用户提供分析数据。

之前,我们正在查询具有数十亿条记录的Oracle数据库,并且性能非常欠佳。即使使用SSD进行了优化,查询仍需要8到12秒才能运行。因此,我们感到有必要使用更快的读取优化,面向分析的数据库。通过将Vertica Clusters置于精益服务层的后面,我们可以运行亚秒级性能的API。

Vertica以优化查询执行的格式将数据存储在投影中。与实例化视图类似,投影将结果集存储在磁盘或SSD上,而不是每次在查询中使用它们时都对其进行计算。投影具有以下优点:

  1. 压缩和编码数据以减少存储空间。
  2. 简化跨数据库集群的分布。
  3. 提供高可用性和恢复。

Vertica通过使用分段在整个群集中分布数据来优化数据库。

  1. 分段将部分数据放在节点上。
  2. 它将数据均匀分布在所有节点上。因此,每个节点执行 整个查询过程。
  3. 查询在集群上运行,每个节点都接收到该查询 计划。
  4. 查询的结果被汇总并用于创建 输出。

有关更多信息,请参阅Vertica文档@ https://www.vertica.com/knowledgebase/