【发布时间】:2019-05-25 08:23:27
【问题描述】:
我想在广告网络中实施 FreqCapping。我想在一天中仅 n 次向唯一用户提供广告系列。如果 n=1,我可以在 redis 中使用 BloomFilter 来实现,但通常 n 大于 1。是否有针对此问题的任何数据结构(甚至是概率数据结构)?那是在redis中实现的吗?
【问题讨论】:
标签: algorithm redis bloom-filter
我想在广告网络中实施 FreqCapping。我想在一天中仅 n 次向唯一用户提供广告系列。如果 n=1,我可以在 redis 中使用 BloomFilter 来实现,但通常 n 大于 1。是否有针对此问题的任何数据结构(甚至是概率数据结构)?那是在redis中实现的吗?
【问题讨论】:
标签: algorithm redis bloom-filter
听起来您在描述 Count-min sketch,虽然 Redis 核心没有它,但 RedisBloom 有 :)
【讨论】:
如果n 很小,只需对'1x' + user、'2x' + user、...、n + 'x' + 'user' 使用布隆过滤器。作为细节,请以随机顺序检查它们。这意味着当用户只被看到一小部分时间时,您的查找次数就会减少。
如果n 很大,请考虑只进行固定数量的随机查找。当你接近你的极限时,它会交易性能,有时当你接近你的极限时选择不填充。例如,最多 4 次查找,在 50% 到极限时,您在 90% 的时间内做出正确选择,在 80% 到极限时,您仍然在 60% 左右做出正确选择时间。如果n=20,当您达到限制时,您将节省大量时间。
我确信有某种特殊的布隆过滤器可以达到类似的限制,您每次都检查/设置散列函数的随机子集(检查比您设置的更多)。但是你不会发现 Redis 中已经预先构建了这种特殊结构。
我建议的概率版本是这样的:
def is_available(user, k=4, n=20):
tried = []
for 1..k:
i = rand(n)
while i in tried:
i = rand(n)
id = user + ":" + str(i)
if bloomfilter.lookup(id):
tried.append(i)
else:
bloomfilter.add(id)
return True
return False
随机化的目的是减少您需要的查找次数。如果您每次都以相同的顺序进行,那么在第 10 次访问时,您将进行 9 次查找,然后才发现它们没有超出配额。但是如果n 是 20 并且您以随机顺序进行,那么第一次查找的一半时间就足够了。这减少了往返次数,从而提高了性能,这在广告技术中非常重要。
【讨论】: