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


189

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

  • 卡桑德拉(表格,用Java编写,由Cisco,WebEx,Digg,Facebook,IBM,Mahalo,Rackspace,Reddit和Twitter使用)
  • CouchDB(用Erlang编写的文档,由BBC和Engine Yard使用)
  • 炸药(键值,用Erlang编写,由Powerset使用)
  • HBase的(键值,用Java编写,由Bing使用)
  • 超表表(表格,用C ++编写,由百度使用)
  • (键值,用Erlang编写)
  • 内存缓存数据库(键值,用C编写,由Reddit使用)
  • MongoDB(用C ++编写的文档,由Electronic Arts,Github,NY Times和Sourceforge使用)
  • Neo4j(图形,用Java编写,一些瑞典大学使用)
  • 伏地魔计划(键值,用Java编写,LinkedIn使用)
  • 雷迪斯(键值,用C编写,由Craigslist,Engine Yard和Github使用)
  • 里亚克(键值,用Erlang编写,由Comcast和Mochi Media使用)
  • 林哥(键值,用Erlang编写,由诺基亚使用)
  • Scalaris(键值,用Erlang编写,由OnScale使用)
  • Terrastore(文档,用Java编写)
  • ThruDB(文档,用C ++编写,由JunkDepot.com使用)
  • 东京内阁/东京暴君(键值,用C编写,由Mixi.jp(日本社交网站)使用)

我想了解您-SO阅读器-使用数据存储已解决的特定问题以及您使用的NoSQL数据存储。

问题:

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

我正在寻找第一手经验,因此,除非您有经验,否则请不要回答。


6
bignose:我认为赏金是我给提供最翔实答案的人的550点声誉小技巧:-)
knorv 2010年

1
不要忘记像GemStone / S这样的解决方案-Smalltalk对象存储。
兰德尔·施瓦兹

2
不要错过OrientDB(orientechnologies.com
Lvca 2011年

Answers:


49

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

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

不幸的是,该版本发布后不久,traceback-logger网站不再响应。我们的主站点的生产数据库存在一些锁定问题,该问题几乎引发了每个请求的异常,以及其他几个错误,而这些错误在测试阶段并未涉及。我们主站点的服务器集群称为traceback-logger提交页面,每秒几千次。对于托管了回溯记录器的小型服务器而言,这实在是太多了(它已经是一台旧服务器,仅用于开发目的)。

这时CouchDB相当流行,因此我决定尝试一下并用它编写一个小型的traceback-logger。新的记录器仅包含一个Python文件,该文件提供了带有排序和过滤选项的错误列表以及一个提交页面。在后台,我启动了一个CouchDB流程。新软件对所有请求的响应速度非常快,我们能够查看大量的自动错误报告。

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

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

总而言之,CouchDB无疑是该子项目的最佳选择(或者至少比MySQL更好的选择),并且它做得很好。


我想我读过某个地方,当未压缩的数据达到一定水平时,您可以使ouchdb自动进行压缩...
Ztyx 2010年

50

实际上是我当前的项目。

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

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

用商业术语来说:第一选择是不可行的。第二种选择意味着我们的应用程序可以工作。

技术细节:在MySQL上同时运行SQL和NoSQL!坚持使用MySQL以获得良好的事务支持,性能以及经过验证的往绩记录,以确保数据不损坏,扩展性相当好,支持集群等。

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

我们没有选择任何新的播放器(CouchDB,Cassandra,MongoDB等),因为尽管它们各自提供了出色的功能/性能,但我们的情况总是存在弊端(例如缺少Java支持/ 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}
]

2
这两个数据库(sql和NoSQL)在哪里?
mavnn'2

两者都是MySQL(我已经编辑了回复以提供此信息,但我最初忘记了它)。相同的数据库,SQL和NoSQL方法的性能差异很大。对MySQL的键/值方法非常满意。
布赖恩2010年

5
嗨,布莱恩,是否可以提供规范化结构的架构示例和键值对“模式”的示例?我们还面临规范化结构的性能问题,目前正在考虑两个选项:对表进行非规范化或转向NoSQL数据存储。由于我们已经在支付许可和维护费用,因此我们希望利用我们当前的Oracle堆栈,因此倾向于采用非规范化的RDBMS解决方案。一个例子会很有趣!
TTH

@Brian:由于示例中有4个是用Java编写的,因此缺少或不成熟的Java支持功能是什么?我没有这方面的经验,但是这对我来说似乎有点令人惊讶。
吉米

tthong-不知道如何简洁地包含我们的规范化架构,但是我添加了一个示例,说明如何将内容存储在单个文本字段中。这有点做作,我无法提供一个真实的例子,因为我的老板会弹道,所以这个“数据模型”的任何“问题”都是最可能的原因。我建议对Oracle和其他一些解决方案进行基准测试,但是如果您的组织具有良好的Oracle专业知识,DBA,备份等功能,那么可以考虑考虑以下方法
Brian

22

托德·霍夫(Todd Hoff)的highscalability.com对NoSQL进行了大量介绍,包括一些案例研究。

商业Vertica柱状DBMS可能适合您的目的(即使它支持SQL):与传统的关系DBMS进行分析查询相比,它非常快。请参见Stonebraker等人最近在CACM上发表的将Vertica与map-reduce对比的论文

更新:Twitter选择了Cassandra而不是其他几个,包括HBase,Voldemort,MongoDB,MemcacheDB,Redis和HyperTable。

更新2:Rick Cattell刚刚发布了高性能数据存储中几种NoSQL系统的比较。而highscalability.com对Rick的论文的看法就在这里



