29

高德深度信息接入的平台化演进

 4 years ago
source link: http://www.cnblogs.com/amap_tech/p/12673102.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

导读

本文介绍了高德地图中POI深度信息接入在平台化过程中的一些思考和实践,从最开始的单体应用,随着业务发展面临挑战,从业务角度提出解决问题的思路和方案,进而转化成技术设计并落地实现的过程。

背景

POI是Point of Interest的缩写,即我们通常理解的地点信息。对普通用户而言, POI数据除包含名称、坐标等基本信息外,还会展示图片、评论、营业信息等内容,这些我们统称为深度信息。 作为真实世界在线上的直接体现,其丰富度、准确度、新鲜度对用户的出行决策起到了至关重要的作用,也是高德地图从生活服务等多方面服务大众的基础。

为了丰富深度信息,我们通过多种途径对接采集数据。每个数据接入源称之为一个CP(Content Provider)。最初只有少量CP的时候,每个CP建立一个应用,完全独立的存储、独立的代码,甚至采用的是完全不同的技术栈。

然而,随着接入规模不断上涨,这种单体应对模式逐渐无力支撑,无法批量生产、更新、运维、监控等问题成为了业务迭代路上的绊脚石,大家花在基础维护等事务上的精力占比甚至超过了业务迭代。

用一组数据说明下深度业务的发展速度:一个季度工作日130天左右,新接入的任务数量却多达到120个以上。截止目前接入的任务总数是研发人数的100倍以上,单日处理数据量达十亿规模。基于对这个趋势的预判,深度团队提前开始了平台化的探索。

平台化实践

平台化的思路是明确的,但是平台化的具体设计实施却有诸多不同的选择。

大多数数据接入系统的设计目标都相对比较纯粹:作为接入系统,只要把数据拿到并输入到本业务体系内就可以,剩余的如数据解析,业务处理都由下游的其他系统再次加工才可形成真正的业务数据,即接入系统从设计之初就是无状态的,对数据本身的理解也基本与业务无关。

但是考虑高德深度信息接入业务的特殊性,我们平台化时并没有采用这个方案,而是采用一种更集约化的思路,接入平台本身对数据就需要有充分的理解,不仅负责数据接入,还要负责数据解析、维度对齐、规格映射及生命周期维护等相关内容,平台直接内置了深度信息处理流程的全部管控逻辑。

另外,不同于一般的接入系统,除研发(RD)外,产品(PM)也是系统的第一用户,平台需要有能力让PM在了解有限技术约束的条件下自主完成全流程数据接入、分析和调试,这就对平台所见即所得的实时设计调试能力提出了极高的要求。从平台设计角度要解决以下一些难点:

  • 数据规模不均匀 :不同CP的数据量和数据体积相差巨大,有的源数据量有几亿条,最少的CP甚至只有一条数据。具体到每条数据大小也差距悬殊,如部分数据单条达到7.5M,有的则只有一个字段,仅几个字节。
  • 业务场景不收敛 :深度数据来源多且杂:有三方合作接口、离线文件、经济体内OSS、ODPS、MetaQ等,且CP数据结构和关联匹配规则多种多样、无法预知,需要平台在设计上能支持各种场景下的维度对齐。
  • 映射清洗逻辑复杂 :这里还有一个和常规业务不同的点,高德深度数据采用Schema比较松散的JSON方式组织,有多层嵌套对象及数组字段,且不同行业的规格并不一样,平台最终需要把数据组织成近百套不同规格的数据,这种松散的、非扁平二维表的数据处理也是挑战之一,尤其是存在数组上下文的场景里。

ju2IJnu.png!web

最终我们设计出如图所示的平台架构,平台集成了基础、转换、推送和任务调度四个模块,配合完成深度信息接入的全部工作。

ayA7BzE.png!web

平台分为几个模块:

基础模块:负责CP、行业、规格、权限等基础信息的在线化,实现统一管理。

转换模块:负责数据获取、维度对齐、规格映射等处理。

推送模块:负责转换后规格数据推送至下游准入服务。

任务模块:负责对任务的管理,如任务类型、积压策略和数据差分等。

  • 转换引擎设计

转换模块由转换引擎、转换管理器、设计器和调试器四部分组成。

为了降低系统的设计复杂度,所有业务规则的自定义部分均由转换模块支持。转换模块作为业务自由度最高的模块,使用相同的底层支持了上层业务的预转换、转换和数据分析三种场景,是系统能支持各种复杂业务场景的核心部分,转换引擎要支持数据获取、维度对齐、规格映射清洗等配置化及调试功能最复杂多变的部分。

数据获取

数据获取能力不仅要支持常见的HTTP、OSS、ODPS、MTOP、MetaQ及Push服务等多种方式,而且还要支持组合叠加。比如先从OSS下载一个文件,解析文件行,根据解析的数据,再调用HTTP服务等场景。

为了支持近乎无限的业务叠加能力和所见即所得的设计效果,我们调研了阿里经济体内外的多种解决方案,如Blink、Stream平台等,没有发现可以直接满足我们业务需求的组件,主要问题为:

  • 基于技术维度组织,需要大量写代码或理解技术语义,无法提供业务视角,对数据PM的理解和使用有极大的障碍。
  • 步骤数据视图是扁平二维表,无法实现松散结构传递和处理。如果在步骤间自定义业务约束及协议则过于复杂。
  • 无法支持实时无副作用调试,运行流程和调试流程数据会互相污染。

