190

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(key-value,用 C 编写,由 Mixi.jp(日本社交网站)使用)

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

问题:

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

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

4

15 回答 15

50

我目前的项目实际上。

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

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

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

技术细节:在 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}
]
于 2010-02-23T09:16:33.997 回答
49

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

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

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

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

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

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

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

于 2010-02-24T17:59:03.747 回答
22

Todd Hoff 的highscalability.com对 NoSQL 有很多很好的报道,包括一些案例研究。

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

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

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

于 2010-02-23T23:52:04.633 回答
8

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

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

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

每天的营业额约为 10GB。

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

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

于 2010-02-24T20:33:40.003 回答
5

由于我没有任何第一手经验,我很抱歉反对您的粗体文本,但是这组博客文章是解决 CouchDB 问题的一个很好的例子。

CouchDB:案例研究

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

于 2010-02-22T19:51:43.043 回答
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);
于 2010-02-28T10:55:09.283 回答
4

我没有第一手经验,但我发现这篇博文很有趣。

于 2010-02-18T14:01:31.133 回答
3

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

MySQL:

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

卡桑德拉:

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

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

于 2013-04-08T18:28:42.777 回答
3

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

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

于 2010-08-27T18:48:01.103 回答
2

I used redis to store logging messages across machines. It was very easy to implement, and very useful. Redis really rocks

于 2010-02-18T22:12:22.783 回答
2

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

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

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

于 2010-02-18T09:02:38.290 回答
2

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

于 2010-02-24T18:28:40.397 回答
1

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

于 2015-01-04T01:14:02.233 回答
1

既然 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. REST API
  4. 开发者指南

最后,我还鼓励您查看 N1QL 以进行分布式查询:

  1. N1QL 教程
  2. N1QL 指南

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

奥斯汀

于 2015-01-07T00:08:14.250 回答
0

I have used Vertica in the past.It relies on columnar compression & expedites disk reads and lowers storage needs to make the most of your hardware. Faster data loads and higher concurrency lets you serve analytics data to more users with minimum latency.

Earlier, we were querying Oracle database having billions of records & the performance was very sub-optimal. The queries took 8 to 12s to run, even after optimizing with SSD. Hence, we felt the need to use a faster read optimized, analytics oriented database. With Vertica Clusters behind the lean service layer, we could run APIs with sub-second performance.

Vertica stores data in projections in a format that optimizes query execution. Similar to materialized views, projections store result sets on disk OR SSD rather than compute them each time they are used in a query.Projections provide the following benefits:

  1. Compress and encode data to reduce storage space.
  2. Simplify distribution across the database cluster.
  3. Provide high availability and recovery.

Vertica optimizes the database by distributing data across cluster using Segmentation.

  1. Segmentation places a portion of data on a node.
  2. It evenly distributes data on all nodes. Thus, each node performs a piece of the querying process.
  3. The query runs on the cluster and every node receives the query plan.
  4. The results of the queries are aggregated and used to create the output.

For more, please refer to Vertica documentation @ https://www.vertica.com/knowledgebase/

于 2019-02-04T08:36:44.117 回答