来到蘑菇街大大小小的项目经历了不少,有交易,有mogu(资讯app),有社区等,从中学习到了不少东西,对技术及架构也有了更胜层次的一些了解,今天想从mogu的推荐架构部分谈谈对架构的一些思考,并不一定正确或适合各种场景,体现个人的感思。
我参与mogu项目可以说是从头至尾一起成长的,从1.0 ugc形式到改版成2.0pgc形式,其中经历过好几次系统的重构,mogu和所有的做内容的app一样,也有自己的推荐系统,一开始我是一直负责服务端的架构以及一些运维的工作(mogu海外部署有节点,公司中间件并没有海外机房有一套部署,因此海外业务使用的例如rpc框架、搜索引擎solr、缓存redis等都需要自己部署及运维)。
mogu的推荐系统一开始是由京东过来的一个团队所搭建的,2016年9月该团队有人离开也有人被裁,剩下的也被派去做其他业务了,我则被派往接手了mogu推荐系统,虽然在生生活中处处感受到了个性化推荐带来的便利,但之前是没有真正经历过推荐后边的原理,这点让我感到很兴奋。
但很快就感觉到头痛了,之前团队的离开,以及并没有跟我有直接的交接程序,以及推荐系统整个链条的庞大及复杂,我开始一点点的去整理推荐的业务,根据现有的资料,以及还在公司被分配到其他业务的同事了解其中零散的部分(之前推荐团队粗略估计不下10人,没人负责自己的模块,并不是每个人都对整体架构有掌握,还有部分业务是和杭州算法团队合作),开始推导,类似于拼图工作,整个架构中缺少的信息就如拼图中缺少的卡片,我需要根据源码来自己绘制出来,这个过程是具有挑战又让人兴奋的。
再经过咨询,业务理解,源码阅读,理解其架构思想以及初衷,终于将原有的架构做了简单的整理:
简单的说:分为离线和在线两个流程。
离线流程:推荐系统从业务系统将数据同步到自有系统db,然后写入hbase,算法团队从hbase拉取数据,进行离线计算,然后将结果写回hbase。
在线计算:主要通过db,cache存储算法计算后的预测结果,提供在线服务
这里我并不打算针对离线模型进行深刻的分析,因为在重构过程中,我主要重构的是在线服务(离线服务重构相对来说少一些),基于在线服务的重构,聊聊我对架构的思想的一些理解或探索。
在之前的架构中将系统分为了:接入层(mogu_root,图中省略了config-system,配置系统,用来配置各个推荐位)、各个推荐位的服务层(资讯推荐、单品推荐...)、预测服务(predictor)
等
接入层:主要负责处理请求、路由、限流等工作,配合config-system一起提供服务
推荐服务:具体推荐的自身的一些逻辑处理,比如数据补全等
预测服务:推荐的中央处理器,所有的推荐业务,都通过predictor操作下层的db、cache提供预测
分析:
单从技术架构来看,在线服务的分层,以及各个服务遵从的单一原则,未来单个服务的横向扩展等等,都是没有问题的。但是这样真的就够了吗?
第一个问题就是,工程特别的多,每个具体服务也构建成一个独立的服务存在,当时只有我一个人来做这件事情,大概不下20个工程,有点儿力不从心,我开始想真的需要这么多工程吗?真需要拆分的如此的细吗?在现有的业务及对未来的一些可能考虑,这个阶段这样架构真的是最合适的吗?
重构第一点考虑:mogu_root层存在的必要性,root层是联系上游客户端和下游推荐服务单元的一个纽带,有存在的必要性吗?如果没有root层,客户端通过rpc或restful或者服务化框架(自带路由及监控等功能),直接访问推荐单元可否?推荐单元是每个推荐业务的主体,随着业务的升级改造,推荐主体的变化性是不可预测的且可能是高频的,此时可能会影响到客户端被迫的升级。故暴露一个统一的出口,将变化性隔离在系统内部是有必要的,所以在我重构推荐的过程中保留了mogu_root层,我认为它的存在是有必要的。
重构第二点:每个推荐单元拆分成独立的进程的必要性,我开始每个工程逐一的阅读,发现了一些"问题"的存在,推荐的各个业务单元,里边没有任何逻辑处理,只是一个单纯的dispatcher到predictor层,所有的预测逻辑都在predictor层,这些“未雨绸缪”的工作合适吗?直接带来的后果是,要为每个单元部署节点,同时还必须是对等集群(避免单点),这无形中对创业团队的服务器资源以及人力成本做了极度的浪费,因为我认为推荐服务的每个单元上游系统还有一个root层负责处理请求转发,故作为下游系统未来的改造升级并不影响客户端的使用方式,所以此处的“未雨绸缪”性的过早拆分业务并不是明智之举,这将是我要重构的第一点。直接将推荐单元从整体架构中移除,root层直接通过rpc api的形式路由到predictor层,做数据的输出通道。这么做的原因是,在现有的业务模型下,并不需要将业务拆分的如此的细,集成在一起通过包及api的形式将业务区分开来则可以,未来随着业务的增长,再做业务的拆分,其实并不复杂,因为,将不变的及可变的因素考虑好,留出扩展的可能性,在业务的驱动下,下一次的重构也会显得很轻松。
推荐单元的在线服务的重构直接省下了服务器资源53来台,包括海外业务(有点惊讶,现有的业务的规模使用的机器量)。
重构第三点:离线服务的重构,离线服务的重构是基于算法全部交由杭州团队,改造的只是跟算法的集成方式,以及数据通道的改变。这里不多累赘。
总而言之:架构一个门平衡的艺术,需要结合资源、业务、技术三者辩证统一的方式去落地各个阶段的业务架构。脱离了任何一种都可能走向"歧途"。
以上都属个人对架构的思考,并不能以偏概全,具体情况需要具体分析,文笔有限,想表达的不知道有没有表达清楚:)。如果有同样经验或一直努力在架构的路上不断追求进步的你,欢迎一起探讨交流。