这个月做的事情还是蛮多的。上线了一个百台规模的ES集群,还设计开发了一套实时推荐系统。 标题有点长,其实是为了突出该推荐系统的三个亮点,一个是实时,一个是基于用户画像去做的,一个是异步化。
*** 实时主要体现在三个层面:***
*** 用户画像和视频画像 ***
用户画像则体现在兴趣模型上。通过构建用户的长期兴趣模型和短期兴趣模型可以很好的满足用户兴趣爱好以及在用户会话期间的需求。做推荐的方式可以很多,比如协同,比如各种小trick,而基于用户画像和视频画像,起步难度会较大,但是从长远角度可以促进团队对用户和视频的了解,并且能够支撑推荐以外的业务。
*** 异步化 ***
推荐的计算由用户刷新行为触发,然后将用户信息异步发送到Kafka,接着Spark Streaming程序会消费并且将候选集和用户进行匹配计算,计算结果会发送到Redis 的用户私有队列。接口服务只负责取推荐数据和发送用户刷新动作。新用户或者很久没有过来的用户,它的私有队列可能已经过期,这个时候异步会产生问题。前端接口一旦发现这个问题,有两种解决方案:
除了新用户,这种情况总体是少数。大部分计算都会被异步计算cover住。
我之前写了很多文章鼓吹流式技术,最露骨的比如 数据天生就是流式的。 当然主要和我这一两年部门的工作主体是构建 流式流水线(Pipline),解决实时日志计费等相关问题。流式计算对推荐系统的影响很大,可以完全实现
在推荐系统中,除了接口服务外,其他所有计算相关的,包括但不限于:
这些流程都是采用Spark Streaming来完成。对于长期协同(一天以上的数据),用户长期兴趣模型等,则是采用Spark 批处理。因为采用了StreamingPro这个项目,可以做到所有计算流程配置化,你看到的就是一堆的描述文件,这些描述文件构成了整个推荐系统的核心计算流程。
这里还值得提的三点是:
整个推荐系统的结构如图:
Snip20161201_6.png
看起来还是挺简单的。分布式流计算主要负责了五块:
存储采用的有:
下面这张图则是对流式计算那块的一个细化:
Snip20161201_7.png
用户上报采用的技术方案:
对于第三方内容(全网),我们自己开发了一个采集系统。
Snip20161201_10.png
所有候选集都是实时更新的。
这里我们说下参数配置服务器的概念。
假设我有三个算法A,B,C ,他们分别由三个流式程序完成,各个程序是互相独立的,最后都会算出各自的结果集。因为不同候选集和算法算出的内容数据量和频度都会有差异,假设A算出的结果集过大,B算出的结果集很小,但是质量很好,这个时候他们在发送到用户推荐队列的时候,需要将自己的情况提交给参数配置服务器,并且由参数服务器决定最后能够发送到队列的量。参数服务器也可以控制对应频度。比如A算法距离上次推荐结果才10s就有新的要推荐了,参数服务器可以拒绝他的内容写入到用户推荐队列。
上面是一种多算法流程的控制。其实还有一种,就是我希望A,B的结果让一个新的算法K来决定混合的规则,因为所有算法都是StreamingPro中的一个可配置模块,这个时候A,B,K 会被放到一个Spark Streaming应用中。K可以周期性调用A,B进行计算,并且混合结果,最后通过参数服配置服务器的授权写入到用户推荐队列。
我14,15年做的一次推荐系统,那个时候还没有流式计算的理念,而且也不能复用一些已有的技术体系,导致系统过于复杂,产品化也会比较困难。而且推荐的效果也只能隔日看到,导致效果改良的周期非常长。当时整个开发周期超过了一个多月。然而现在基于StreamingPro,两三人没人么天只能投入两三小时,仅仅用了两个礼拜就开发出来了。后续就是对用户画像和视频画像的进一步深入探索,核心是构建出标签体系,然后将这些标签打到用户和视频身上。我们组合了LDA,贝叶斯等多种算法,获得不少有益的经验。