@ar:谢谢,这是一个很好的链接。Vertica员工产生了很多争议。
Jim Ferrans 2010年

8

我们将部分数据从mysql移至mongodb,不是为了扩展性,而是为了将其更适合文件和非表格数据而增加了更多。

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

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

每天的交易量约为10GB。

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

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


您能否详细说明一下您提到的问题?
felixfbecker

5

对于没有您的第一手经验,我不赞成您使用粗体字表示歉意,但是,这组博客文章是解决CouchDB问题的一个很好的例子。

CouchDB:一个案例研究

本质上,textme应用程序使用CouchDB来处理其爆炸性数据问题。他们发现SQL太慢,无法处理大量档案数据,并将其移至CouchDB。这是一本非常好的读物,他讨论了弄清楚CouchDB可以解决什么问题以及如何最终解决这些问题的整个过程。


5

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

我有一个开源的c#redis客户端,可让您用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);

4

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


3

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

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


3

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

MySQL:

  • 以主-主同步设置。失去同步的问题很少出现。压力很大,尤其是刚开始时可能要花几个小时才能解决。
  • 插入时间不是问题,但是随着数据的增长,查询需要越来越多的内存。问题是索引被视为一个整体。就我而言,我只使用了非常少量的索引,这些索引是加载到内存中的必要条件(只有很少的设备会经常受到监视,并且它是在最新的数据上)。
  • 这是很难备份。Rsync无法对大型InnoDB表文件进行快速备份。
  • 很快就很清楚,不可能更新重表架构,因为它花费了太多时间(数小时)。
  • 导入数据要花费数小时(即使最后完成索引也是如此)。最好的救援计划是始终保留数据库的几个副本(数据文件+日志)。
  • 从一家托管公司转移到另一家托管公司确实是一件大事。复制必须非常小心地处理。

卡桑德拉:

  • 比MySQL更容易安装。
  • 需要大量的RAM。2GB实例无法使其在第一个版本中运行,现在它可以在1GB实例上运行,但是不知道(太多数据刷新)。在我们的案例中,给它8GB就足够了。
  • 一旦了解了如何组织数据,存储就很容易了。请求有点复杂。但是一旦绕开它,它的速度就会非常快(除非真正愿意,否则您就不会犯错)。
  • 如果正确完成了上一步,那么它将保持超快。
  • 看起来好像是组织了要备份的数据。每个新数据都将作为新文件添加。我个人而言,但这不是一件好事,每天晚上和每次关机之前(通常是用于升级)刷新数据,这样还原所需的时间更少,因为要读取的日志更少。压缩不会创建太多文件。
  • 导入数据的速度非常快。主机越多,速度越快。导出和导入千兆字节的数据不再是问题。
  • 没有架构是一件非常有趣的事情,因为您可以使数据不断发展以适应您的需求。这可能意味着同一列系列上同时具有不同版本的数据。
  • 添加主机很容易(虽然速度不快),但是我还没有在多数据中心设置中做到这一点。

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


2

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

但是,如果要使用Windows操作系统,则NoSQL数据库的选择受到限制。而且并不总是有C#提供程序

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


3
AC#提供程序基本上无关紧要,因为这些系统没有类似于常规数据库的接口(因此称为“ NoSQL”),因此ADO.NET接口将成为一个方孔。
MarkR 2010年

2
确实,您不需要实现ADO.NET接口的提供程序,但是仍然需要某种驱动程序/提供程序以在db和.NET之间进行耦合。MongoDB有一个功能,但还不完善。例如,异常处理需要改进。
Theo

我有一个Redis的开源C#客户端@ code.google.com/p/servicestack/wiki/ServiceStackRedis,它允许您将“类型的POCO”存储为文本Blob,并为Redis服务器提供IList <T>和ICollection <T>接口边列表和集合等
mythz 2010年

2

我使用redis来存储跨机器的日志消息。这非常容易实现,而且非常有用。Redis真的很摇滚


2

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


1

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


我知道这是遥不可及的,但是您在平衡方面特别遇到了哪些问题?
Seer

1

我会鼓励阅读此书的任何人都可以尝试Couchbase,因为3.0已经面世了。初学者有200多种新功能。Couchbase Server的性能,可用性,可伸缩性和易于管理的功能使数据库极为灵活,高度可用。管理UI是内置的,API会自动发现集群节点,因此无需从应用程序到数据库的负载平衡器。尽管我们目前没有托管服务,但是您可以在AWS,RedHat Gears,Cloudera,Rackspace,Docker Containers(例如CloudSoft)等产品上运行长沙发。关于重新平衡,具体取决于您所指的是什么,但是Couchbase不会在节点故障后按照设计自动地重新平衡,但是管理员可以为第一个节点故障设置自动故障转移,并且使用我们的API,您还可以在使其变为活动状态之前获得对副本vbucket进行读取的访问权限,或者使用RestAPI,可以通过监视工具强制执行故障转移。这是一种特殊情况,但可以完成。

除非节点完全脱机并且永不恢复运行,或者新节点准备好自动平衡,否则我们几乎不会在任何模式下进行重新平衡。这里有一些指南,可以帮助任何有兴趣了解性能最高的NoSQL数据库的人。

  1. Couchbase Server 3.0
  2. 管理指南
  3. REST API
  4. 开发人员指南

最后,我也鼓励您检查一下N1QL以进行分布式查询:

  1. N1QL教程
  2. N1QL指南

感谢您的阅读,如果您需要更多帮助,请告诉我或其他人!

奥斯丁


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/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.