糖豆实时推荐系统设计与实现

1.实时推荐系统与相关工作

1.1 原因

实时计算能够及时捕获用户短时兴趣,同时能够快速反馈分发当前系统的用户兴趣内容。大量实践以及发表的文章都显示了推荐系统实时化,对推荐精准度的提升的有效性和必要性。

1.2 腾讯架构与实现

实时推荐相关工作非常多,腾讯和北大合作的两篇SIGMOD文章是比较实际和详细的实现,采用的计算框架能够支持大规模数据的实时推荐,以下将会分开简述以下两篇文章。

2015年

Huang发表了基于Storm和KV存储的大规模实时推荐系统 (TencentRec: Real-time Stream Recommendation in Practice)

  1. 实现了一系列经典推荐算法的实时版本
  2. 实现了数种实时算法提高推荐精度
  3. 广泛应用于业务有效提高

腾讯采用使用storm原因,支持实时数据流式计算,良好的可扩展性、可容错性,采用简单编程模型。
文章核心包括实时增量计算的ItemCF,以及用户隐式反馈计算、实时剪枝算法、基于用户画像的数据稀疏性策略。应用在多个业务上都有不同程度的提升,最明显的是腾讯视频的全局表现提升高达30%。

全文核心应该是下图六道公式,阐述腾讯如何具体实现的增量itemcf。

文章中的co-rating,其实就是我们常说的user bias. 公式3和4解决了用户隐式反馈问题,细节的计算可以参考2016的文章,实际是一个log函数融合了用户的浏览、点击、分享、购买等行为,转化成rating.

corating.png

请注意公式4,由于他们定义了corating,实际是将相似度的增量计算从L2范数的计算转化成了L1范数计算.(当Rup取x的时候,y=1/x)。

可扩展的增量计算


itemcf.png
initemcf.png

2016年

腾讯视频的推荐应用(Real-time Video Recommendation Exploration)

  1. 实时处理、大规模数据下的准确率和可扩展性。
  2. 开发了一个基于矩阵分解的大规模在线协同过滤算法,以及一系列的自适应更新策略。
  3. 通过增加包括视频类别、时间因素影响、用户画像剪枝以及训练等方法,提高实时TopN推荐的精度。

在我们看来,全文核心在于实时计算的数据流转,如下图所示:


tecvideo.png

基于storm的实时计算topology图:


topo.png

2. 糖豆的设计与实现

2.1 架构

糖豆整体推荐框架,从离线,近线,在线三套计算流程组合而成。在线流程基于Spark Streaming框架实现,部署在近线集群。 在线推荐框架实时根据用户行为,生成实时推荐列表,从而满足用户瞬时兴趣,提高推荐系统的推荐新鲜度。简单架构图如下:


糖豆实时架构.png

2.2 基于Spark Streaming的实现

2.2.1. 计算流程

实时计算流程如下图所示:

实时计算流程图
实时计算流程图

分解步骤:

  1. Spark Streaming 读取Kafka,原始日志ETL
  2. 提取用户隐式反馈,生成候选集tuple (uid,vid)
  3. 每天凌晨会将离线计算好的ItemCF模型结果集导入Redis。itemcf数据结构是一个similarity vid list。
  4. 实时维护看过视频set,对看过视频的处理候选集tuple过滤该用户看过的视频
  5. 实时更新推荐过视频set,候选集tuple过滤当天已经被推荐过的视频
  6. 候选集写入Redis推荐list

python实现:

if __name__ == "__main__":
    print sys.argv
    reload(sys)
    sys.setdefaultencoding('utf-8')
    sc = SparkContext(appName="real_time_etl")
    #20秒
    ssc = StreamingContext(sc, 15)
    brokers = "kafka-servers:9092"
    topic = "logstash"
    #读取kafka
    kvs = KafkaUtils.createDirectStream(ssc, [topic], {"metadata.broker.list": brokers})
   #解析日志、过滤无关数据、读取相似视频
    lines = kvs.map(lambda x : readJson(x[1])).filter(lambda x: x is not None).map(lambda x: getTopkfromRedis(x))
    #lines.pprint()
     #写入推荐结果
    lines.foreachRDD(lambda rdd: list2Redis(rdd))  
    ssc.start()
    ssc.awaitTermination()

2.2.2 监控

部署在集群Master节点的监控脚本会每30s扫描一次实时计算代码进程,如果发现进程被failed,会自动拉起实时计算Spark Steaming进程。如果进程拉起失败会触发邮件、短信报警

#! /bin/sh

MOBILE="your phone numbers"
RT_HOME=/home/realtime/recommend.py

DIR=/data/rtdamon
PID_FILE=$DIR/.run/rt-litetl-damon.pid
LOG_FILE=$DIR/.log/rt-litetl-damon.log
t=$(date -d "today" +"%Y-%m-%d %H:%M:%S")

source /etc/profile 
echo $PID_FILE $LOG_FILE

if [ -e "$PID_FILE" ];
then
      pid=`cat $PID_FILE`
      echo $pid
      damon_process_exists=`ps v -p $pid | grep "rt-litetl-damon.sh" | grep -v grep|grep -v \<defunct\> `
      echo "damon process exists : $process_exists"
      if [ -n "$damon_process_exists" ]
      then
              echo "Process rt-litetl-damon.sh is running! $t" >> $LOG_FILE
              exit
      fi
fi

pid=$$
echo "$pid" > $PID_FILE

while :
do
      process_exists=`ps -ef|grep "$RT_HOME"|grep "spark"|grep -v grep|wc -l`
      echo "process exists : $process_exists" >>$LOG_FILE
      if [ "$process_exists" == "0" ]; then
      

/hadoop/spark/bin/spark-submit  --master yarn --packages org.apache.spark:spark-streaming-kafka-0-8_2.11:2.1.0 --py-files /hadoop/user/rt/redis.zip --num-executors 10 --executor-cores 7 --executor-memory 6g /home/realtime/recommend.py>>/data/rtlog/rtrecommed.log  2>&1 &
  /usr/bin/php -f /data/rtdamon/yunsms.class.php "$MOBILE" "recommend.py"
              echo "realtime recommendation process already restarted at $t" >> $LOG_FILE
      fi

      #sleep `expr 3600 \* 3`
      sleep `expr 60 \* 1`
done

2.3 收益

根据我们的AB测试数据来看,整体CTR提升25%。用推荐系统的A版对比无推荐的B版,用户观看时长提升47%。

recabdata.png

3. 问题与改进

  1. 较多代码逻辑集中在Redis。目前Redis无灾备措施,同时IO和负载也会出现Peak。
  2. Spark Streaming 目前实时级别在分钟级。需要升级成storm的秒、毫秒级别。
  3. 需要用户点击等行为才会生产数据,容易召回不足。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容