最新消息:关注人工智能 AI赋能新媒体运营

Pinterest如何设计新广告推荐系统,来有效模组化数十万行程序码

科技智能 admin 浏览 评论

在2021年底,Pinterest决心砍掉重练旧广告推荐系统Mohawk,打造新广告系统AdMixer。他们期待新系统上线后,能额外投入上百名工程师来参与广告系统,开发和维运新产品和演算法,来支援飞速成长的广告业务。不只如此,新系统设计下,不同工程团队开发和维运时,不能互相干扰,且维持高服务稳定性及数据完整性。

新系统更要避免重蹈旧系统覆辙,否则随着业务持续增长,系统肥大、难以改动、错误频出等同样问题,仍会再次浮现。

基于前述需求,他们奠定出4大设计原则,包括易于扩展、明确划分系统边界、安全设计(Safe by design),以及利于高效开发。

首先是易于扩展原则。系统框架和API需要具备足够弹性,既能支持新功能扩展,也能方便地淘汰旧功能。尤其,记取上一代系统累积巨量技术债的教训,Pinterest这次特别加入功能淘汰的设计,避免导致系统过于拥肿。

再来是明确划分系统边界,根据业务逻辑来定义高层次、抽象的系统模组。这样一来,不同团队负责的功能会各自形成一套模组,并相互隔离,以避免开发和维运过程中彼此干扰。

安全设计原则,强调从高层次的设计和逻辑来确保执行绪安全和数据完整性安全。他们希望用并行运算(Concurrent computing)来提升效率,但不互相竞争资源。同时,多执行绪并行时,希望能避免数据被任意改动,导致系统错误或Logging到错误数据。

利于提升开发效率原则,则是在设计系统时就将开发体验纳入考量,并提供开发者易于使用和重複利用的测试和分析工具。

为了实现这些原则,Pinterest工程团队採用了DAG图学架构,来组织程序码模组之间的关係。同时制定了一套资料模型,作为DAG不同节点传递数据的规则,以保证程序执行时的执行绪和数据安全。

以Twitter为师,用DAG图学架构来组织程序码模组

Pinterest旧版广告推荐系统不只有38万行程序码,更串联超过70个外部资料来源,来执行请求处理器(Request handler)、特徵拓展器(Feature expander)、检索(Retrieval)、排序(Ranking)、竞价(Auction)等一系列功能,规模庞大、内外部系统关係複杂。

为了妥善划分程序码模组,以及管理模组间的耦合性,Pinterest採用Twitter开源的非同步性服务(Asynchronous service)运作框架Nodes,来设计新一代广告推荐系统。

Pinterest还以Nodes为基础,修改出自家程序码组织框架Apex,并规定较Mohawk严谨许多的资料模型规则,来确保节点间,数据传输的规格与处理模式都如预期进行,以符合安全设计的设计原则。

Pinterest以Twitter开源的非同步性服务运作框架Nodes为基础,发展出新一代广告推荐系统的程序码组织架构Apex,来管理负责模组间的耦合关係及资料传输流程。

此框架採用了一个特别的程序码组织方式,将一个个程序码模组视为节点,串联成一个网状DAG流程图。Pinterest看好这套架构,可以组织和执行RPC(远端程序呼叫)服务器等非同步性服务,适合用来打造AdMixer模组间耦合性複杂的大系统。

工程师添加新模组时,就像是于这张DAG流程图中新增一个节点,需要明确定义上下游依赖关係,也就是新节点与其他节点之间的箭头。反之,淘汰功能时,能明确看出移除一个节点后,哪些上下游节点会受耦合性影响,避免意料之外的错误。

用更严谨的资料模型规则进一步强化系统安全性设计

Pinterest工程团队为Apex框架定义出一套,适用于广告推荐系统的资料模型,统一规範资料在节点间传输的结构和型别,以及资料存取或更动的限制。

他们维护资料模型规则的做法是,将一系列资料结构及资料处理规则检查机制,写在一个个Java物件中,用来连接节点,以确保数据传输时,节点处理数据的方式符合预期。

他们还将系统中的节点,组织为一个个节点子群组,每个子群组内的节点都有相同资料模型。这样一来,当一个子群组要拓展新节点,能轻鬆套用同一套资料模型,符合AdMixer易于扩展的系统设计原则。

Apex框架需要搭配更加严谨的资料模型规则,是记取了前一代广告系统Mohawk的教训。旧系统允许程序码在任意地方修改全域的资料,且没有检查机制来维护数据处理流程的最佳实践方法,冲击系统数据完整性。甚至,当不同并行执行的功能模组需要同时存取同一份资料,还有可能造成执行绪安全问题,导致其他节点存取到错误数据,彼此干扰,并影响到整体广告投放流程。

Apex资料模型规则中,尤其重要的两项是,严格数据输入和输出节点的数据型别,以及资料单次写入原则。

资料模型关键规则一:强型别数据传输模式

Apex资料模型的一项重要规则是,节点间资料传输时,必须明确定义输入与输出的型别。

Twitter Nodes框架下的节点是弱型别(Weakly-typed),只会定义数据输出型别。输入时,则採取通用的「物件(Object)」类型处理,需要进一步由编译器来自动转换型别,或用程序码来手动转换型别。这种设定,容易出现人为错误,且不容易快速追蹤到错误根因。

为了避免此问题,Pinterest设计Apex框架时,将节点调整为强类型(Strongly-typed),统一于资料模型中定义数据输入与输出的型别。

开发者无需再手动撰写类型转换的程序码,且早在执行阶段之前的编译阶段(Compile time),编译器即能自动检查数据类型,準确抓出型别错误发生的程序码,既节省除错时间,还能避免对广告业务的影响,是为了满足安全设计和利于高效开发两项原则的做法。

资料模型关键规则二:单次写入原则

另一条重要的资料模型规则是,节点间传输的数据,必须符合单次写入(Write-once)原则。

AdMixer预设的Thrift数据框架下,数据是可变(Mutable)的。不过,Pinterest为了在编译阶段就能维护单次写入原则,特别写出一套脚本,来产生只有取值器(Getter)而没有设值器(Setter)的不可变(Immutable)Java资料类别。

接着,尽可能将资料、资料栏位、资料类别,都设定为不可变属性。他们花了大把时间研究,哪些资料适合设为不可变属性,如广告请求相关的资料。当节点有需要动用这些不可变资料时,需要产生新版本资料,而不能更动原始版本资料。

这些做法,是为了确保广告投放流程中,不同执行顺序的节点都能存取正确版本的数据。同时,两个节点同时存取相同的数据栏位时,不会意外修改该数据并影响其他节点。

常见避免这些问题的做法是资料锁定(Data Lock),在资料库端或其他资料储存环境设置,每次只有单一执行绪能存取和修改资料。Pinterest则从资料模型规则下手,来统一规定整个系统的资料处理模式,进一步确保资料处理模式符合预期。

AdMixer的四大系统设计原则,以及因应而生的Apex程序码组织框架和一系列严谨的资料模型规定,都是Pinterest为了避免重蹈旧系统Mohawk覆辙,而採取的做法。

他们表示,这些做法都是为了Pinterest广告业务规模提升时,较不易累积技术债,同时让系统错误能在更早的阶段显露,以提升开发和维运效率,进而降低对广告业务的冲击。

系统设计时期所採用的高度模组化做法及一系列资料模型规定,更有助于他们在测试和转移阶段,能降低成本、增加效率。

发表我的评论
取消评论

表情

您的回复是我们的动力!

  • 昵称 (必填)
  • 验证码 点击我更换图片

网友最新评论