Apache Flink 在翼支付的实践应用
![Apache Flink 在翼支付的实践应用](https://static001.geekbang.org/infoq/0b/0bdca594c09824c61f388877473a1e85.jpeg)
摘要:本文整理自翼支付高级开发工程师曹劼、尹春光在 Flink Forward Asia 2021 平台建设专场的分享。本篇内容主要分为四个部分:
公司简介
实践中的问题
案例实践
未来规划
一、公司简介
![](https://static001.geekbang.org/infoq/00/00f6803cd7dd51a35cddbdae620252ef.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
翼支付是中国电信的全资子公司,公司主要业务分为民生缴费、消费购物、金融理财,同时我们依托云计算、大数据、人工智能等技术手段,赋能线上及线下的商户。
![](https://static001.geekbang.org/infoq/9a/9ac1df6fc4f3a5975182b7c522bd70b4.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
公司主要的业务板块分为数字生活、数字金融及金融科技服务。其中数字生活主要是指常规的支付业务,例如民生缴费,即居民的水电煤气费缴纳等等,同时我们会结合电信联合推出 5G 的权益套餐;数字金融主要是包含保险、理财、信贷,其中橙分期和企业白条是重点产品;科技服务主要分为企业征信及数智业务,企业征信是指依托现有的云计算、大数据、人工智能、区块链等核心科技能力,打造专业高效智能的风险管理及征信科技解决方案。数智业务是指以天翼云为基础平台,重点聚焦 SaaS/PaaS 服务及金融安全服务,打造端到端的金融解决方案。
![](https://static001.geekbang.org/infoq/62/621cacc30c3fa5a8bd369972b2f9e965.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
目前,翼支付的月活用户数为 5000 万+,存量用户数 5 个亿+,线上的服务器大约 4000 台,每日的记录数为千亿条。
![](https://static001.geekbang.org/infoq/83/8356e943aea405ce56615e373c371ff3.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
随着公司的业务规模不断扩展,我们面临的业务挑战也在不断增多,主要表现在两个方面:
一方面,随着需求量的不断增多,采用定制化开发的方式使得应用的数量急剧增加,导致应用难以统一管理,各个业务线的应用向着烟囱式的方向发展,指标口径和计算不统一,重复的加工会造成能力的浪费;
另一方面,某些场景下的单 topic 数据量高达 220 万/秒,同时针对风控等场景,业务响应延迟要求 200 毫秒以内。
![](https://static001.geekbang.org/infoq/bd/bd4a265e9617b4ac7dbef5b2cbe90007.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
针对以上问题,我们从 18 年开始,结合行业的实践经验,积极探索建立实时加工体系。在 19 年开始着手构建实时指标加工系统,引入 SparkStreaming 作为计算引擎。在 20 年初出于对时效性的考虑,我们引入 StructuredStreaming 作为实时计算引擎。随着服务的应用不断增多,我们接收到依赖原子指标的组合的实时决策需求逐渐增多。因此在 20 年 9 月份,我们开始构建实时决策系统,将 FlinkCEP 引入系统中。直到今年 4 月份,为了解决一些复杂指标的加工需求,我们将 Flink SQL 引入到了指标加工链路中。
经过产品的不断迭代,最终形成了一套企业化的智能决策系统——先鉴平台。
![](https://static001.geekbang.org/infoq/8e/8e6c528344ee6049df7a5d56be790bd6.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
上图展示了先鉴平台的主要功能。首先是实时指标加工。目前我们支持多样化的数据源,主要包含常用的中间件比如 Kafka 及 Pulsar。同时为了降低用户的使用难度,我们提供了 23 种算法模板,也支持 SQL 的定制化加工方式;其次是实时决策。我们支持丰富的规则及规则组的嵌套组合,满足复杂决策的需求。此外,我们整合了实时、离线及第三方的标签,为用户提供统一的数据查询服务,同时为了生产的稳定性,我们提供了全面的监控功能和细粒度资源隔离、熔断、限流的策略。同时针对实时计算作业的运行状态,我们对 Source 及 Sink 的数据量和延迟都进行了相关的 Metrics 监控。
![](https://static001.geekbang.org/infoq/b3/b3be8e9207d8c7f4daca3f0cef1b15ce.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
上图展示了先鉴平台的逻辑架构,主要分为 4 层。
最上层是应用调用方,主要包含智能风控、智能决策、智能营销系统;
往下是实时决策模块,提供实时决策的功能,其中包含 Web 进行决策的配置及管理,同时提供开发中心进行决策任务的验证,通过决策核心进行实时的决策;
第三层是实时指标加工模块,通过用户配置不同的加工方式,录入到不同的执行引擎,同时整合数据服务,为用户提供结果查询;
最下面是数据层,数据源主要包含业务数据、用户的埋点数据以及集团加工的离线数据。最终根据用户的配置,将计算结果存储到相应的 DB。
![](https://static001.geekbang.org/infoq/52/52f067825e8e4c803b0b5a5a3a8cbab8.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
实时指标加工系统的技术架构图主要包含三个模块。前端界面主要负责用户任务的配置及权限管理,后台会将用户配置的信息生成相应的自定义 DSL 语言格式提交给内核,内核根据不同的配置方式,经过 Mode Selector 选择相应的执行引擎。
如果通过模板的加工方式,则会经过 DSL Parser 进行语法解析,再进行数据的清洗以及算法的计算;如果是 SQL 模式,则只进行 SQL 语法的解析,同时加载用户的 UDF 及相关配置信息生成相应的任务执行图交给 Program Deployer 并选择相应的部署环境进行任务的发布。
执行环境通过 yarn 进行资源管控,同时 HDFS 负责元数据存储。
![](https://static001.geekbang.org/infoq/6f/6f65b0ce32b48b9ecf08359a7ef6cd9e.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
Stream SQL 的功能分为基础功能和性能监控功能。
基础功能主要包括以下几种:
SQL 语法校验。目前支持 Flink SQL 语法,在用户提交之前先进行 SQL 语法的验证;
沙箱测试。用户可以预提交任务并进行任务准确性的验证;
支持用户 udf 函数的加载。
性能监控功能主要包括以下几种:
提供了细粒度的资源配置。社区版本的 Flink SQL 不支持 operator 层级的资源配置,只能使用统一的并行度配置,会导致生产上某个节点压力过大而造成任务延迟的情况。所以我们通过获取 Streamgraph 的 JsonPlan 的方式进行各个节点的并行度设置,从而实现细粒度的资源配置;
任务状态监控。我们会监控任务的运行状态,同时考虑任务延迟以及加工链路过长的问题。我们仅仅针对 source 及 sink 的数据流和流量的变化率进行监控,一旦发现变化率异常,会及时反馈给业务用户,能够尽早发现业务变化;
失败任务自动恢复。能够通过获取最近一次 Checkpoint 进行恢复。同时针对 Checkpoint 周期长的任务,在重启时考虑恢复时间的问题,我们会在重启时之前强制进行一次 Savepoint,从而缩短任务恢复时间。
![](https://static001.geekbang.org/infoq/0e/0e4b18bf6accbbff7794f034cd232738.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
上图展示了实时指标配置的过程:
第一步,配置相应的 Source、Schema 信息或提供数据的 demo 进行自动解析;
第二步,选择数据清洗的方式,这里提供了几种简单的数据清洗逻辑,也支持 SQL 的方式;
第三步,选择计算用的算法模板,也支持算法的嵌套。
![](https://static001.geekbang.org/infoq/13/1364e696b22362bc6768748ebd84cc4e.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
上图展示了 SQL 加工配置的过程。先创建一个任务,包含用户的资源等参数,然后编写任务 SQL,最后上线任务并提交给执行环境。
![](https://static001.geekbang.org/infoq/44/441c49defddc8ec9f6075e200a513178.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
实时决策模块里的前端页面主要负责决策任务的配置及用户权限管理,并将任务提交给后端。后端会通过 Zookeeper 将上线的策略发布到相应的决策节点。每一个执行节点都有一个 ZK Watcher,用于监听策略的状态,通过 RuleLoader 加载策略并通过 RuleCompiler 对策略进行编译,最后交给 Flink CEP 进行决策执行。最终将决策的结果存储到 DB 或中间件。
![](https://static001.geekbang.org/infoq/e4/e474f7a43e1a932438b4b311a078406f.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
决策配置的过程首先需要创建一个任务,然后配置相应的规则以及规则的组合,最后通过开发中心进行任务的试运行,验证决策的准确性。
二、实践中的问题
在实践过程中,我们也遇到了很多挑战,总结起来有如下几个方面:
![](https://static001.geekbang.org/infoq/ed/ed0cc86cfb7865fc522858c7ba83e75b.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
业务 State 数据一致性、指标重复计算问题、动态规则配置以及全链路监控监控问题。
![](https://static001.geekbang.org/infoq/dd/ddf80f7223786c81ab224490b1f2562c.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
首先是指标作业升级过程中,通过指标引擎配置的 job State 数据一致性问题。早期指标作业是通过手动开发,部分业务 State 存储在 HDFS 中,指标引擎配置的 job 没有单独管理业务 State 的数据,老的任务迁移到平台过程中就会遇到数据一致性问题。
解决思路是扩展老的计算程序,读取全量 State 数据存储到外部,然后停止老任务。指标引擎配置的作业从指定的 offset 进行数据计算,然后从外部存储补齐原有的指标数据。
![](https://static001.geekbang.org/infoq/a0/a0362d114034f7ae2f01921aba4f2b8f.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
上图展示了作业升级的流程。Task 在 open function 的时候读取业务 State 数据存储到外部。如果是 Keyed State,则 State 接口无法获取当前 task 的所有 State 数据,需要将 State 对象进行向下类型强转,然后获取所有 State 数据指标引擎。作业通过配置指定对应的 offset,通过从外部补齐数据的方式进行指标计算,从而完成数据恢复。
![](https://static001.geekbang.org/infoq/28/28f004bdf3ccc5dfba29a1440137c2bb.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
其次是指标作业在不断新增过程中存在的痛点,多个作业重复消费同一个 Kafka 导致上游消费压力大以及指标重复计算的问题。
![](https://static001.geekbang.org/infoq/31/314114da461d39aac97143a6989be585.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
针对以上痛点,我们的解决方法是对所有作业进行统一优化,对所有消息源进行统一预清洗,按照业务过程分发到对应的数据域 Topic 中。对指标进行统一的口径管理,保证指标不重复计算。目前没有对实时指标进行分层处理,主要为了避免在计算链路过长从而影响业务的时效性。
![](https://static001.geekbang.org/infoq/91/91f726da544a1747023f90649041f8a1.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
第三,Flink CEP 存在的问题。实时决策的模块是通过 Flink CEP 进行规则匹配,最初是通过程序编码的方式实现规则的匹配,然而随着规则越来越多,不便于维护,开发成本也随之增加。Flink CEP 无法进行动态的规则配置以及多个规则并行决策。
针对上述问题,我们对 Flink CEP 进行了扩展开发来解决规则动态配置以及多个规则决策的问题。
![](https://static001.geekbang.org/infoq/fc/fc521d6d68a561e1fa6d73dbc45f75be.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
上图展示了 Flink CEP 扩展开发的逻辑架构。用户通过 RuleManager 配置规则并将规则变更事件发布到 Zookeeper 中,RuleListener 监听到事件的变更后,若是新增规则,则会通过 groovy 动态语言编译生成 RulePattern 实例。随着规则的增多,CEP operator 线程处理效率会下降,需要通过把规则分组绑定到对应的 Worker 上来加速规则处理。CEP operator 线程接收到事件后会分发给所有 Worker,Worker 线程处理完后通过队列发布到 CEP operator 线程,最后发布到下游。
![](https://static001.geekbang.org/infoq/24/2486728ae0f46cd585a4f3e164cbf650.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
最后是数据全链路监控的问题。数据流从收集端经过 Flume 传输,再到消息中心指标计算,然后发布到下游的实时决策,不允许大量的数据丢失以及数据延迟。
基于以上诉求,需要对整体数据链路进行监控,采用 prometheus + grafana 进行 metrics 的收集以及告警。这里主要针对 Flume 消息中间件进行消息堆积以及丢失的监控。Flink 指标计算主要监控运行状态以及背压情况,下游监控 CEP 决策的时间。对数据链路的监控能够帮助运维快速定位并解决线上的问题。
三、案例实践
![](https://static001.geekbang.org/infoq/19/19c03d40e9a5725f8fc2f5cd8bbee487.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
上图展示了先鉴平台的工作方式。
首先,上游的用户行为和业务事件通过数据通道传输到先鉴平台,业务方负责配置实时指标和业务规则,当业务事件通过指标计算结果触发了业务规则,先鉴平台随即将结果推送到下游的消息中心,通过各业务系统触达到用户。比如用户访问理财首页时,如果 30 分钟内未进行产品申购,就会根据用户的资质给他发送对应的推送短信。
四、未来规划
![](https://static001.geekbang.org/infoq/80/80c5b02279b1cdbcc53c45fe59c20423.jpeg?x-oss-process=image/resize,p_80/auto-orient,1)
未来,我们计划在以下几个方面进行持续探索:
第一,数据库增量采集的方案统一。目前 MySQL 的采集是使用 Canal 实现的,未来我们规划使用 Flink CDC 来针对 Oracle 和 MySQL 进行统一的增量采集;
第二,离线实时的批流融合。目前离线数仓通过 Spark SQL 计算,实时数仓使用 Flink SQL 计算,维护两套元数据以及不同的指标口径使得日常工作负荷很大,因此我们希望使用 Flink 来完成统一的批流计算;
第三,Flink 作业自动扩容缩容。目前 Flink 无法进行自动扩容缩容,早晚流量变化较大,会导致较多的资源浪费,计算能力不足的时候只能通过人工进行作业扩容。我们希望基于 Flink 来实现自动扩容,降低运维成本。
更多 Flink 相关技术问题,可扫码加入社区钉钉交流群第一时间获取最新技术文章和社区动态,请关注公众号~
![](https://static001.geekbang.org/infoq/6f/6f7be2f7e9f8afb492678a68a55b04d7.png)
版权声明: 本文为 InfoQ 作者【Apache Flink】的原创文章。
原文链接:【http://xie.infoq.cn/article/05e9ed73807989ecc4e2a6b90】。文章转载请联系作者。
评论