MongoDB vs. Redis与Cassandra之间的快速写入临时行存储解决scheme

我正在构build一个跟踪和validation广告展示次数和点击次数的系统。 这意味着有很多插入命令(平均每秒90次,峰值为250)和一些读取操作,但重点在于性能,并使其非常快速。

该系统目前在MongoDB上,但自那时以来我已经被介绍给了Cassandra和Redis。 去这两个解决scheme之一,而不是留在MongoDB上是一个好主意吗? 为什么或者为什么不?

谢谢

对于这样的收获解决scheme,我会推荐一个多阶段的方法。 Redis擅长实时通信 。 Redis被devise为内存中的键/值存储,并inheritance了作为内存数据库的一些非常好的好处:O(1)列表操作。 只要在服务器上使用RAM,Redis将不会减慢推送到列表的末尾,当您需要以极高的速率插入项目时,这是很好的select。 不幸的是,Redis无法使用大于您拥有的RAM数量的数据集(只写入磁盘,读取数据用于重新启动服务器或系统崩溃),并且扩展必须由您的应用程序完成 。 (一种常见的方法是将密钥分散到多个服务器上,这些服务器由一些Redis驱动程序实现,特别是用于Ruby on Rails的驱动程序。)Redis也支持简单的发布/订阅消息传递,这也可能有用。

在这种情况下,Redis是“第一阶段”。 对于每种特定types的事件,您都使用唯一的名称在Redis中创build一个列表; 例如我们有“浏览页面”和“链接点击”。 为了简单起见,我们要确保每个列表中的数据是相同的结构; 链接点击可能有一个用户令牌,链接名称和URL,而查看的页面可能只有用户令牌和URL。 你的第一个担心就是事实发生了,你需要的任何绝对必要的数据都会被推送出去

接下来,我们有一些简单的处理工作人员,将这个疯狂插入的信息从Redis的手中拿走,要求它从列表的末尾取下一个项目并交给他们。 工作人员可以进行任何调整/重复数据删除/ ID查找,以正确归档数据并将其交给更永久的存储站点。 为了保持Redis的内存负载,需要尽可能多地启动这些工作。 只要它有一个Redis驱动程序(现在大多数Web语言),并且一个用于您想要的存储(SQL,Mongo等等),您可以使用任何您想要的方式(Node.js,C#,Java,…) )

MongoDB擅长文件存储 。 与Redis不同,它可以处理大于RAM的数据库,并且它自己支持分片/复制。 与基于SQL的选项相比,MongoDB的一个优点是您不必具有预定义的模式,您可以随时改变数据的存储方式。

不过,我会build议Redis或Mongo进行处理数据的“第一步”,并使用传统的SQL设置(Postgres或MSSQL)来存储后处理数据。 跟踪客户行为听起来像关系数据,因为您可能想要“显示所有查看此页面的人”或“此人在此特定date查看了多less页”或“哪一天的观众人数最多? ”。 为了达到分析的目的,可能会有更复杂的连接或查询,而成熟的SQL解决scheme可以为您做很多这样的过滤; NoSQL(特别是Mongo或Redis)不能对不同的数据集进行连接或复杂的查询。

我目前的工作是一个非常大的广告networking,我们写平面文件:)

我个人是一个Mongo粉丝,但坦率地说,Redis和Cassandra不可能performance更好或更差。 我的意思是,你所做的只是将东西扔到内存中,然后在后台刷新到磁盘(Mongo和Redis都这样做)。

如果你正在寻找快速的速度,另一种select是在本地内存中保留几个印象,然后每分钟刷新一次。 当然,这基本上是Mongo和Redis为你做的。 没有一个真正令人信服的理由移动。

所有这三种解决scheme(四个如果你计算平面文件)会给你快速的写作。 非关系型(nosql)解决scheme也会为灾难恢复提供可调整的容错function。

就规模而言,我们的testing环境只有三个MongoDB节点,每秒可以处理2-3k个混合事务。 在8个节点上,我们可以每秒处理12k-15k个混合事务。 卡桑德拉的规模可能更高。 250读是(或应该是)没有问题。

更重要的问题是,你想用这些数据做什么? 运营报告? 时间序列分析? 特设模式分析? 实时报告?

如果您希望能够根据集合中的多个属性进行即席分析,那么MongoDB是一个不错的select。 您可以在一个集合上放置多达40个索引,尽pipe索引将被存储在内存中,所以请注意大小。 但结果是一个灵活的分析解决scheme。

卡桑德拉是一家重要的商店。 您可以定义一个静态列或一组列作为您的主要索引。 所有针对Cassandra运行的查询都应该被调整到这个索引。 你可以把它放在第二位,但是就这一点而言。 当然,您可以使用MapReduce来扫描商店中的非关键属性,但这只是:通过商店的串行扫描。 Cassandra在服务器节点上也没有“like”或regex操作的概念。 如果你想find名字以“Alex”开头的所有客户,你必须扫描整个集合,为每个条目抽出名字并通过客户端正则expression式运行。

我不太熟悉Redis聪明地谈论它。 抱歉。

如果您正在评估非关系平台,那么您可能还需要考虑CouchDB和Riak。

希望这可以帮助。

刚刚发现这个: http : //blog.axant.it/archives/236

引用最有趣的部分:

这第二张图是关于Redis RPUSH与Mongo $ PUSH与Mongo插入,我觉得这个图真的很有趣。 多达5000个条目mongodb $ push与Redis RPUSH相比速度更快,然后变得非常慢,可能是mongodb数组types具有线性插入时间,所以它变得越来越慢。 mongodb可能会通过暴露一个恒定的时间插入列表types来获得一些性能,但是即使使用线性时间数组types(这可以保证恒定的时间查找),它也可以用于小数据集。

我猜一切至less取决于数据types和数量。 最好的build议可能是基准你的典型数据集,看看你自己。

根据NoSQL数据库评测标准( 下载地址 ),我推荐Cassandra。 在这里输入图像说明

如果你有select(并且需要摆脱平面),我会和Redis一起去。 它的速度非常快,可以轻松处理您正在讨论的负载,但更重要的是,您不必pipe理冲洗/ IO代码。 我理解它非常简单,但更less的代码pipe理比更好。

您还将获得Redis的水平缩放选项,您可能无法使用基于文件的caching。

插入到数据库中的问题是,它们通常需要为每个插入写入磁盘上的随机块。 你想要的东西只能写入磁盘每10插入左右,理想情况下顺序块。

平面文件是好的。 汇总统计(例如每页总点击次数)可以使用合并分类映射简化型algorithm以可扩展的方式从平面文件中获得。 推出自己并不难。

SQLite现在支持预写式日志logging,这也可以提供足够的性能。

我可以在简单的350美元戴尔上用MongoDB获得每秒30k的插入。 如果你只需要大约2k插入/秒,我会坚持使用MongoDB,并将其分解为可扩展性。 也许还可以考虑使用Node.js或类似的东西来做一些更asynchronous的事情。

我有mongodb,couchdb和cassandra的实践经验。 我将很多文件转换为base64string,并将这些string插入到nosql中。
mongodb是最快的。 cassandra是最慢的。 couchdb也很慢。

我认为mysql会比所有的更快,但是我没有为我的testing用例尝试mysql。