我想在广告网络中实施FreqCapping。我只想一天n次向唯一身份用户投放广告系列。如果n = 1,则可以在redis中使用BloomFilter来实现,但是通常n大于1。是否有针对此问题的数据结构(甚至是概率数据结构)?并在redis中实现了吗?
答案 0 :(得分:3)
听起来您正在描述Count-min sketch,而Redis core没有它,而RedisBloom却是:)
答案 1 :(得分:1)
如果n
很小,只需对'1x' + user
,'2x' + user
,...,n + 'x' + 'user'
使用布隆过滤器。详细信息,请按随机顺序检查它们。这意味着当只在很小一部分时间内看到用户时,您的查询就会减少。
如果n
大,请考虑仅进行固定数量的随机查找。当您接近极限时,这会影响性能,有时接近极限时会选择不执行。例如,最多进行4次查询,在达到上限的方式中,有50%的情况下您在90%的时间内做出了正确的选择,而在达到上限的方式中有80%的情况下,您仍然在约60%的情况下做出了正确的选择时间。而且如果是n=20
,则达到极限时将节省很多时间。
我确信有某种特殊的Bloom过滤器可以达到类似的限制,每次您检查/设置哈希函数的随机子集(检查的次数超过设置的次数)。但是您不会发现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,并且您是以随机顺序进行的,则第一次查找的时间将减少一半。这样可以减少往返次数,从而提高性能,这在adtech中非常重要。