【问题标题】:Count unique users if user visit n times如果用户访问 n 次,则计算唯一用户
【发布时间】:2019-05-25 08:23:27
【问题描述】:

我想在广告网络中实施 FreqCapping。我想在一天中仅 n 次向唯一用户提供广告系列。如果 n=1,我可以在 redis 中使用 BloomFilter 来实现,但通常 n 大于 1。是否有针对此问题的任何数据结构(甚至是概率数据结构)?那是在redis中实现的吗?

【问题讨论】:

    标签: algorithm redis bloom-filter


    【解决方案1】:

    听起来您在描述 Count-min sketch,虽然 Redis 核心没有它,但 RedisBloom 有 :)

    【讨论】:

      【解决方案2】:

      如果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 并且您以随机顺序进行,那么第一次查找的一半时间就足够了。这减少了往返次数,从而提高了性能,这在广告技术中非常重要。

      【讨论】:

      • 使用多重布隆过滤器的好主意,但我冒昧地提供了另一种奇特的数据结构。
      • 这是一个有趣的想法(当然,count-min sketch 是一种替代方案,但可能需要更多内存)。我不明白的是“随机顺序”。它有什么帮助?您能否更详细地描述该算法(使用查找和添加的伪代码)?
      • @ThomasMueller 我添加了代码和简要说明。
      猜你喜欢
      • 2020-09-01
      • 2016-08-31
      • 2018-03-08
      • 2021-03-08
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多