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

  • 卡桑德拉 (表格,用 Java 编写,由 Cisco、WebEx、Digg、Facebook、IBM、Mahalo、Rackspace、Reddit 和 Twitter 使用)
  • 沙发数据库 (文档,用 Erlang 编写,由 BBC 和 Engine Yard 使用)
  • 炸药 (键值对,用 Erlang 编写,由 Powerset 使用)
  • 数据库 (键值对,用Java编写,Bing使用)
  • 超表 (表格,C++编写,百度使用)
  • (键值对,用 Erlang 编写)
  • 内存缓存数据库 (键值对,用C编写,Reddit使用)
  • MongoDB (文档,用 C++ 编写,被 Electronic Arts、Github、NY Times 和 Sourceforge 使用)
  • 新4j (图表,用 Java 编写,一些瑞典大学使用)
  • 伏地魔计划 (键值对,用Java编写,LinkedIn使用)
  • 雷迪斯 (键值对,用 C 语言编写,由 Craigslist、Engine Yard 和 Github 使用)
  • 里亚克 (键值对,用 Erlang 编写,Comcast 和 Mochi Media 使用)
  • 林檎 (键值对,用 Erlang 编写,诺基亚使用)
  • 斯卡拉里斯 (键值对,用 Erlang 编写,由 OnScale 使用)
  • 特拉存储 (文档,用Java编写)
  • 通过数据库 (文档,用 C++ 编写,由 JunkDepot.com 使用)
  • 东京内阁/东京暴君 (key-value,用C语言编写,Mixi.jp(日本社交网站)使用)

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

问题:

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

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

有帮助吗?

解决方案

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

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

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

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

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

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

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

其他提示

实际上是我当前的项目。

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

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

从商业角度来说:第一种选择不可行。第二个选项意味着我们的应用程序可以运行。

技术细节:在 MySQL 上运行 SQL 和 NoSQL!坚持使用 MySQL 以获得良好的事务支持、性能以及不损坏数据、良好扩展、支持集群等方面的良好记录。

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

我们没有选择任何新的参与者(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}
]

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

商业广告 维蒂卡 列式 DBMS 可能适合您的目的(即使它支持 SQL):与用于分析查询的传统关系 DBMS 相比,它的速度非常快。参见 Stonebraker 等人的 最近的 CACM 论文 将 Vertica 与 Map-Reduce 进行对比。

更新:和 Twitter 选定的 Cassandra 超过其他几个,包括 HBase、Voldemort、MongoDB、MemcacheDB、Redis 和 HyperTable。

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

我们将部分数据从 mysql 迁移到 mongodb,与其说是为了可扩展性,不如说是因为它更适合文件和非表格数据。

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

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

每日成交量约10GB。

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

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

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

沙发数据库:案例研究

本质上, 发短信给我 应用程序使用 CouchDB 来处理数据爆炸的问题。他们发现 SQL 太慢,无法处理大量档案数据,并将其转移到 CouchDB。这是一本很棒的读物,他讨论了弄清楚 CouchDB 可以解决哪些问题以及他们最终如何解决这些问题的整个过程。

我们已将一些用于存储在 Postgresql 和 Memcached 中的数据移至 雷迪斯. 。键值存储更适合存储分层对象数据。与使用 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);

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

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

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

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

MySQL:

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

卡桑德拉:

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

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

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

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

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

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

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

我过去使用过 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,您还可以访问在激活副本 vbuckets 之前进行读取,或者使用 RestAPI,您可以通过监控工具强制执行故障转移。这是一个特殊情况,但也是可以做到的。

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

  1. Couchbase服务器3.0
  2. 管理指南
  3. 休息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文档@ https://www.vertica.com/knowledgebase/

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top