Files
fun-rec/docs/ch01/ch1.2.md
2022-04-21 20:02:33 +08:00

11 KiB
Raw Blame History

推荐系统架构

推荐和搜索系统核心的的任务是从海量物品中找到用户感兴趣的内容。在这个背景下,推荐系统包含的模块非常多,每个模块将会有很多专业研究的工程和研究工程师,作为刚入门的应届生或者实习生很难对每个模块都有很深的理解,实际上也大可不必,我们完全可以从学习好一个模块技术后,以点带面学习整个系统,虽然正式工作中我们放入门每个人将只会负责的也是整个系统的一部分。但是掌握推荐系统最重要的还是梳理清楚整个推荐系统的架构,知道每一个部分需要完成哪些任务,是如何做的,主要的技术栈是什么,有哪些局限和可以研究的问题,能够对我们学习推荐系统有一个提纲挈领的作用。

所以这篇文章将会从数据驱动角度出发分析推荐系统的架构,这种架构将推荐系统按照对数据利用情况和系统响应要求出发,将整个架构分为离线层、近线层和在线层三个模块。然后分析这三个模块分别承担推荐系统什么任务,有什么制约要求。这种角度不和召回、排序这种通俗我们理解推荐系统的角度出发,因为更多的是考虑推荐算法在工程技术实现上的问题和我们需要推荐算法达成的目标这两个角度出发,方便我们理解为什么推荐系统要这样设计。

架构设计是一个非常大的话题设计的核心在于平衡和妥协。在推荐系统不同时期、不同的环境、不同的数据架构都会面临不一样的问题。Netflinx官方博客有一段总结

We want the ability to use sophisticated machine learning algorithms that can grow to arbitrary complexity and can deal with huge amounts of data. We also want an architecture that allows for flexible and agile innovation where new approaches can be developed and plugged-in easily. Plus, we want our recommendation results to be fresh and respond quickly to new data and user actions. Finding the sweet spot between these desires is not trivial: it requires a thoughtful analysis of requirements, careful selection of technologies, and a strategic decomposition of recommendation algorithms to achieve the best outcomes for our members. “找到恰当的平衡并不容易,需要深思熟虑和需求分析,细心选择技术,战略性的推荐算法分解,才能达到最好的结果”

所以在思考推荐系统架构考虑的第一个问题是确定边界:知道推荐系统要负责哪部分问题,这就是边界内的部分。在这个基础上,架构要分为哪几个部分,每一部分需要完成的子功能是什么,每一部分依赖外界的什么,这是边界外的部分。了解推荐系统架构也和上文讲到的思路一样,我们需要知道的是推荐系统要负责的是怎么问题,每一个子模块分别承担了哪些功能,它们的主流技术栈是什么。从这个角度来阅读本文,将会有助于读者抓住重点。

数据驱动下的推荐系统架构

推荐系统架构首先从数据驱动角度最经典的就是Netflix在2013年提出的典架构整个架构分为

  1. 离线层:不用实时数据,不提供实时响应;
  2. 近线层:使用实时数据,不保证实时响应;
  3. 在线层:使用实时数据,保证实时在线服务;

设计思想

架构设计有很多切入方式,最经典的就是根据每一个模块工作的层级、响应速度来分为离线层、近线层、在线层。网飞的这个架构提出的非常早,其中的技术也许不是现在常用的技术了,但是架构模型仍然被很多公司采用。

这个架构为什么要这么设计本质上是因为推荐系统是由大量数据驱动的大数据框架最经典的就是lambda架构和kappa架构这里不展开讲这两个架构。而推荐系统在不同环节所使用的数据、处理数据的量级、需要的读取速度都是不同的目前的技术还是很难实现一套端到端的及时响应系统所以这种架构的设计本质上还是一种权衡后的产物所以有了下图这种模型

在这里插入图片描述

上面是网飞的原图,我搬运了更加容易理解的线条梳理后的结构:

在这里插入图片描述
接下来详细介绍一下这三个模块。

离线层

离线层是计算量最大的一个部分,它的特点是不依赖实时数据,也不需要实时提供服务。需要实现的主要功能模块是:

  1. 数据处理、数据存储;
  2. 特征工程、离线特征计算;
  3. 离线模型的训练;