基于以上分析,我们决定不在上述平台上进行二次开发,而且直接基于当前业务场景定制一套引擎,虽然这些引擎无法直接使用,但是PDI的步骤组织及驱动方式和我们的业务场景比较匹配,从自由度、表达力和直观性几个角度考虑,转换引擎舍弃了DAG这种依赖计算和并行调度都相对容易的技术模型,使用和PDI类似的有向图模型进行组织。

2E7Fne7.png!web

为了最大限度的支持PM直接对业务场景进行描述,我们最终采纳了PDI的转换引擎设计思路,直接以原始有向图方式对步骤进行驱动执行,最大限度保持设计直觉和运行时的逻辑一致,从而不需要实现引擎层面的翻译器、优化器、执行器等复杂组件。

R3MZn27.png!web

为了保证引擎的执行效率和安全性,我们保证步骤间数据传递不会跨进程,所有数据交互全部在内存内完成,且步骤之间均为异步并行执行,通过背压感知机制从后向前传导,平衡各步骤间的处理速度差异。

维度对齐

维度对齐是指把不同数据源、不同维度的数据通过给定的业务规则关联整合成某一种维度的数据,比如深度信息业务一般需要整合成POI维度的数据。理论上有了引擎提供,能直观表达并堆叠业务的能力可以实现维度对齐的需求。但是,深度信息还有一个问题要解,即面对数据PM使用实时调试的需求,所以无论复杂还是简单的转换都需要能随时调试,并直观地展示结果,方便数据PM快速分析和排查。

常规ETL里都会涉及维度对齐的问题,但是由于常规业务一般都是二维数据表间的关联整合,所以像PDI之类的方案基本都是通过SQL+临时表的方案进行处理,在设计时即绑定了输入输出,调试和运行并无本质的区别,或者调试时需要修改配置,强制输出到一个临时存储,这意味转换引擎需要依赖特定的外部环境(如特定的数据库表),造成调试和运行时的数据会互相污染。

我们的数据天然不是二维结构,无法平铺到表中,自然也就无法使用这种方案。我们采用的是只依赖本机内存+磁盘的方式进行数据处理,如flatten这种数据打散的需求直接用内存实现,不需要借助存储;像merge join等可能全量数据交叉运算的直接采用本地磁盘做辅助,实现了全部功能都不需要外部特殊环境支持,秉承这个思路,我们最终实现了具备如下能力的转换引擎:

纯引擎

  • 不写数据,不生成执行记录。
  • 不依赖任务及特殊执行环境。
  • 可以随时初始化并执行。

数据透出

  • 转换配置不需要指定输出,数据输出步骤动态挂接。
  • 多种场景管理器:任务场景会写到DB,调试场景通过WebSocket回传到前端页面。

有了这样的引擎,综合考虑调试场景的要求,转换在设计时不再需要指定输出目标,输出目标会在运行时由场景管理器根据调试场景和正常运行场景动态挂接,避免数据互相污染。平台在Web端支持几乎所有层次的所见即所得的调试分析功能,覆盖了预转换、转换、清洗、推送等几乎所有环节。

规格映射清洗

为了支持松散Schema映射和透明扩展,转换的行模型(RowSchema)创新性的设计为双容器结构。

  • 主数据:承载上游步骤的直接结果数据。
  • 数据托盘:承载转换参数、步骤变量、映射结果等内容。

22MbErj.png!web

映射步骤通过映射类型、映射规则和清洗参数支持映射清洗一体化。

  • 正向映射:自上而下进行数据提取,以扩展JSONPath表达式(扩展了主数据、数据托盘、数组循环item等上下文语义)为主,多种映射类型为辅。
  • 反向清洗:自下而上逐层清洗,可任意叠加策略。

转换模块通过步骤、映射、字段清洗三个层次对数据进行处理,PM使用时只需要通过Web界面拖拽对应组件并简单填写一些业务参数即可完成配置。

为了避免业务黑盒问题,系统设计不同于Stream平台的一个地方是系统组件会向后兼容,步骤插件、映射插件、清洗插件都没有版本的概念。系统不支持的自定义业务在各个系统模块均可以写脚本(Groovy)的方式托底实现,但是不允许上传二进制包,代码必须以配置形式直接体现,避免后期的维护问题。

生命周期管理

生命周期是指系统要在适当的时机触发数据的新增、更新、删除操作。站在数据接入的角度,删除是一个较为复杂的过程,业务术语称之为下线。要说清楚下线问题得先说下深度信息的任务模型。

目前我们支持批处理和流处理两种模型,如大家直观理解的,批处理任务每次执行都会递增一个批次号,比如常见的定时任务类型。流模型指任务一旦打开就会始终保持运行,数据一般是通过MetaQ、Push服务等方式被动接收的,没有批次概念。

为了满足业务需求我们支持批次过期、时间过期、条件下线三种策略,且支持多策略叠加使用。而这些策略设计时也有各自要考虑的内容,如批次过期怎样避免扫描全批次的历史记录、历史和重试场景批次号的共享递增问题;时间过期如何避免对每条记录绑定定时器造成的定时器数量爆炸等等。

生命周期管理涉及到比较多的任务模块设计内容,比如任务调度模型及多机分片机制设计,任务预警熔断逻辑设计,存储表的设计等,由于深度信息业务的集成需求,接入平台没有选用开源或阿里经济体现有的任务调度框架,而是自己定制开发了一个,篇幅有限这里不再展开论述。

小结展望

深度信息接入平台见证了高德深度接入飞速发展的几年,以极低的人力投入支撑了高德在各垂类领域的深耕拓源,为高德向生活服务类高频应用拓展提供了底层数据支持。未来我们还将在全链路Debug、运营精细化场景支持、非标数据处理、自由业务编排平台等方面继续深化和演进。

rQRvEvY.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK