如何用Redis构建高性能在线广告系统

转载于:https://yq.aliyun.com/articles/293995

背景

在线广告作为互联网最主要的盈利模式之一,支撑着互联网行业的发张。早期的在线广告主要是展示广告,和在报纸,期刊上刊登广告相似。通过建立个性化数据,Google推出了AdSense产品,通过AdSense的合作网站,采集到访客在这些网站的访问足迹,并利用这些数据提高其广告的相关性;以Facebook为代表的社交网络由于具备了完善的用户个性化数据,利用这些数据,网站可以将定向技术使用到展示广告,这使展示广告迎来了第二春。近年来一种新的广告业务模式–“实时竞价广告交易系统”也逐渐被网站主和广告主接受,其核心目的是让每次广告展现都创造出尽可能多的回报,以自动化的方式系统使用实时数据和竞价信息将广告空间分配给那一时刻出价最高的销售渠道。由于对实时性要求越来越高,如何构建高效的在线广告系统,成为关注的焦点。本文以阿里云Redis来阐释在线广告子系统的构建。

广告业务分类介绍

广告按业务划分有以下几类:

  • 展示广告(Banner广告)
  • 搜索广告(关键词广告

按计费模式有:

  • CPT: 按有效广告展示天数计费,可定价或竞价;
  • CPM: 按有效广告展现次数计费,可定价或竞价;
  • CPC: 按有效点击次数计费;
  • CPS: 按效果计费,如,按成交订单额,按流量带来的有效下载或安装次数计费;

广告系统按结构可划分为以下子系统:

  • 广告投送服务器
  • 广告数据库及业务系统
  • 用户行为跟踪系统
  • 日志传输系统
  • 流式数据分析和计算平台
  • 离线数据分析和计算平台

在线广告系统架构设计

首页广告在阿里云Redis上的实现

  • 使用Redis的list数据类型存放需要展示的广告ID,hash数据类型存放广告详细信息。
  • 首先使用阿里云Redis构建简单广告数据。

    $./bin/redis-cli -p 7197
    # 使用RPUSH插入一条广告ID

      127.0.0.1:7197> RPUSH  Home:Ad:List  Ad:hash:1
      (integer) 1

    # 使用HMSET插入该广告相关的信息

      127.0.0.1:7197> HMSET  Ad:hash:1  Id  12345 Title "Ad title" Pic "Ad picture url" Url "Ad url"
      OK

    # 使用RPUSH插入一条广告ID

      127.0.0.1:7197> RPUSH  Home:Ad:List  Ad:hash:2
      (integer) 1

    # 使用HMSET插入该广告相关的信息

      127.0.0.1:7197> HMSET  Ad:hash:2  Id  123456 Title "Ad2 title" Pic "Ad2 picture url" Url "Ad2 url"
      OK

    # 使用RPUSH插入一条广告ID

      127.0.0.1:7197> RPUSH  Home:Ad:List  Ad:hash:3
      (integer) 1

    # 使用HMSET插入该广告相关的信息

      127.0.0.1:7197> HMSET  Ad:hash:3  Id  1234567 Title "Ad3 title" Pic "Ad3 picture url" Url "Ad3 url"
      OK

    # 使用RPUSH插入一条广告ID

      127.0.0.1:7197> RPUSH  Home:Ad:List  Ad:hash:4
      (integer) 1

    # 使用HMSET插入该广告相关的信息

      127.0.0.1:7197> HMSET  Ad:hash:4  Id  12345678 Title "Ad4 title" Pic "Ad4 picture url" Url "Ad4 url"
      OK
            
    1. 每增加一条广告展示,在列表“Home:Ad:List”末尾使用"RPUSH"命令增加一个值(例如:ID值为4的广告,值为“Ad:hash:4”)。同时使用"HMSET"命令存储一条"hash"类型的广告数据。
    2. 每删除一条广告信息,使用"LREM"命令从列表“Home:Ad:List"中删除对应的广告ID(例如:"Ad:hash:5”),同时使用"DEL"命令删除本条广告对应的"hash"类型数据。
    3. 获取广告展示列表,先使用"LRANGE"命令从列表"Home:Ad:List"中获取广告ID集合(例如:LRANGE("Home:Ad:List", 0, 9))。循环遍历,使用"HGETALL"命令获取广告详细信息。

  • 广告的数据在Redis中的分布图为:

