2012-07-11 54 views
2

背景/意图:一次增加数百个计数器,redis或mongodb?

所以我要从头开始创建一个事件跟踪器,并有几个关于如何做到这一点的想法,但我不确定的最佳方式与数据库方面着手东西的。我有兴趣做的一件事是允许这些事件是完全动态的,但同时允许报告关系事件计数器。

例如,所有国家按操作系统细分。预期的效果将是:

  1. 美事件#
    • 的iOS - 事件#,在美国发生
    • 的Android - 事件#,在美国发生
  2. CA#的事件
    • iOS - 发生在CA的事件数#
    • Android - 发生在CA中的事件数#

我的意图是要能够接受这些事件的名字,像这样:

/?country=US&os=iOS&device=iPhone&color=blue&carrier=Sprint&city=orlando&state=FL&randomParam=123&randomParam2=456&randomParam3=789 

为了做关系计数器像上面我这意味着每个请求可能会增加100+个计数器。

假设每天会有上千万的上述请求。

我想让事情完全保持动态,而且我也希望以这种方式进行,以便数据查找保持超级快速。因此,我一直在研究如何使用redis或mongodb。

问题:

  1. 有没有更好的办法,同时保持动态的领域做到这一点,然后柜台?

  2. 如果这是全部在一个文件中(结构像一棵树),将在mongodb中使用$ inc操作符在一次操作中同时增加100个以上的计数器是可行的而不是缓慢的?这里的好处是,我可以在单个查询中快速检索一个“广告系列”的所有统计信息。

  3. 这会更适合于redis并为事件的所有适用计数器执行锌比?

感谢

+0

如何“动态”你需要它?即什么延迟?另一种方法是为每个事件存储文档,然后定期使用map-reduce来汇总数据。这样的方法也可以让你改变事后报告的内容(例如添加'奥兰多'的自定义报告)。 – 2012-07-11 22:38:43

+0

由于这是更多的市场营销信息,它将是理想的尽快提供。为什么我认为柜台可能很适合的另一个原因。 – Ataraxy 2012-07-12 00:51:02

回答

2

根据您的密钥结构的布局方式,我会建议流水线的zincr命令。你有一个简单的“提交”触发器 - 请求。如果你要迭代你的参数并且遍历每个键,那么在请求结束时通过execute命令将会非常快。我已经实现了一个系统,就像你在cgi和Django应用程序中描述的一样。我设置了一键结构一起的台词:

YYYY-MM-DD:HH:MM - >排序集合

,并能够处理事情是每秒150000-200000增量对Redis的侧有一个单一的过程,这应该是足够的你描述的情况。这个关键结构使我能够根据时间窗口获取数据。我还添加了一个过期的密钥,以避免编写一个数据库清理过程。然后我有了一个cronjob,它可以使用上述关键模式的变体来设置操作,以“汇总”每小时,每天和每周的统计数据。我提出这些想法是因为您可以利用Redis的内置功能来简化报告方面。还有其他的方式,但这种模式似乎运作良好。

正如eyossi指出的那样,全局锁定对于并行写入和读取的系统来说可能是一个真正的问题。如果您将此作为实时系统编写,那么并发性可能会成为问题。如果它是“结束日期”日志解析系统,那么它不可能触发争用,除非在输入时运行解析器或报告的多个实例。关于保持读取速度快在Redis中,我会考虑设置一个只读redis实例,从主引导文件中删除。如果您将其放在运行报告的服务器上,并将其指向报告进程,则应该非常快速地生成报告。

根据您的可用内存,数据集大小以及是否将任何其他类型的数据存储在redis实例中,您可能会考虑运行32位redis服务器以减少内存使用量。一个32b实例应该能够将很多这种类型的数据保存在一小块内存中,但是如果运行正常的64位Redis并没有占用过多的内存,可以随意使用它。与往常一样测试你自己的使用模式,以验证

+0

谢谢你的观点和建议。我实际上正在考虑以类似的方式进行。其目的是为了实现这一目标,并拥有多个用户和活动,因此可以将数据从Redis中滚出来,这可能会很棘手,因为这些参数可能会产生如此多的未知变化。我将不得不进一步思考这一点,但这应该是一个开始的好地方! – Ataraxy 2012-07-12 23:09:18

0

在Redis的,你可以使用multi同时递增多个键。

+0

非常感谢,玩了几分钟后,我想我可能会以这种方式结束。 – Ataraxy 2012-07-12 00:52:11

0

我对MongoDB有一些不好的经验,我发现当它有很多写入时它可能会非常棘手......

你可以看看this link了解更多信息,不要忘记阅读“MongoDB使用1 BFGL(大型全局锁定)”的部分(这可能已经在版本2.x中得到了改进 - 我没有检查它)

另一方面,我有一个很好的经验Redis,我用它进行了大量的读/写操作,效果很好。 你可以找到关于如何我使用Redis的更多信息(以获得有关并发量读取/写入感觉)位置:http://engineering.picscout.com/2011/11/redis-as-messaging-framework.html

+0

欣赏链接。我已经使用了redis,并且非常喜欢它,所以我可能只需要使用它。让我想起mongodb的是在一份文件中为“竞选”做好每件事的潜在前景,但BFGL在这方面令人沮丧。虽然我不清楚这是否仅影响集合中的书写,或者它也影响集合中的事物。我会进一步研究这一点! – Ataraxy 2012-07-12 00:54:36

0

我宁愿用pipeline不是multi如果你不需要的原子功能..