我正在构建一个跟踪和验证广告展示次数和点击次数的系统。这意味着有很多插入命令(大约90 /秒平均值,峰值为250)和一些读取操作,但重点是性能并使其超快速。
该系统目前在MongoDB上,但从那时起我就被介绍给Cassandra和Redis。去两个解决方案中的一个,而不是留在MongoDB上是不是一个好主意?为什么或为什么不呢?
谢谢
答案 0 :(得分:28)
对于这样的采伐解决方案,我建议采用多阶段方法。 Redis擅长实时通信。 Redis被设计为内存中的键/值存储,并继承了作为内存数据库的一些非常好的好处:O(1)列表操作。只要在服务器上使用RAM,Redis就不会减慢推送到列表末尾的速度,当你需要以极高的速率插入项目时这是很好的。遗憾的是,Redis无法使用大于您拥有的RAM数量的数据集(它只写入到磁盘,读取用于重新启动服务器或系统崩溃)并且必须进行扩展由您和您的应用程序完成。 (一种常见的方法是在众多服务器之间传播密钥,这是由一些Redis驱动程序实现的,特别是那些用于Ruby on Rails的驱动程序。)Redis也支持简单的发布/订阅消息传递,这也很有用。
在这种情况下,Redis是“第一阶段”。对于每种特定类型的事件,您可以使用唯一名称在Redis中创建列表;例如,我们有“页面浏览”和“链接点击”。为简单起见,我们希望确保每个列表中的数据是相同的结构;单击链接可能具有用户令牌,链接名称和URL,而查看的页面可能只有用户令牌和URL。您首先要关心的是它发生的事实以及您需要的所有绝对必要的数据。
接下来,我们有一些简单的处理工作人员从Redis的手中取出这个疯狂插入的信息,要求它从列表的末尾取一个项目并将其移交。工作人员可以进行任何调整/重复数据删除/ ID查找,以正确归档数据并将其移交给更永久的存储站点。尽可能多地启动这些工作人员,以保持Redis的内存负载可忍受。你可以用任何你想要的东西编写工作者(Node.js,C#,Java,...),只要它有一个Redis驱动程序(现在大多数网络语言都有)和一个用于你想要的存储(SQL,Mongo等)。 )
MongoDB擅长文档存储。与Redis不同,它能够处理大于RAM的数据库,并且它支持自己的分片/复制。 MongoDB优于基于SQL的选项的一个优点是您不必拥有预定的模式,您可以随时更改数据的存储方式。
然而,我会建议Redis或Mongo进行处理数据的“第一步”阶段,并使用传统的SQL设置(可能是Postgres或MSSQL)来存储后处理数据。跟踪客户端行为听起来像关系数据给我,因为您可能想要“显示每个查看此页面的人”或“这个人在这一天查看了多少页”或“总共有多少观众? ”。可能会有更复杂的连接或查询用于您提出的分析目的,而成熟的SQL解决方案可以为您执行大量此类过滤; NoSQL(Mongo或Redis专门)不能跨不同的数据集进行连接或复杂查询。答案 1 :(得分:21)
我目前正在为非常大型广告网络工作,我们会写入平面文件:)
我个人是Mongo粉丝,但坦率地说,Redis和Cassandra不太可能表现更好或更差。我的意思是,你所做的只是将东西扔进内存然后在后台刷新到磁盘(Mongo和Redis都这样做)。
如果您正在寻找超快的速度,另一种选择是在本地内存中保留多次展示,然后每分钟左右刷新一次磁盘。当然,这基本上就是Mongo和Redis为你做的事情。不是一个真正令人信服的理由。
答案 2 :(得分:12)
所有三种解决方案(如果计算平面文件,则为四种)将为您提供极快的写入速度。非关系(nosql)解决方案将为您提供可调容错,以便进行灾难恢复。
就规模而言,我们的测试环境只有三个MongoDB节点,每秒可以处理2-3k个混合事务。在8个节点,我们每秒可处理12k-15k混合事务。卡桑德拉可以扩大规模。 250次读取是(或应该)没有问题。
更重要的问题是,您想对这些数据做什么?运营报告?时间序列分析?临时模式分析?实时报告?
如果您希望能够根据集合中的多个属性进行临时分析,那么MongoDB是一个不错的选择。您可以在集合上放置最多40个索引,尽管索引将存储在内存中,因此请注意大小。但结果是灵活的分析解决方案。
Cassandra是一家超值商店。您可以在前面定义一个静态列或一组列作为主索引。针对Cassandra运行的所有查询都应调整到此索引。你可以在它上面放一个辅助设备,但这就是它的全部内容。当然,您可以使用MapReduce扫描商店以获取非密钥属性,但它只是:通过商店进行串行扫描。 Cassandra在服务器节点上也没有“喜欢”或正则表达式操作的概念。如果要查找名字以“Alex”开头的所有客户,则必须扫描整个集合,为每个条目提取第一个名称,然后通过客户端正则表达式运行。
我对Redis不够熟悉,不能聪明地谈论它。遗憾。
如果您正在评估非关系平台,您可能还需要考虑CouchDB和Riak。
希望这有帮助。
答案 3 :(得分:9)
刚刚发现:http://blog.axant.it/archives/236
引用最有趣的部分:
这第二张图是关于Redis RPUSH vs Mongo $ PUSH vs Mongo insert,我发现这个图非常有趣。即使与Redis RPUSH相比,mongodb $ push也可以更快地达到5000个条目,然后它变得非常慢,可能mongodb阵列类型具有线性插入时间,因此它变得越来越慢。 mongodb可以通过暴露恒定时间插入列表类型获得一些性能,但即使使用线性时间数组类型(可以保证恒定时间查找),它也可以应用于小型数据集。
我想一切至少取决于数据类型和数量。最好的建议可能是对典型数据集进行基准测试并看看自己。
答案 4 :(得分:6)
根据Benchmarking Top NoSQL数据库(download here) 我推荐Cassandra。
答案 5 :(得分:3)
如果你有选择(并且需要远离平坦的fies),我会选择Redis。它非常快,可以轻松处理您正在谈论的负载,但更重要的是,您不必管理刷新/ IO代码。我理解它很直接,但管理的代码要少于更多代码。
您还可以使用Redis获得水平扩展选项,这些选项可能无法通过基于文件的缓存获得。
答案 6 :(得分:2)
插入数据库的问题是它们通常需要在磁盘上为每个插入写入随机块。你想要的是每10次插入只写入磁盘的东西,理想情况下是顺序块。
平面文件很好。可以使用merge-sorty map-reducy类型算法以可伸缩的方式从平面文件获得摘要统计(例如,每页的总命中数)。滚动你自己并不难。
SQLite现在支持Write Ahead Logging,它也可以提供足够的性能。
答案 7 :(得分:2)
我可以在简单的350美元戴尔上使用MongoDB获得大约30k插入/秒。如果你只需要大约2k插入/秒,我会坚持使用MongoDB并将其分成可扩展性。也许还会考虑使用Node.js或类似的东西来使事情更加异步。
答案 8 :(得分:0)
好吧,我不是想挖坟,
我没有经历过任何提到的那些,但我有使用 InfluxDB 作为具有高写入的 NoSQL 解决方案的经历。它声称是 faster than MongoDB 但我再次相信这取决于我们的用例。如果你使用的数据结构更多的是时间序列,为什么不试试 InfluxDB?
答案 9 :(得分:-6)
我有mongodb,couchdb和cassandra的实践经验。我将很多文件转换为base64字符串并将这些字符串插入到nosql中 mongodb是最快的。卡桑德拉是最慢的。 couchdb也很慢。
我认为mysql会比所有这些都快得多,但我还没有为我的测试用例尝试mysql。