文章发表在netflix的技术博客上。作者是Xavier Amatriain和Justin Basilico
利用清明的时间学习了一下,翻译备份,好货分享之。有不当的地方请评论中指出。多谢各位。

前一章节我们重点强调了数据和算法在创建一个有非常好的用户体验的推荐系统。我们同时也提到提升用户与推荐系统交互的参与程度和热情的重要性。今天我们将展现给大家的是另一个非常重要的问题:怎么样实现一套系统架构来完成以上所讲的体验以及更快的创新迭代。接下来讲一下我们这边的推荐架构,主要处理现有大量的数据,和用户交互,并且能够快速实现实验。

首先我们展示一下目前我们的整体推荐系统框图。主要的系统模块包含了一个或者多个机器学习的算法。Netflix的推荐和个性化系统架构 _netflix

最简单的处理数据的方法是保存起来,然后离线进行计算。这也正好是Offline Jobs的主要工作。尽管如此,计算可以以三种方式完成:offlinenearlineor online。在线计算可以更好地响应当前的事件以及用户交互,但是必须实时地响应。这也限制了在线计算算法的复杂度以及使用的数据集合。离线计算对于数据总量和计算复杂度有较小的限制。在个性化架构中,一个重要的点是如何无缝地融合离线和在线计算。Nearline计算处于一个中间状态,表现为在线计算的形式,但是不需要实时地服务。Model training是另外一种计算形式,它能利用现在数据去生成未来实际推荐结果计算要用的model。架构中另外一个重要的组成部分是Event and data distribution系统,主要来处理各种不同的事件和数据。相关的技术点是如何在在线,离线,伪在线合成各种不同的signalsmodels。最后,我们需要计算怎么样合并中间的推荐结果给最终用户展示。接下来详细地展示这些各个部分以及他们之间的交互关系。我们先会把系统划分为几个不同的子系统,然后会详细介绍这些子系统,所有架构都是运行在Amazon Web Services Cloud


Offlinenearlineonline  computing

Netflix的推荐和个性化系统架构 _netflix_02

以上所述,我们的算法可以在实时online计算,批量离线计算,或者两者之间的计算。每一个方法都有自己的优缺点,对不同的情况下需要 不同的考虑。

在线计算能利用最近的数据,更快地响应在线的事件,举个例子,利用当前的上下文信息为会员推荐动作影片的概览。在线模块遵循可获得性和响应时间的SLA。指定了从客户端用户开始等待的时刻起到最终获得推荐的最大的响应时间。这导致了在线模块不能处理复杂的计算算法。同时,纯的在线计算可能在某些情况下超出SLA的标准。因此,快速的反馈机制也就变得非常重要。例如采用前一次计算好的推荐结果。在线地计算也要求各种数据必须在线能够获取到,这也要求有额外的架构来支持

在另一个极端,离线计算允许更多的算法选择,例如复杂的算法,对使用数据总量无限制等,最简单的例子是周期的计算统计数据从百万级的电影播放数据里面,获取到基线热门的推荐。离线计算同时拥有更简单的工程需求。例如,宽松的响应时间SLA易于达到。我们不需要花费很多精力在性能调优上,当我们有新的算法需要部署到产品里面。在Netfilx我们利用了这个优点可以支持更快速的实验,新的实验算法执行速度太慢,我们只要增加Amazon EC2的实例个数可以获取到更高的吞吐量,节省了我们工程优化性能的时间,并且这个算法可能毫无商业价值,也就节省了我们无用的工程性能优化时间。尽管如此,因为离线计算不需要很强的响应时间需求,它将不会快速对上下文和新数据做出反应。同时离线计算需要存储,计算以及获取预先计算好的推荐大数据集的架构。

Nearline计算可以视为在线和离线计算的组合,其中,计算和在线的比较类似,但是我们不必把计算出来的结果直接服务于线上,而是可以缓存这些数据,允许异步的加载。近似线上计算主要在响应用户事件,保证系统更具有响应能力在请求之间。这样相当于为在事件之前进行更复杂的计算打开了后门。一个简单的例子,更新推荐结果,当一个电影被立刻观看,当一个会员开始观看的时候,推荐结果可以在中间缓冲中保存。近似在线计算对增量计算算法有着天然的支持。

在任何情况下,选择在线,离线和近似在线计算不是一个或的问题,所有的方法能够并且是应该被组合在一起。组合的方式多种多样,我们已经提到过了利用离线的计算获取fallback。另外一种选择是预先计算部分的推荐结果,通过离线的计算方式。同时留一部分放在在线计算计算更多的上下文相关的推荐结果。

即使是建模部分也可以综合利用在线和离线的计算。传统的监督的分类方法一般是在线下批量的训练标签数据,并且在线上对新的输入进行分类,这并不是很好的适合综合利用在线和离线。但是对于Matrix Factorization而言,就是很自然的混合在线离线模型。一些因子可以离线预先计算好,而另外一些因子应该在线更新以便获取更新鲜的结果。另外一些非监督的方法,类似于聚类,也是离线计算好模型供在线使用。这些例子指出我们可能分割所有模型训练成为两个部分:大数据并且是复杂的全局计算模型,轻量级的指定用户模型训练或者是在线的更新逻辑。


Offline Jobs

