一尘不染

一次增加数百个计数器(redis或mongodb)?

redis

背景/意图:

因此,我将从头开始创建一个事件跟踪器,并对如何执行操作有一些想法,但是我不确定继续进行数据库操作的最佳方法。我感兴趣的一件事是允许这些事件完全动态,但同时允许报告相关事件计数器。

例如,所有国家都按操作系统细分。理想的效果是:

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

我的意图是能够接受这些事件名称,如下所示:

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

这意味着为了为上述内容做关系计数器,我可能会为每个请求增加100个以上的计数器。

假设每天将有10+百万个上述请求。

我想让事件名称完全保持动态,并且我还想以一种使数据查找保持超快的方式进行操作。因此,我一直在考虑为此使用redis或mongodb。

问题:

  1. 有没有更好的方法可以做到这一点然后在保持字段动态的同时进行计数?

  2. 如果所有这些都在一个文档中(结构像一棵树),那么在mongodb中使用$ inc运算符在一个操作中同时增加100个以上的计数器是否可行并且不会慢?这样做的好处是,我可以在单个查询中快速检索一个“广告系列”的所有统计信息。

  3. 这是否更适合Redis并为活动的所有适用计数器做一次Zinrby?

谢谢


阅读 366

收藏
2020-06-20

共1个答案

一尘不染

根据键结构的布局方式,我建议对zincr命令进行流水线处理。您有一个简单的“提交”触发器-
请求。如果您要遍历您的参数并为每个键添加锌,那么在请求结束时传递execute命令将非常快。我已经实现了一个像您描述为cgi和Django应用程序的系统。我按照以下步骤建立了一个关键结构:

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

并且能够通过单个过程以每秒150000-200000的增量在Redis端进行处理,这对于您所描述的场景应该足够了。这种密钥结构使我可以基于时间窗口获取数据。我还为密钥添加了一个到期时间,以避免编写数据库清理过程。然后,我进行了一项cronjob,它将使用上述键模式的变体将操作设置为每小时,每天和每周“汇总”统计信息。我提出这些想法是因为它们是您可以利用Redis的内置功能来简化报告方的方式。还有其他方法可以执行此操作,但是这种模式似乎效果很好。

正如eyossi指出的那样,对于同时进行写入和读取的系统,全局锁定可能是一个真正的问题。如果您将其编写为实时系统,则并发性很可能是一个问题。如果它是“一天结束”日志解析系统,那么除非您在输入时运行解析器的多个实例或报告,否则它不太可能触发争用。关于保持快速读取,在Redis中,我将考虑建立一个从主实例派生的只读Redis实例。如果将其放在运行报告的服务器上并指向报告过程,则生成报告应该很快。

根据可用内存,数据集大小以及是否在Redis实例中存储任何其他类型的数据,您可能会考虑运行32位Redis服务器以降低内存使用量。32b实例应该能够在一小部分内存中保留大量此类数据,但是如果运行正常的64位Redis不会占用太多内存,则可以随意使用它。与往常一样,测试您自己的使用模式以进行验证

2020-06-20