摘要:本文整理自网易互娱技术中心计费实时平台与 SDK 技术负责人林佳在 Flink Forward Asia 2021 行业实践专场的演讲。本篇内容主要分为三个部分:
- 从一次 APP 内购买支付聊起
- 实时 SDK 与平台化的双线发展
- 走向实时全关联
说到网易互娱,大家首先想到的肯定是游戏。作为网易的核心业务线之一,让游戏业务可以稳定可靠地运行自然是重中之重,而游戏业务中最重要就是 APP 内购买服务的可靠性。本文的分享,就从一次 APP 内购买聊起。
一、从一次 APP 内购买支付聊起
玩家在游戏内购买道具的操作,首先会触发客户端行为与渠道商、计费中心进行通讯,完成下单与支付。计费中心也会与渠道商进行交互,验证客户端订单的合法性以及支付状态。只有订单合法,游戏服务才会被通知发货。而这一整套流程下来,每一个参与者产生的日志、数据监控点等等,它们的来源、数据结构、时间步调可能是千差万别的。此外,这个过程中还有通讯网络、数据库、监控系统等的参与,使得整个过程非常复杂。
数据持续而大量地产生,数据之间会话的关联、数据源之间的异构、数据结构的异构还有时间步调的不一致等等,都是我们选择用实时方式去处理的原因。
2017 年之前我们的处理方式相对落后,其中还有一些比较陈旧的处理方式,比如网盘、rsync、T+1 处理离线任务等。
组件繁多、技术栈的割裂、时效性低、资源使用情况粗糙等,都会使资源无法被均匀地利用,而这正是带来时效性低的原因之一,也使代码能效、数据能效和资源能效都相对较低。
上图是我们之前的离线计算业务运行时的资源情况示意,在凌晨的时候去计算前一天的数据报表。在流式计算普及之前,这是一种非常大规模使用的模式,在凌晨的时候用一大批机器执行 Spark 离线任务去计算前一天的结果。为了使报表可以按时交付,整个离线集群需要大算力,堆叠大量的机器资源,而这些机器资源在许多时间段却是空闲的,这便造成了资源能效低下。
如果这类计算任务可以被实时化,那么它所需要的算力即可被分摊到每一个时间片上,避免在凌晨的时候资源使用严重倾斜。这些机器算力可以被托管在资源管理的平台上,所以它们也可以被其他业务所使用,进而提升能效。
那么如何选择实时化的框架?经过深刻的调研和尝试之后,我们最终选择了 Flink,它所提供的特性,可以说是完全适配了我们的场景,下图列举了我们关于技术架构选型的一些考虑。
二、实时 SDK 与平台化的双线发展
网易互娱从 2018 年开始便制定了双线发展计划,全面推进数据中心 JFlink 的实时化进程。
经过多次迭代,目前我们已经形成了一个一站式的运维平台 + 一个支持配置化开发的 SDK,且已经完成了从可用到实用的进阶,下一步就是让用户爱用。
如何提高人力以及代码的效能,是我们从一开始设计 JFlink 的时候就极其注重的。我们希望可以用有限的人力最大化地发挥出能效,所以 SDK 的配置化、模块化变得尤为重要,要实现每一个实时作业都可以用一套配置语义来描述。
SDK 中封装了 JFlink SDK 常用的连接器处理函数以及数据的流转对象,使得可以以配置化的形式来组装和使用它们。SDK 还提供了统一的配置文法,能够将作业以配置的形式描述后,动态地去组织构造 Flink DAG,以实现一个 SDK 程序包覆盖各类数据业务的特性,提高代码的复用和能效。
在 SDK 上,可以通过编写或生成 Kafka source、TiDB sink 以及中间聚合窗口的 UDF,即可拉起一个实时业务,不需要任何额外的开发。
为了配合 SDK 作业的统一文法,我们也构建了一个一站式的处理平台,数据运维人员可以一站式、便捷、可视化地构造自己的数据业务。
即便 DAG 如此错综复杂,也依然可以用解析文法来生成。
SDK 化战略实现了功能模块化、作业配置化、数据视图化以及流批一体化,让模块复用成为日常,让每个人都能相互理解彼此的作业,让异构的数据能为每一种写好的 UDF 模块进行处理,更重要的是让历史作业可以过渡到 Flink 上。
SDK 化还为我们提供了快速跟随社区升级 Flink 版本的能力。SDK 隔离了业务逻辑和 Stream API,且绝大多数扩展功能都是在 SDK 侧对 Flink 原生类的拓展。这在跟随 Flink 进行大版本升级时,一方面业务侧可以做到近乎零改动升级,另一方面也解决了内部关于 Flink 的拓展功能需要不断从各个版本的内部分支向新版分支上做合并的巨大代价。
而双线发展计划中的另一侧则是网易互娱的一站式平台,它完全基于 K8s 实现了作业的独立集群化运行。
上图是平台的技术架构图,它配套的 Nexus、HDFS 等大数据组件来作为基础设施,维护了版本化的软件仓库,里面托管了包括 SDK 以及其他业务 jar 包。运行层面,Flink 使用了 k8s 独立集群的理念,即每一个作业都运行在自己独立的 k8s 命名空间下,拥有自己的资源配套以及依赖集合,实现了业务作业的完全隔离运行以及资源的精细化调配。
为跟踪业务的迭代、作业的运行以及日志集分析等等的平台化功能,JFlink 平台还封装好了各种运维接口,通过无状态的 rest 服务节点对外提供。平台还为运维人员提供了可视化创建实时作业的功能,这也正是我们把平台与 SDK 相互配合而产生的优秀成果。
在一站式平台上,用户可以监视自己的作业实时状态,查阅运行日志,回滚历史版本,甚至可以查阅历史的异常、记录与统计、风险控制、生命周期的详细管理。
除了上述提到的能力,我们的一站式平台上还有相当多其他功能,所有的功能与 SDK 相互配合共同组成了我们的实时计算体系。
三、走向实时全关联
接下来,从数据业务的角度出发,分析阐述网易互娱在计费这一关键领域上开展实时业务的经验与实践。
我们最早的实践是对计费节点上产生的数据日志进行统计分析。不同来源的日志往往形式各异、千奇百怪,尤其是外部渠道商的回调,更是难以规范其日志格式,应该如何处理这些杂乱的格式,将它们变成一种可以统一处理的数据?这是我们第一个探索目标。
为此, SDK 封装了可以通过定义抽象语法树来处理半结构化数据的 UDF Message Unified Parse,也制定了一些可以处理 Group By 以及聚合函数的 UDF。这样的需求,以配置文法的形式实现了这个统计业务,并通过封装的 Sink,写入自研的 TSDB 中。
日志分析监控是从点的角度对计费业务接口、模块的访问量、法规情况和时延等来进行监控,以此实现对业务的无侵入式实时监视,降低了原先通过微批处理的时延以及业务服务器上监控脚本导致的 CPU 开销,也提高了监控发现率,使业务更可靠。
紧接着,我们把目光投向了做通用的 ETL 框架。
异构数据通过 Parser 可以转化为统一的视图和统一的流转对象,随后可以被内置的符合协议的 UDF 进行处理转换,我们还实现了一个 JavaScript UDF,通过灵活地 JS 脚本的嵌入,实现了轻松便捷地处理数据的转换工作。
通过 Flink 处理的数据流入我们自研的异构数据仓库中,可以让业务方很方便地使用。还可以直接使用 SQL 来对实时产生的日志进行查询,甚至对这些日志进行聚合。而这些业务是以点的角度,将支付环境上的接口模块产生的数据实时地利用起来,每日处理的数据量大约在 30 Billion 级别,它为后续展开更深一步的数据业务实时化提供了有力的保障。
在 2019 年左右,我们开始考虑如何把这些点关联成有机的线?即将在支付环境上发生的支付,会从头到尾进行一个全链路的关联分析,这其中的服务是否会发生问题?
这些服务的日志来源千差百怪,可能是来自于客户端的日志,可能是计费的日志,也可能是网关的日志。而针对这些与上下文分析有关的链路式的日志,其实 Flink 已经为我们提供了非常方便的 API,就是 keyed stream + session window。
上图是全链路监控的架构图。链路分析的知识被封装成了模型,并加载到 Flink 实时分析的程序中。它会把一条支付链路上的数据进行实时串联,然后写入到我们自研的图数据库中,供下游继续使用。此外,它还提供了 Daily Spark Job 来处理异常链路,以完成一些链路补全的需求,这也是对于 Lambda 架构的一种实践。
上图展示了全链路串联的效果。一笔支付订单可以被串联和展示,这种方式非常有利于 DBA 和产品去定位支付问题。
2020 年左右,网易互娱开始了对实时数仓的探索,其中一个很重要的应用就是用户画像系统。
此前 T+1 的形式展示数据报表,时效性比较低。将报表升级改造和实时化之后,现在已经可以通过接口的形式做到即时查询。而这种时效性的提升使得产品可以去做精细化的运营,更及时地响应营销需求,进而提升收益。
这些千差万别的计算,也是通过配置 +SDK 的形式来实现的。
尤其是流式的数据打宽,利用 Flink 提供的 Async IO 去外表进行 Lookup Join,都是实时处理数据的得力助手。
实时用户数仓和实时数仓指标为产品提供了玩家级的微观查询和报表级的宏观查询。这些用户数据可以对接到可视化工具,通过数据可视化直观地进行展示,让产品运营可以发现从数字中无法发现的规律,进一步挖掘出其中的数据价值。
有了上述实践之后,我们开始思考,在一笔链路、一个用户的层次上,能否能将整个支付环境上的各种数据都关联起来,实现支付环境的宏观监控。
我们将支付环境会话上各种异构术语,比如支付数据库 TiDB、支付中间件产生的各种日志数据,都通过 Flink 的 Interval Join 特性来进行关联分析。
比如在 TiDB 中,存储有下单与付款的数据库 40 行,日志中有用户从客户端下单到渠道回调等支付过程的记录,对它们分别关联即可分析出对应服务模块的情况。
进一步可以把各个模块情况产生的链路再进行关联合并,最终得到整个支付环境上的关联分析结果。
例如,存在一种可能的异常,数据日志发货完毕后,数量骤减或错误码的情况很多,那么运维人员可以很快发现发货服务存在异常。如上图展示这类关联分析的情况,在生成环境的一些复杂场景中,这套全关联分析框架处理了近十种异构源的数据、关联分析出几十种情况的业务场景会话。基于关联分析的能力做出的许多支付环境上的实时报表,以协助运营修复问题,指导产品制定策略,最终提升收益。
数据业务实时化之后带来的资源能效和数据能效的提升有目共睹,而高时效性带来了全新的数据使用灵感的迸发,这也正是 Flink 带来的全新的大数据未来。
更多 Flink 相关技术问题,可扫码加入社区钉钉交流群
第一时间获取最新技术文章和社区动态,请关注公众号~