大家好,提前谢谢大家。我是NoSQL游戏的新手,但我目前的工作地点让我负责对一些大数据进行集合比较。
我们的系统有客户标签集和目标标签集。标签是一个8位数字。
客户标记集最多可以有300个标记,但平均为100个标记
目标标签集可以具有多达300个标签,但平均为40个标签。
预先计算不是一种选择,因为我们正在争取10亿潜在用户群。
(这些标记是分层的,因此只有一个标记意味着您也有它的父标记和祖先标记。暂时把这些信息放在一边。)
当客户访问我们的网站时,我们需要尽快将他们的标签集与100万个目标标签集相交。客户集必须包含要匹配的目标集的所有元素。
我一直在探索我的选择,雷迪斯的SET交叉口似乎是理想的选择。然而,我在互联网上的搜索并没有透露需要多少内存才能容纳100万个标签集。我知道交叉路口会很快,但这是雷迪斯可行的解决方案吗?
我意识到这是一种蛮力和低效。我也想用这个问题作为一种手段,就过去如何处理这类问题提出建议。如前所述,标签存储在树中。我也开始考虑将MongoDB作为一种可能的解决方案。
再次感谢
3条答案
按热度按时间hfsqlsce1#
这是一个有趣的问题,我认为Redis可以在这方面提供帮助。
Redis可以使用优化的“intset”格式存储整数集。有关详细信息,请参阅http://redis.io/topics/memory-optimization。
我相信这里正确的数据结构是目标标记集的集合,外加一个反向索引来将标记Map到它们的目标标记集。
要存储两个目标标记集,请执行以下操作:
我会使用:
当从系统添加/移除目标标签集时,该反向索引非常容易维护。
全局存储器消耗取决于多个目标标签集所共有的标签的数量。在Redis中存储伪数据和模拟内存消耗是相当容易的。我已经使用simple node.js script完成了。
对于100万个目标标签集(标签为8位数字,每组40个标签),当目标标签集共享的标签很少时(倒排索引中超过3200万条),内存消耗接近4 GB,当标签被大量共享时(倒排索引中只有10万条),内存消耗约为500MB。
使用这种数据结构,找到包含给定客户的所有标签的目标标签集非常高效。
交集操作是高效的,因为Redis足够智能,可以按基数对集合进行排序,并从基数最低的集合开始。
现在我知道您需要实现相反的操作(即查找目标标记集,其所有标记都在客户标记集中)。反向指数仍能有所帮助。
下面是一个用难看的伪代码编写的示例:
因此,您永远不需要针对100万个目标标记集测试客户标记集。您可以依靠反向索引将搜索范围限制在可接受的级别。
xam8gpfp2#
这可能会有所帮助:
案例研究:在非常大的集合(120m+和120m+)上使用Redis交集
http://redis4you.com/articles.php?id=016&name=Case+Study%3A+Using+Redis+intersect+on+very+large+sets
t1qtbnec3#
所提供的答案最初对我有帮助。然而,随着我们客户群的增长,我偶然发现了一项伟大的技术,涉及到使用Redis字符串位和位操作符非常快速地对数亿用户执行分析。
请看这篇文章。Redis的创建者安提雷兹也经常提到这一点。
http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/