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

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

  • Cassandra (用 Java 编写的表格,由 Cisco、 WebEx、 Digg、 Facebook、 IBM、 Mahalo、 Rackspace、 Reddit 和 Twitter 使用)
  • CouchDB (文档,在 Erlang 编写,由英国广播公司和 Engine Yard 使用)
  • Dynomite (键值,Erlang 编写,Powerset 使用)
  • HBase (键值,用 Java 编写,由 Bing 使用)
  • Hypertable (用 c + + 编写的表格,百度使用)
  • Kai (键值,在 Erlang 编写)
  • MemacheDB (键值,用 C 编写,由 Reddit 使用)
  • MongoDB (文档,用 C + + 编写,由 Electronic Arts、 Github、 NY Times 和 Sourceforge 使用)
  • Neo4j (图表,用 Java 编写,一些瑞典大学使用)
  • 项目 Voldemort (键值,用 Java 编写,由 LinkedIn 使用)
  • Redis (键值,用 C 编写,由 Craigslist、 Engine Yard 和 Github 使用)
  • Riak (键值,在 Erlang 编写,由 Comcast 和 Mochi Media 使用)
  • Ringo (键值,在 Erlang 编写,诺基亚使用)
  • Scalaris (key-value,用 Erlang 编写,由 OnScale 使用)
  • Terrastore (用 Java 编写的文档)
  • 东京内阁/东京暴君 (键值,用 C 写,由 Mixi.jp (日本社交网站)使用)

I'd like to know about specific problems you - the SO reader - have solved using data stores and what NoSQL data store you used.

问题:

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

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

18653 次浏览

我不知道。我想使用一个简单的和免费的键值存储,我可以在进程中调用,但这样的事情不存在虚假的 Windows 平台。现在我使用 Sqlite,但我想使用东京内阁之类的东西。BerkeleyDB 有许可证“问题”。

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

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

我没有第一手的经验,但我发现 这个的博客条目相当有趣。

我使用 redis 来跨机器存储日志消息。它非常容易实现,而且非常有用。雷迪斯真的很棒

我很抱歉违背了您的粗体文本,因为我没有任何第一手经验,但是这组博客文章是用 CouchDB 解决问题的一个很好的例子。

CouchDB: 案例研究

实际上,发短信应用程序使用 CouchDB 来处理数据爆炸问题。他们发现 SQL 速度太慢,无法处理大量的归档数据,于是将其转移到 CouchDB。这是一本优秀的读物,他讨论了找出 CouchDB 可以解决什么问题以及它们最终如何解决这些问题的整个过程。

实际上是我现在的项目。

在规范化结构中存储18,000个对象: 在8个不同的表中存储90,000行。检索它们并将其映射到我们的 Java 对象模型需要花费1分钟的时间,所有东西都被正确地索引了等等。

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

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

技术细节: 在 MySQL 上同时运行 SQL 和 NoSQL!坚持使用 MySQL,以获得良好的事务支持、性能,以及未损坏数据的经过验证的跟踪记录、相当好的伸缩性、对集群的支持等等。

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

我们没有选择任何新玩家(CouchDB、 Cassandra、 MongoDB 等) ,因为尽管它们各自提供了很好的特性/性能,但我们的环境总是有缺陷(例如缺少/不成熟的 Java 支持)。

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

更新: 这里有一个例子,我们如何表示文本内容,而不是我们实际的业务领域(我们不与“产品”工作) ,因为我的老板会拍摄我,但传达的想法,包括递归方面(一个实体,这里是一个产品,“包含”其他)。希望在一个规范化的结构中,这可以是相当多的表格,例如将一个产品加入到它的味道范围中,其他产品包含在其中,等等

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}
]

Todd Hoff 的 Highscalability.com有很多关于 NoSQL 的报道,包括一些案例研究。

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

更新: 和 推特选了卡珊德拉超过其他几个,包括 HBase、 Voldemort、 MongoDB、 MemacheDB、 Redis 和 HyperTable。

更新2: Rick Cattell 刚刚发布了一个 高性能数据存储中几个 NoSQL 系统的比较。Highscalability.com 对瑞克论文的看法是 给你

我将一个小的子项目从 MySQL 切换到 CouchDB,以便能够处理负载。

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

不幸的是,在发布后不久,追踪记录器网站就不再响应了。我们的主站点的生产数据库有一些锁定问题,几乎每个请求都会抛出异常,还有一些其他的 bug,我们在测试阶段还没有研究过。我们主站点的服务器集群,称为跟踪日志提交页面,每秒数千次。这对于托管了回溯日志记录器的小型服务器来说是一种过分的方式(它已经是一个旧的服务器,只用于开发目的)。

当时 CouchDB 相当流行,因此我决定试用它并用它编写一个小型的回溯日志记录器。新的日志记录器只包含一个 python 文件,该文件提供了带有排序和筛选选项的 bug 列表以及一个提交页面。在后台,我启动了一个 CouchDB 进程。新软件对所有请求的响应非常迅速,我们能够查看大量的自动错误报告。

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

现在,快速编写的 CouchDB-traceback 日志记录器仍在运行,它是探索主站点错误的有用方法。无论如何,大约每个月都会有一次数据库变得太大,CouchDB 进程被终止。但是,CouchDB 的 compact- db 命令再次将大小从几个 GB 减少到几个 KB,数据库就可以重新启动并运行了(也许我应该考虑在这里添加 cronjob... 0o)。

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

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

我们将部分数据从 mysql 移动到 mongodb,与其说是为了提高可伸缩性,不如说是为了更好地适应文件和非表格数据。

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

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

每天的流量大约是10GB。

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

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

