风险洞察之事件总线的探索与演进
作者:京东科技 刘红申
一、事件总线介绍
事件总线,或称其为数据管道,作为整个风险洞察数据流转的重要一环,它承担着风险实时数据统一标准化的重要职责。
在面对复杂多样的上游数据,事件总线可以将复杂数据进行解析、转换, 富化、分发等操作。底层核心算子抽象为source、transform、sink三层架构, 支持各层算子插件式扩展, 并支持groovy、python等脚本语言自定义配置,以及自定义jar包的上传,拥有将上游数据单向接入多向输出的能力,在数仓与上层应用的开展中,起着承上启下的作用。
二、事件总线-遇到的技术挑战与解决方案
技术难点与挑战
风险洞察平台运行初期,业务数据接入完全采用定制化代码处理,通过代码配置消费MQ消息,然后根据业务需求,完成其所需字段的解析,最终数据落入Clickhouse。这种业务接入方式在早期是可以满足业务所需,但是随着风险洞察平台在风控领域的不断推进,业务的发展与数据不断膨胀,面对风控数据的复杂多样性、消息平台的差异性,数据接入定制化成本也越来越高,同时数据转化与计算逻辑的强耦合,大促时期吞吐量已然达到瓶颈,呈现出越来越多的痛点:
1. 数据结构差异性: 随着风险洞察平台使用业务方的的不断增加,业务数据消息体的复杂性也不尽相同,如复杂场景以天盾反欺诈场景为例,消息体结构包含对象、对象字符串而且还有数组;简单场景以内容安全为例,消息体结构就是简单平铺的一层;面对风控数据的复杂多样性,定制数据的统一标准化已然迫在眉睫;
2. 代码逻辑重复性: 对消息体的处理绝大多数逃离不了序列化与反序列化操作,然而随着业务量的增多以及开发人员的不尽相同,业务代码是每日剧增且带有参差性的,逻辑重复,维护成本高;
3. 解析写入低效性: 同一个MQ消息可能会对应很多的业务方,不同的业务方所需业务数据又千差万别,如以天策MQ为例,实时数据中包含着金白条数据,金条与白条数据又区分着各自的业务线,如果单次订阅MQ消息,会导致逻辑处理极其复杂,不可维护;然而采用多次订阅,又无法复用已有逻辑,且导致数据成倍增长,造成资源浪费,同时吞吐能力成为瓶颈;
4. 输入输出多样性: 随着风险洞察平台被使用的越来越广,来自于上游数据的生产方式也出现了多样性,如JMQ2、FMQ、Kafka以及JMQ4等等,同时又为了给用户更好的平台使用体验,不同业务数据又会被落入不同存储中,如Clickhouse、R2m、Jes以及消息队列,如何快速支持这些组件成为了挑战;
5. 业务需求易变性: 上游业务频繁的策略调整与变更,对应到事件总线就意味着解析字段以及底层表字段频繁的增删改,正如字段解析完全依赖于硬编码且不同业务数据耦合着各自的业务逻辑,导致开发人员维护成本极高,开发周期长、上线影响广;
技术解决方案
研发一套数据流转服务,用其贯穿数据接入到数仓存储的整个流程,再结合风险洞察平台特性,以数据源组件为基础,作为数据流转的入口与出口,具体方案如下:
三、事件总线-整体架构图
事件总线-架构介绍
事件总线整体架构抽象为三层,source、transform 和sink。 通过连接器扩展机制实现数据引擎扩展, 并采用责任链模式处理数据链路, 插件化管理函数、脚本,实现实时消息接入、过滤、富化、转换、分发标准化处理, 并通过分组消费、降级机制保证架构高可用。
事件总线-核心类图介绍
事件总线定义了一个顶层父接口IEventHubExecutor,并定义了一个execute方法,其三个主要子接口,IEventHubParse、IEventHubTransform与IEventHubSink分别对应于事件总线的三个组成部分,source、transform和sink。通过实现这三个子接口,便可以完成对不同中间件的适配问题。比如,目前事件总线仅支持解析的数据写入到Clickhouse,但业务需求需要做检索,那么很显然数据存储在Es要优于存储在Clickhouse,所以此时需要扩展一个JesEventHubSink来实现IEventHubSink即可。
其中Context作为上下文,贯穿了整个事件总线的执行过程,上下文中包含了解析过程中所需要的一起信息,比如,从哪里来的数据、要解析哪些字段、解析好的数据送到那里去等等。
事件总线-自定义函数介绍
自定义函数的实现,其实借助了开源框架Avaitor表达式,Aviator是一个轻量级、高性能的Java表达式执行引擎, 它动态地将表达式编译成字节码并运行,主要用于各种表达式的动态求值。相比Groovy这样的重量级脚本语言,Aviator是非常轻量级的表达式执行引擎。
事件总线-动态分组、一键降级与流量监控介绍
分组消费
事件总线解析能力的提升,也很大一部分归结于分组消费的设计,对流量做到灵活分流,对机器做到物尽其用。动态分组,又分为物理分组与逻辑分组,如下图:
一键降级
一键降级更多的用于大促期间,但是为了降的更加“人性化”,一键降级我们也做了分类:丢弃降级与积压降级,如下图:
流量监控
事件总线的流量监控现依赖于ump,对单个主题以及所有主题的入口都设有埋点,数据在每个关键流转位置解析性能以及流量都能被监控,代码片段如下:
Profiler.registerInfo(this.getClass().getSimpleName(), UmpUtil.UMP_APP_NAME, false, true);
四、未来展望
自事件总线上线以来,已经经历了多次大促考验,大促解析量已达5000w/min,日常解析量也已2000w/min,伴随着风险洞察平台被越来越多的部门所使用,事件总线已然成为其重要组成部分,为了更好的提高解析性能,就需要去做更多的探索。同时,目前事件总线做的更多的是对实时数据的处理,未来我们也将推进flink-cdc等技术在事件总线中的应用。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
微服务拆分治理最佳实践
作者:京东零售 徐强 黄威 张均杰 背景 部门中维护了一个老系统,功能都耦合在一个单体应用中(300+接口),表也放在同一个库中(200+表),导致系统存在很多风险和缺陷。经常出现问题:如数据库的单点、性能问题,应用的扩展受限,复杂性高等问题。 从下图可见。各业务相互耦合无明确边界,调用关系错综复杂。 随着业务快速发展,各种问题越来越明显,急需对系统进行微服务改造优化。经过思考,整体改造将分为三个阶段进行: 数据库拆分:数据库按照业务垂直拆分。 应用拆分:应用按照业务垂直拆分。 数据访问权限收口:数据权限按照各自业务领域,归属到各自的应用,应用与数据库一对一,禁止交叉访问。 数据库拆分 单体数据库的痛点:未进行业务隔离,一个慢SQL易导致系统整体出现问题;吞吐量高,读写压力大,性能下降; 数据库改造 根据业务划分,我们计划将数据库拆分为9个业务库。数据同步方式采用主从复制的方式,并且通过binlog过滤将对应的表和数据同步到对应的新数据库中。 代码改造方案 如果一个接口中操作了多张表,之前这些表属于同一个库,数据库拆分后可能会分属于不同的库。所以需要针对代码进行相应的改造。 目前存在问...
- 下一篇
【码农教程】单元测试利器——手把手教你使用Mockito
作者:京东零售 秦浩然 从你成为开发人员的那一天起,写单元测试终究是你逃不开的宿命!那开发人员为什么不喜欢写单元测试呢?究其原因,无外乎是依赖。依赖其他的服务、依赖运行的环境、等等,各种依赖都成为了我们写单元测试的绊脚石。那现在有个单元测试利器可以帮我们解决依赖的问题,你愿意使用一下吗?你愿意!那就是我们要学习的Mockito 一、前期准备~ 1、准备工作 <!--mockito依赖--> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>2.7.19</version> <scope>test</scope> </dependency> <!-- junit依赖 --> <dependency> <groupId>junit</groupId> <...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Red5直播服务器,属于Java语言的直播服务器
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2全家桶,快速入门学习开发网站教程
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2整合Redis,开启缓存,提高访问速度