如何用Redis构建高性能在线广告系统_第1张图片

使用阿里云Redis构建频次访问控制器

频次控制旨在控制某个用户接触到某创意的次数,以达到提高广告性价比的目的。一般来说,随着某个用户看到同一个创意频次的逐渐上升,点击率呈逐渐下降的趋势。因此在按照CPM采买流量时,广告主有时会要求根据频次控制某个用户接触到某次创意地次数。

  • 首先使用Redis的hash类型来构建用户,广告,频次访问限制。
  • 其次使用用户+广告id为key,来构建用户对某广告的访问频次统计。

         # HMSET userID adID reqFrequency,使用HMSET构建用户,广告和访问频次的关系
         # 127.0.0.1:7197> HMSET  12345 1 3
           OK
           
         # 初始化广告的访问频次
         # 127.0.0.1:7197> SET 12345_1  0
           OK
           
         # 设置访问频次的过期时间,该过期时间为绝对过期时间,为自然天的timestamp。
         # 127.0.0.1:7197> EXPIREAT  12345_1  1513239705
           (integer) 1
         
         # 增加广告访问频次
         # 127.0.0.1:7197> INCR  12345_1
           (integer) 1
         
         # 获取用户访问的某个广告的访问频次
         # 127.0.0.1:7197> HMGET 12345 1
           1) "3"
           

在线广告系统整体架构图

如何用Redis构建高性能在线广告系统_第2张图片

下面介绍下List,Hash的使用方法

   # BLPOP key [key ...] timeout
     BLPOP是列表的阻塞式(blocking)弹出原语。
     
   # BRPOP key [key ...] timeout
     BRPOP 是列表的阻塞式(blocking)弹出原语。
     
   # BRPOPLPUSH source destination timeout
     BRPOPLPUSH 是 RPOPLPUSH 的阻塞版本,当给定列表 source 不为空时, BRPOPLPUSH 的表现和 RPOPLPUSH 一样。
     
   # LINDEX key index
     返回列表 key 中,下标为 index 的元素。
     
   # LINSERT key BEFORE|AFTER pivot value
     将值 value 插入到列表 key 当中,位于值 pivot 之前或之后。
     
   # LLEN key
     返回列表 key 的长度。
     
   # LPOP key
     移除并返回列表 key 的头元素。
     
   # LPUSH key value [value ...]
     将一个或多个值 value 插入到列表 key 的表头。
     
   # LPUSHX key value
     将值 value 插入到列表 key 的表头,当且仅当 key 存在并且是一个列表。
     
   # LRANGE key start stop
     返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。
     
   # LREM key count value
     根据参数 count 的值,移除列表中与参数 value 相等的元素。
     
   # LSET key index value
     将列表 key 下标为 index 的元素的值设置为 value# LTRIM key start stop
     对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
     
   # RPOP key
     移除并返回列表 key 的尾元素。
     
   # RPUSH key value [value ...]
     将一个或多个值 value 插入到列表 key 的表尾(最右边)。
   
   # HMGET key field [field ...]
     返回哈希表 key 中,一个或多个给定域的值。
   
   # HMSET key field value [field value ...]
     同时将多个 field-value (域-值)对设置到哈希表 key 中。
     
   # HDEL key field [field ...]
     删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。
   
   # HVALS key
     返回哈希表 key 中所有域的值。
  

总结

本文主要介绍了使用阿里云Redis构建在线广告系统模块的数据存储方式和使用方法。介绍了构建相关模块所使用的Redis命令。为了方便用户交流开源和Redis相关技术,我们也建立了Redis交流钉钉群,欢迎有兴趣的同学移步这里加入,另外也欢迎大家使用阿里云Redis服务。对于有兴趣从事云数据库内核或者管控相关工作可以移步这里,欢迎C++/JAVA/GOLANG/PYTHON等各种开发人才加盟。


你可能感兴趣的:(redis)