我们已经将一些存储在 Postgresql 和 Memcached 中的数据转移到了 雷迪斯中。键值存储更适合于存储分层对象数据。与使用 ORM 将 blob 映射到 RDBMS 相比,存储 blob 数据的速度要快得多,开发时间和工作量也要少得多。

我有一个 开源 c # redis 客户端,让您存储和检索任何 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);

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

我们已经转向对象数据库管理系统(ODBMS)。它们超出了列出的 noSQL 系统的能力。GemStone/S (代表 Smalltalk)就是这样一个例子。还有一些其他的 ODBMS 解决方案具有针对多种语言的驱动程序。一个关键的开发人员的好处是,您的类层次结构自动是您的数据库模式、子类和所有。只需使用面向对象语言使对象持久化到数据库。ODBMS 系统提供了 ACID 级别的事务完整性,因此它也可以在金融系统中工作。

我为 M2M 系统从 MySQL (InnoDB)切换到 Cassandra,该系统基本上存储每个设备的传感器时间序列。每个数据都由(device _ id,date)和(device _ id,type _ of _ Sensor,date)索引。MySQL 版本包含2000万行。

MySQL:

  • 主-主同步中的设置。在 失去同步性周围出现了一些问题。压力很大,尤其是一开始可能要花几个小时才能缓解。
  • 插入时间不是问题,但 查询需要越来越多的内存随着数据的增长而增加。问题是这些索引都是作为一个整体来考虑的。在我的例子中,我只使用了内存加载所必需的索引中非常薄的一部分(只有少数设备经常受到监视,而且是在最近的数据上)。
  • Rsync 无法对大的 InnoDB 表文件进行快速备份。
  • 它很快变得清楚,它 无法更新重表模式,因为它花了太多的时间(小时)。
  • 导入数据需要花费数小时 (即使最终完成了索引)。最好的拯救计划是始终保留数据库的几个副本(数据文件 + 日志)。
  • 从一个托管公司移动 到另一个 真的是件大事。复制必须非常小心地处理。

卡桑德拉:

  • 甚至比 MySQL 更容易安装。
  • 需要大量内存。一个2GB 的实例不能让它在第一个版本中运行,现在它可以在一个1GB 的实例上工作,但是这不是主意(太多的数据刷新)。给它8GB 对我们来说已经足够了。
  • 一旦理解了如何组织数据,存储就变得容易了。请求有点复杂。但是一旦你绕过了它,它真的很快(除非你真的想要,否则你不可能真的犯错)。
  • 如果前一步做得正确,它将保持超快的速度。
  • 看起来好像数据是被组织起来备份的。每个新数据都作为新文件添加。我个人认为,这不是一件好事,每天晚上和每次关机(通常是为了升级)之前刷新数据,这样恢复所需的时间更少,因为我们可以读取的日志更少。它不会创建太多的文件,因为它们被压缩了。
  • 导入数据非常快。接待员越多,速度越快。导出和导入千兆字节的数据不再是问题。
  • 没有模式是一件非常有趣的事情,因为您可以让数据按照您的需要进化。这可能意味着在同一列族上同时拥有不同版本的数据。
  • 添加主机很容易(虽然不是很快) ,但是我还没有在多数据中心设置上完成。

注意: 我也使用了 弹性搜索(基于 lucene 的面向文档) ,我认为它应该被视为一个 NoSQL 数据库。它是分布式的、可靠的,而且通常速度很快(一些复杂的查询可能执行得非常糟糕)。

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

既然3.0已经出门了,我鼓励任何读到这篇文章的人再次尝试 Couchbase。对于初学者来说,有超过200个新特性。Couchbase Server 的性能、可用性、可伸缩性和易于管理的特性使其成为一个极其灵活、高可用性的数据库。管理 UI 是内置的,API 会自动发现集群节点,因此不需要从应用程序到数据库的负载平衡器。 虽然我们现在还没有一个托管服务,但是你可以在像 aWS、 RedHat Gears、 Cloudera、 Rackspace、像 CloudSoft 这样的 Docker 容器等等上运行 couchbase。关于重新平衡,它取决于你具体指的是什么,但 Couchbase 不会自动重新平衡后,按照设计,节点失败,但管理员可以设置自动故障转移的第一个节点失败,使用我们的 API,你也可以访问复制 vbucket 读取之前,使他们活跃或使用 RestAPI 你可以强制监视工具的故障转移。这是一个特例,但是是可以做到的。

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

  1. Couchbase Server 3.0
  2. 行政指引
  3. REST API
  4. 开发指南

最后,我还鼓励您检查分布式查询的 N1QL:

  1. N1QL 教程
  2. N1QL 指南

感谢您的阅读,让我或其他人知道,如果您需要更多的帮助!

奥斯汀

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

早些时候,我们查询 Oracle 数据库有数十亿条记录,性能非常不理想。即使在使用 SSD 进行优化之后,查询也需要8到12秒才能运行。因此,我们觉得有必要使用一个读取速度更快、面向分析的数据库。有了精益服务层后面的 Vertica 集群,我们可以运行性能低于秒级的 API。

Vertica 以优化查询执行的格式在投影中存储数据。与物化视图类似,投影将结果集存储在磁盘或 SSD 上,而不是每次在查询中使用它们时都进行计算。预测提供了以下好处:

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

Vertica 通过使用分段在集群之间分布数据来优化数据库。

  1. 分段将一部分数据放置在节点上。
  2. 它将数据均匀地分布在所有节点上 查询过程的一部分。
  3. 查询在集群上运行,每个节点接收查询 计划。
  4. 查询的结果进行聚合,并用于创建 输出。

更多信息,请参考 Vertica 文档@< a href = “ https://www.Vertica.com/Knowledge base/”rel = “ nofollow norefrer”> https://www.Vertica.com/knowledgebase/