如何实现广告弹窗触达频率的控制?
今天我们聊聊实际工作中遇到的一个问题:
产品提出想在我们的产品的首页做个弹窗广告, 但是又不希望用户每次进来都给用户弹窗, 每个用户每天进来只弹一次就好了.
这个如何实现?
方法一(暴力破解)
或许有些人会觉得这个挺简单的, 这个问题抽象出来不就是要记录用户的行为么, 这个将用户的每一次行为都存在 Redis 或数据库中, 每次访问的时候都查一下数据库或 Redis 判断一下, 有没有.
以 Redis 举例, 如果用户今天访问过一次, 就在 Redis 里面设置一个以用户为维度的 key.
方法一. PNG
真爽, 这么简单, 然后我们就高高兴兴的玩去了, 突然某一天, 运维找到你, 告诉你 Redis 服务被挤爆了, 内存不足. 什么鬼? 你抬起脑袋, 暗暗一想, 你们的用户有 1 个亿用户.
打算一个用户占用 14 个字节, 14B*100000000/1024/1024=1335MB, 我去, 这么一个小功能, 都占用至少 1G 的内存了.
方法二(Bitmap 数据结构)
为了实现这样的小的效果, 花费了 1G 的宝贵的 Redis 内存空间, 显然是划不来的. 有没有一种办法或数据结构可以即实现想要达到的一天一次弹窗效果, 又能占用内存最小.
这个时候, 你突然想到用户的唯一标识符(uid), 是一个从 0 到 1 个亿递增的整数. 一天一次弹窗对应一个 01 二进制值. 那能否分配一个大的数组, 数组的值是 boolean 值, 这个时候你突然想到了 Redis 的 Bitmap 数据结构.
方案二. PNG
抬起头算了算, 一个用户 uid 为 1bit 位, 1 亿用户, 大概: 100000000b/8/1024/1024=11MB. 到这里, 需要 1 个 G 的内存的功能现在只需要 11MB 就能存储下来.
方法三(布隆过滤器)
以为到使用 bitmap 解决问题就完了么? 如果现在不止有一个弹层呢, 比如 1000 个? 亦或者用户的唯一标识符并不是一个自增的整数. 这个时候如何处理呢?
如果我们愿意牺牲少了的准确度, 达到比较大的存储量的话, 你可能会考虑到布隆过滤器(Bloom Filter).
布隆过滤器
在方案二中的分配一大片的 bitmap 基础上, 将要保存的 uid 或 key 通过若干个哈希函数映射到不同的 bit 上保存.
这种方案有个好处就几十 MB 内存可以存储几十亿的数据去重判断. 当然坏处就是会牺牲掉少量的准确性.
方案四(前端存储)
在上面三种方案的基础上, 我们会发现想这些控制内存的方法, 我们想得老细胞都要死掉好多. 有没有一种简单有效的方式呢?
如果产品不需要强制要求必须用户一天只弹一次, 那能不能将这个控制任务交给前端来控制呢, 比如存储在 cookie 或 locolstorage 中?, 这样就完全不用担心存储内存的问题了.
但是这样有个缺点就是如果用户在不同的客户端 (H5 或 App) 中打开, 会出现一天弹多次的情况, 控制可能没那么精准.
没有完美的技术方案, 只有最合适的技术方案.
到这里, 如何控制频率的方法介绍完毕. 希望对你有所帮助.
都看到这里了, 关注个公众号吧
微信公众号 rudy_tan_home
来源: http://www.jianshu.com/p/04041c2761ac