【发布时间】: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