我正在试图找出Google趋势背后的系统设计(或任何其他像Twitter这样的大规模趋势功能)。
挑战:
需要处理大量数据来计算趋势。
过滤支持 - 按时间,地区,类别等。
需要一种存储方式进行存档/离线处理。过滤支持可能需要多维存储。
这就是我的假设(我对MapReduce / NoSQL技术没有实际经验)
来自用户的每个搜索项目将维护将存储并最终处理的一组属性。
以及按时间戳,搜索区域,类别等维护搜索列表
示例:
搜索Kurt Cobain
字词:
Kurt-> (Time stamp, Region of search origin, category ,etc.)
Cobain-> (Time stamp, Region of search origin, category ,etc.)
问题:
他们如何有效地计算搜索词的频率?
换句话说,给定一个大型数据集,他们如何以分布式可扩展方式找到前10个频繁项目?
答案 0 :(得分:5)
嗯......找出前K个术语并不是一个大问题。该领域中的关键思想之一是“流处理”的想法,即,在单次传递数据中执行操作并牺牲一些准确性以获得概率性答案。因此,假设您获得如下数据流:
A B K A C A B B C D F G A B F H I B A C F I U X A C
你想要的是前K个项目。天真地,人们会为每个项目维护一个计数器,最后按每个项目的计数排序。这需要O(U)
空格和O(max(U*log(U), N))
时间,其中U
是唯一项目的数量,N
是列表中的项目数。
如果U
很小,这不是一个大问题。但是,一旦您进入具有数十亿或数万亿独特搜索的搜索日志域,空间消耗就开始成为问题。
所以,人们提出了“计算草图”的想法(你可以在这里阅读更多内容:count min sketch page on wikipedia)。在这里,您维护一个长度为n
的哈希表A,并为每个项目创建两个哈希值:
h1(x) = 0 ... n-1
h2(x) = 0/1
每个概率为0.5
然后你做A[h1[x]] += h2[x]
。关键的观察是,因为每个值随机哈希到+/- 1,E[ A[h1[x]] * h2[x] ] = count(x)
,其中E
是表达式的期望值,count是流中出现的次数。< / p>
当然,这种方法的问题在于每个估计值仍有很大的差异,但可以通过维护大量散列计数器并从每个集合中获取平均值或最小值来处理。
使用此草图数据结构,您可以获得每个项目的大致频率。现在,您只需维护一份包含迄今为止频率估算值最高的10个项目的列表,最后您将获得列表。
答案 1 :(得分:1)