用户对资源访问的频控缓存设计

目录

  • 一. 业务场景
  • 二. 缓存设计
  • 三. 扩展

一. 业务场景

基于用户行为, 控制广告/福利等资源对用户的展示频率

其中: 每个资源有不同id, 用户对资源可以有多个行为, 不同的行为有不同的禁止展示期.


  • 场景举例

场景1: 控制广告对用户的投放频率

  1. 资源是广告, 每个广告有不同的id, 用户对广告的操作有点击、关闭
  2. 用户点击过的广告, 3小时内不再曝光该广告
  3. 用户关闭过的广告, 1天内不再曝光该广告

场景2: 控制用户对体验会员的投放频率:

  1. 资源是体验会员, 每个体验会员有不同的id, 用户对体验会员的操作有关掉提示、使用体验会员
  2. 用户关掉体验会员, 则2小时内不再曝光该体验会员
  3. 用户使用体验会员, 则30分钟内不再曝光该体验会员

场景3: 控制用户推荐视频的投放频率:

  1. 资源是推荐视频, 每个推荐视频有不同的id, 用户对推荐视频的操作有划过、观看
  2. 用户划过推荐视频, 则3天内不再推荐该视频
  3. 用户划点击推荐视频, 则3天内不再推荐该视频

二. 缓存设计

zset结构, key为usr:{uid}, member为{resouceId}, score为{endTime}

endTime为频控结束时间

缓存写入时计算endTime: clientTime+X天, 曝光时X=2支持配置, 点击时X=3支持配置

整个key的expireTime: 取resouceId中最大时效时间, 失效的member写入或查询时惰性删除


优点:

  1. 支持按resouceId批量查询
  2. 支持按endTime区间查询
  3. 支持用户维度的查询(看了哪些广告)

缺点:

  1. 每个membe没有单独的失效时间, 需要手动去检查删除, 数据量大的话可能会浪费缓存空间
  2. 如果resouceId很多的话可能会造成大key(需要分片)

如果resouceId只有一个或没有批量查询的场景, 还可以设计为:

  1. kv结构, key为usr:{uid}:{resouceId}, value为{endTime}, key的expireTime为endTime
  2. 优点: 粒度更细过期就失效, 不用检查手动检查失效且节省内存空间
  3. 缺点: 如果有批量查询会造成缓存访问次数膨胀过大.

三. 扩展

如果需要支持次数的限制, 如一天浏览3个广告未点击, 则当天不再弹出广告

这样涉及次数的话, 则需要另外设计一个支持次数的缓存才能满足要求

你可能感兴趣的:(Cache,缓存,redis)