Netflix的推荐和个性化系统架构 _netflix_03Netflix的推荐和个性化系统架构 _netflix_03

个性化机器学习算法大部分计算都可以离线完成,这代表着这些任务可以周期性的调度,并且不需要与请求或者展示结果同步。主要有两部分计算:模型训练和批量的中间或者最终结果计算。在模型训练任务中,我们搜集了相关现有数据,应用一个机器学习算法去产出模型的参数集合。这个模型通常经过编码,并且存在一个文件中,以供后续计算。虽然大部分模型训练是离线批量的,我们还是有一些在线的学习计算,在线上的增量计算也是非常必要的。我们利用现存的模型和相应的输入结果计算后续在线处理或者直接展示给用户的结果,这个整体离线计算过程,就是批量的结果计算。

所有这些任务需要重新规整数据来进行处理,这个经常是通过数据库请求来达到需求。由于这些请求是在大量的数据上运行,它能在分布式上得到收益。这也导致hive或者pig是一个非常好的候选。一旦请求完成,我们需要一个发布结果数据的机制。这个机制有几点需求:1. 它能自动通知任务提交者最终的结果已经计算完毕;2. 它能支持多个不同的repositories (HDFS, S3 Cassandra)3.它对错误的容忍程度,允许监控和报警。在Netflix,我们用一个内部的工具:Hermes。它能提供上述功能,并且综合成一个内在的发布订阅框架。它能支持实时的传输数据给订阅者,在某种程度上,它覆盖了Apache Kafka部分功能,但是它不是一个消息时间队列系统。



信号量和模型

Netflix的推荐和个性化系统架构 _netflix_04Netflix的推荐和个性化系统架构 _netflix_04

无论是在线还是离线计算,我们都需要想一个算法需要处理三种输入:模型,数据和信号。模型一般是较小的文件包含了离线训练的各个参数。数据是指预处理过的并且保存在数据库的有序信息。可能是电影内容排序或者是热门度排序。我们用信号来代表更新信息或者触发信息,这些信息是我们输入到算法中,并且从线上的服务获取而来。这些信息可以是用户相关的信息组成,例如会员最近看了什么,上下文信息如session,设备,日期或者时间。


事件和数据分布

Netflix的推荐和个性化系统架构 _机器学习_05Netflix的推荐和个性化系统架构 _机器学习_05

我们的目标是把会员交互信息用来提高会员体验。我们有各种Netflix用户界面(智能电视,游戏界面等),不光为了配送更好的用户体验,同时为了收集到更多的用户事件。这些动作包括了点击,浏览,观看,甚至是焦点内容。事件信息可以被归约为我们算法的基础数据。这里我们试图对数据和事件做一个区分,虽然界限是非常模糊的。我们认为事件是一种时间敏感的信息,需要以最少的延迟被处理。这些事件会导致触发一系列的动作或者处理,例如更新近似线上计算的结果集等,另一方面,数据被认为是一种更稠密的信息单元,为了未来使用,它需要被处理和存储。这里响应时间不及信息的质量和数量重要。当然,可能会存在着即是事件,也是数据的情况,用户事件,它会被传给两条流。

netflix,我们的近似实时计算事件流被内部一个框架管理,Manhattan。它是一个分布式的计算系统,以我们推荐算法架构为核心,有点类似于TwitterStrom,但是它专注于对于不同的内部需求集合有不同的关心点和响应。数据流通过日记系统(通过chukwahadoop集群)来管理,后来我们利用Hermes作为我们的提交发布机制。
 

推荐结果

Netflix的推荐和个性化系统架构 _netflix_06Netflix的推荐和个性化系统架构 _netflix_06
我们机器学习的方法主要为了个性化推荐服务。推荐的结果一般可以直接从我们预先计算好的列表中获取,或者在线算法直接计算获取。当然,我们也可以综合利用上述两种方法,线下计算好的推荐结果集,加上在线计算的更新。

Netflix,我们以多种形式保存离线和中间的结果,最主要的形式采用Cassandra, EVCache, 和MySQL。每一个方法都有优缺点。MySql允许保存结构化的关系数据,这些数据会在未来某些查询中使用。尽管如此,会带来分布环境下的扩展性问题。Cassandra和EVCache都是K-V存储,Cassandra是一个著名的并且是标准的搞扩展性分布式noSQL存储。尽管如此,当我们需要不断的高强度的写操作的时候,EVCache会是一个更好的选择。最关键的一点就是我们需要综合考虑不同情况下的查询复杂度,读写延迟时间,事务一致性,然后来达到一个比较好的存储选择。


结论

在上述文稿中,我们强调了数据,模型和UI对建立一个世界一流的推荐系统的重要性。当建立这套系统的时候,软件工程框架也是一个非常重要的因素。我们需要这个框架能够利用复杂的机器学习算法,这些算法可以是任意的复杂度,可以处理大量的数据。同时,我们需要一个灵活的框架支持新的创新方法可以被很快很容易地部署和plug-in。最后,我们希望我们推荐结果可以被更新,并且对新的数据和用户行为反应迅速。在这些需求上找到最好的点是比较困难的,它需要深入的分析需求,小心的选择各种技术,并且对于策略有很好的解耦合能力,以达到最佳的产出