我正在构建一个跟踪和验证广告展示次数和点击次数的系统.这意味着有很多插入命令(大约平均90 /秒,峰值为250)和一些读取操作,但重点是性能并使其快速.
该系统目前在MongoDB上,但从那时起我就被介绍给Cassandra和Redis.去两个解决方案中的一个,而不是留在MongoDB上是不是一个好主意?为什么或者为什么不?
谢谢
对于像这样的收获解决方案,我建议采用多阶段方法.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专门)不能跨不同的数据集进行连接或复杂查询.
我目前正在为一个非常大的广告网络工作,我们写平面文件:)
我个人是Mongo的粉丝,但坦率地说,Redis和Cassandra不太可能表现更好或更差.我的意思是,你所做的只是将内容扔进内存然后在后台刷新到磁盘(Mongo和Redis都这样做).
如果您正在寻找超快的速度,另一种选择是在本地内存中保留多次展示,然后每分钟左右刷新一次磁盘.当然,这基本上就是Mongo和Redis为你做的事情.移动并不是一个真正令人信服的理由.
所有三种解决方案(如果算上平面文件,则为四种)将为您提供极快的写入速度.非关系(nosql)解决方案将为您提供可调容错,以便进行灾难恢复.
在规模方面,我们的测试环境只有三个MongoDB节点,每秒可以处理2-3k个混合事务.在8个节点,我们每秒可处理12k-15k混合事务.卡桑德拉可以扩大规模.250次读取是(或应该)没有问题.
更重要的问题是,您想对这些数据做些什么?运营报告?时间序列分析?临时模式分析?实时报道?
如果您希望能够根据集合中的多个属性进行临时分析,那么MongoDB是一个不错的选择.您可以在集合上放置最多40个索引,尽管索引将存储在内存中,因此请注意大小.但结果是灵活的分析解决方案.
Cassandra是一家超值商店.您可以在前面定义一个静态列或一组列作为主索引.针对Cassandra运行的所有查询都应调整到此索引.你可以在它上面放一个辅助设备,但这就是它的全部内容.当然,您可以使用MapReduce扫描商店以获取非密钥属性,但它只是:通过商店进行串行扫描.Cassandra在服务器节点上也没有"喜欢"或正则表达式操作的概念.如果要查找名字以"Alex"开头的所有客户,则必须扫描整个集合,为每个条目提取第一个名称,然后通过客户端正则表达式运行它.
我对Redis不够熟悉,不能聪明地谈论它.抱歉.
如果您正在评估非关系平台,您可能还需要考虑CouchDB和Riak.
希望这可以帮助.
刚发现这个:http://blog.axant.it/archives/236
引用最有趣的部分:
第二个图是关于Redis RPUSH vs Mongo $ PUSH vs Mongo insert,我发现这个图非常有趣.即使与Redis RPUSH相比,mongodb $ push也可以更快地达到5000个条目,然后它变得非常慢,可能mongodb阵列类型具有线性插入时间,因此它变得越来越慢.mongodb可能通过暴露恒定时间插入列表类型获得一些性能,但即使使用线性时间数组类型(可以保证恒定时间查找),它也可以应用于小型数据集.
我想一切至少取决于数据类型和数量.最好的建议可能是对典型数据集进行基准测试并看看自己.
根据Benchmarking Top NoSQL数据库(在这里下载),我推荐Cassandra.