【问题标题】:top most common/duplicate elements over a time period in realtime实时在一段时间内最常见/重复的元素
【发布时间】:2017-08-29 21:39:49
【问题描述】:

我有用户生成的字符串以未定义的速率进入,其中一些是重复数据,我想实时统计前 20 个最常见的重复数据,在给定的恒定时间段内(例如,过去一小时内),在 Go 中。

唯一字符串的数量不受任何限制,因此,为了避免 DoS,数据结构可能必须定义最多元素的大小(例如,top-10k-elements 和/或1MB 整体大小),如果最近插入的元素还没有任何重复项,则丢弃它们(但永远不要丢弃任何新传入的元素!)。

我的理解是ngx_http_limit_req_module.c 就是implemented,这种方法在documentation 中被称为“漏桶”,但是wikipedia 页面似乎暗示它是新的将从队列中删除的数据,而不是旧的,因此,不确定该概念是否适用。

无论如何,我尝试在 Golang 中寻找“漏桶”实现,到目前为止,我找到的最流行的结果是 uber-go/ratelimit,它的 API 似乎根本不适合我的问题陈述——它只是实现了一些实际的限速队列,而不是实时最后 Y 计数的前 X。

谁能建议我正在寻找的正确名称,以及完成此任务的最佳方法,最好是在 Go 中?

【问题讨论】:

  • 要在您的语料库中实时搜索,您至少需要具有可预测搜索/插入时间的数据结构,例如平衡二叉树或哈希图或排序数组。您可以定期压缩此结构。我建议使用具有恒定搜索/插入时间和恒定大小的 Bloom 过滤器以及 Go 中的多个实现。
  • 您需要精确计数,还是概率估计就足够了?
  • 我很好奇是否有人认为这是题外话可以解释为什么它不适合stackoverflow.com/help/on-topic。该问题要求一种特定编程问题算法,即如何保持用户搜索中出现的实时前20个术语列表。这是软件开发独有的实用、可回答的问题 - 找我其他任何想解决此类问题的人!尽管符合初始标准,但它不是不在主题的 6 种问题中的任何一种。那么为什么有 4 个人认为这是题外话呢?
  • @btilly,我更喜欢精确计数,但要符合与 nginx 实现记录相同的条件,即最近插入的元素(希望当前也没有任何重复项)都会启动。
  • @cnst nginx 实现在nginx.com/blog/rate-limiting-nginx 中描述。可以在 lru 缓存中跟踪最近插入的位。 Google 找到了github.com/hashicorp/golang-lru 以获取示例实现。但请注意,nginx 限制活动 IP 地址这一事实减少了他们需要跟踪的数据量,而且他们不会尝试跟踪一个小时。您可能希望以某种方式限制您需要跟踪此功能的信息量。

标签: algorithm nginx go data-structures


【解决方案1】:

这是两个问题。

  1. 跟踪您选择跟踪的名称。
  2. 注意不在您的列表中的热门名称以进行跟踪。

对于第一个问题,我建议跟踪每个名称,每分钟,有多少。当他们完成时,将它们添加到运行总数中,然后添加到要在一个小时内减去的东西的队列中。这为每个名称提供了 60 个小对象,并且在运行的基础上,您将保持哈希运行。

第二个问题更具挑战性。为此,我将使用概率方法。这个想法是每个名称都使用唯一的 id 进行哈希处理,并且您只保留您在一分钟内看到的一千个最小的哈希值(和相关名称)。 (我会在一分钟内给出一个算法。)你的哈希值应该均匀地分布在 2^64 最大的独立名称中,所以常见的名称最终会出现在这个列表中。当他们这样做时,你开始数他们! (您将失去前几个,但通过更多的工作,您可以估计您错过了多少。这种优化可能比它的价值更多。)

现在我们如何保留一千个最小的哈希值?您使用 优先级队列,通常使用 heap 实现该队列,以创建一个可更新的数据结构,以便轻松提取最大的散列值。所以你运行下面的伪代码。

create your priority queue of (hash, name)
for each name:
   hash hash of name and unique new id
   entry = (hash, name)
   if queue size < 1000:
       insert entry
   else if hash is smaller than the current max in the queue
      insert entry
      remove the largest entry

【讨论】:

  • 感谢您的回答。你知道 nginx 是如何实现的吗?文档似乎没有提到任何形式的概率不确定性。
  • @cnst 我在上面回答了这个问题。即使单个搜索词的数量非常大,这里的概率设计也允许在有限的内存要求下执行此操作。在大型集群上,它可以进行调整以允许在多台机器上进行计算然后合并。但根据您的问题,这可能是矫枉过正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
  • 1970-01-01
  • 2017-01-05
  • 2019-03-25
相关资源
最近更新 更多