这里我们可以看出离线层的任务是最接近学校中我们处理数据、训练模型这种任务的,不同可能就是需要面临更大规模的数据。离线任务一般会按照天或者更久运行,比如每天晚上定期更新这一天的数据,然后重新训练模型,第二天上线新模型。

在这里插入图片描述

离线层优势和不足

离线层面临的数据量级是最大的面临主要的问题是海量数据存储、大规模特征工程、多机分布式机器学习模型训练。目前主流的做法是HDFS收集到我们所有的业务数据通过HIVE等工具从全量数据中抽取出我们需要的数据进行相应的加工离线阶段主流使用的分布书框架一般是Spark。所以离线层有如下的优势

  1. 可以处理大量的数据,进行大规模特征工程;
  2. 可以进行批量处理和计算;
  3. 不用有响应时间要求;

但是同样的,如果我们只使用用户离线数据,最大的不足就是无法反应用户的实时兴趣变化,这就促使了近线层的产生。

近线层

近线层的主要特点是准实时,它可以获得实时数据,然后快速计算提供服务,但是并不要求它和在线层一样达到几十毫秒这种延时要求。近线层的产生是同时想要弥补离线层和在线层的不足,折中的产物。

它适合处理一些对延时比较敏感的任务,比如:

  1. 特征的事实更新计算例如统计用户对不同type的ctr推荐系统一个老生常谈的问题就是特征分布不一致怎么办如果使用离线算好的特征就容易出现这个问题。近线层能够获取实时数据按照用户的实时兴趣计算就能很好避免这个问题。
  2. 实时训练数据的获取比如在使用DIN、DSIN这行网络会依赖于用户的实时兴趣变化用户几分钟前的点击就可以通过近线层获取特征输入模型。
  3. 模型实时训练:可以通过在线学习的方法更新模型,实时推送到线上;

近线层的发展得益于最近几年大数据技术的发展很多流处理框架的提出大大促进了近线层的进步。如今Flink、Storm等工具一统天下。

在这里插入图片描述

在线层

在线层最大的特点是对响应延时有要求,它是直接面对用户群体的。所有的用户请求都会发送到在线层,在线层需要快速返回结果,它主要承担的工作有:

  1. 模型在线服务;包括了快速召回和排序;
  2. 在线特征快速处理拼接根据传入的用户ID和场景快速读取特征和处理
  3. AB实验或者分流根据不同用户采用不一样的模型比如冷启动用户和正常服务模型
  4. 运筹优化和业务干预:比如要对特殊商家流量扶持、对某些内容限流;

典型的在线服务是用过RESTful/RPC等提供服务一般是公司后台服务部门调用我们的这个服务返回给前端。具体部署应用比较多的方式就是使用Docker在K8S部署。

在线层最大的问题就是对实时性要求特别高,一般来说是几十毫秒,这就限制了我们能做的工作,很多任务往往无法及时完成,需要近线层协助我们做。

在这里插入图片描述

总结

整篇文章梳理了Netfliex的经典推荐系统架构整个架构更多是偏向实时性能和效果之间tradeoff的结果。如果从另外的角度看推荐系统架构比如从数据流向或者说从推荐系统各个时序依赖来看就是我们最熟悉的召回、粗排、精排、重排、混排等模块了。这种角度来看是把推荐系统从前往后串起来其中每一个模块既有在离线层工作的也有在在线层工作的。而从数据驱动角度看更能够看到推荐系统的完整技术栈推荐系统当前面临的局限和发展方向。

召回、排序这些里面单拿出任何一个模块都非常复杂。这也是为什么大家都说大厂拧螺丝的原因,因为很可能某个人只会负责其中很小的一个模块。许多人说起自己的模块来如数家珍,但对于全局缺乏认识,带来的结果是当你某天跳槽了或者是工作内容变化了,之前从工作当中的学习积累很难沉淀下来,这对于程序员的成长来说是很不利的。

所以希望这篇文章能够帮助大家在负责某一个模块,优化某一个功能的时候,除了能够有算法和数据,还能能够考虑对整个架构带来的影响,如何提升整体的一个性能,慢慢开阔自己的眼界,构建出一个更好的推荐系统。

参考资料