本期分享嘉宾
王磊
光大银行资深架构师
大数据团队负责人
以下是王磊老师在 SACC 2022中国系统架构师大会的演讲实录:
传统方案面临的挑战
对于实时变化数据的处理,业界常见的技术方案是CDC工具加分布式消息队列的组合,以消息作为核心管理对象。
不过,在长期应用中发现该方案仍有不足之处。本文会讲述在传统方案中光大银行大数据团队所遇到的问题,及其过程中的体系如何演进和改造,并从中沉淀了哪些经验与成功实践。
更进一步讲,本次分享的设计方案中,我们通过强化schema管理,封装SDK等方式,强化了系统的数据属性和平台级支撑能力,将消息为核心的设计替换为以流数据为核心,突出数据管理能力。
实时数据处理体系的演进过程
光大银行大致从 2017 年,就开始了实时数据处理体系的探索与实践。首先回顾下过程中体系的演进过程,大致可分为两个阶段。
光大最开始去投产上线,真正实时数据类的处理,可追溯至 2017 年。此前,已做过相关方面的规划、可行性的论证,以及备选方案上的一些讨论。
2017 年随着整个大数据的体系,应用的范围越来越广,互联网以及互联网之外的一些行业里,均有诸多实践。光大开始真正地投产上线了,当时叫做准实时数据平台。
该平台的使用,基本思路是通过 CDC 抓取工具,从交易类系统的数据库中获取最新的数据变更,将其推送到数据分析类的一些平台上,高效完成数据的分析工作。该过程中,实际上会以Kafka为核心的消息处理组件去处理这些数据,其处理有两种模式:单笔、微批。
单笔的最典型场景,像在风控及一些营销场景里;还有些是微批操作,对一些数据集的处理,希望提高其时效性,比如一些经营指标。前文提到一些准实时的场景,会有单笔,会有微批。微批模式下,比如在小时甚至到分钟完成批量数据的处理和加工。
对实时数据体系进行新改造
2022 年也即今年开始,光大对整个实时数据的体系,进行了新改造(该体系原指单一的准实时数据平台)。
整个新方案里,将其分成两部分:实时流数据平台(也称为数据总线);实时数据湖。而实时数据湖、实时数仓,其实也是近两年很热门的话题。这两个平台里,实则会更聚焦一些。
从整个定位来讲,实时流数据平台更多聚焦于流数据的处理。其处理模式更多侧重于单笔的场景,以前文提到的营销场景为例,比如具体的单笔的操作,即可触发其后的一个业务场景,该种模式下还是会放在流数据去处理。
另有前文提到的微批操作,比如对于一些关键经营指标,其实操作对象是一个数据集合,或者说落到一个数据平台上面,即体现为一个数据表的形态。
对于此种操作,光大将它转移到实时数据湖上面来做,为何如此?
以下简单说明下准实时数据平台,今年做改造前平台大概长的样子,如下图所示。从左到右看,是整个数据流。简单说,标蓝的部分是周边的系统,红色标注部分是该平台的范围内。
再从左边开始看,前文提到的就是光大的数据来源。最主要为两类:从该业务系统的数据库抓取;从日志抓取。
我相信类似的其他企业平台,大概也主要是以上两个源头。从数据库抓取的方式看,光大采用的是 Oracle CDC 工具,日志方面用 Flume,这两个抓取工具获取到数据后,便会将其投递到Kafka。其中 Kafka 里边做了多层次的划分,主要是三个层次,第一层是贴源层,所有的数据先被投递到这一层,第二层是一个标准化层。
标准化层之后下面就是订阅发布,是一个发布层。其实该层中间留了一个空间,实则用来做业务处理的;或者说对于特定的下游可能有一些技术上的适配,做一些特定的加工等等,放到最后一层,如此一来便会形成贴源层、标准化层、发布层三层的方式。
准实时数据平台特点的一些总结:
1.准实时数据平台是以消息为传输实体的,能够看到无论是 CDC 工具还是日志,它拿到数据后,实际上对Kafka来讲去推送时都是一个消息。
2.向应用去暴露原生接口,即所有的应用对接,无论是上游、下游,其实它都是以Kafka的标准接口的方式联系起来的。
3.数据是一个多层次的存储,光大将其分为了三层。
上图中4、5两点,实则为在技术上所采用技术组件的特点,以Kafka分布式消息队列为核心,内置了流计算引擎包括 Flink、 spartk stream,当然现在主要是 Flink。
准实时数据平台的问题
上述的一些特点,整个架构上面来看,相信大家能够感受到,平台还是存在一些问题。近几年的使用中,光大通过实践总结出来四类。总地来说,第一类问题其实相对来讲,有解决方式。其他几类问题,留了下来。
第一类问题:整个数据管理能力不强。
消息和数据有差异。转换程序把 avro 转成 JSON,其不足之处,即开发成本仍有点偏高。由于它实际上更多的时候,都是需要针对性做开发的。比如说有新的topic,就需要经针对新的 topic 来实现转码的工作。
再者是对于部分字段变更的抽取。采用了内置全量数据基线的方式,来补齐那些未变更的字段,这是光大实践中采用的一种方式。
其他的几个问题,目前并未得到特别好的解决,下文将逐一加以探讨。第二类问题,数据结构的上下游耦合紧密。我觉得是这类系统里面非常典型的一个问题。第三类是原生接口的变动,波及所有应用。
第四类是数据平台和资源平台的叠加。该问题正是由于第一个问题的解决手段带来的。把 Flink 作为一个很重要的能力插入进来,它会需要一定的资源,而且因为它的Flink使用相对会有一定的规模。此时光大一开始对该平台的定位,除了数据平台以外,也变成了流计算的一种资源平台。其他的流计算资源的申请,也会向该平台申请。
但这两种定位,其实还是对系统造成了定位不清晰的问题,也即它到底是一个数据平台,还是一个类似 IAAS 或是 PAAS 的资源平台。其实此时两种不同定位,两个不同方向,对系统后续的发展,会形成一些拉扯。
技术方案调研
下文阐述实时流数据平台,从新的思路、方法层面看看光大是如何解决上述一些问题的。
第一类是对于数据管理能力不足的问题,对此采用的新方式为 schema registry ,后续会重点讲解。
实际上,用 schema registry 方式,可以做到将数据的序列化和反序列化 通过统一的机制来实现,不用 case by case 做开发。第二点好处是将逻辑和算力可以做分离。该方式实则可将转换的逻辑封装起来,只有当下游需要消费这个数据的时候,此逻辑才会被真正加以运行,去消耗算力。
还有一个好处就是把算力的供给和逻辑本身分离出来以后,也即在下游若场景不需要流计算,在整个数据处理过程当中其实也就无需出现 Flink。当然去调用 schema 的一些逻辑时,调用方即应用方,因为这本身会由它去执行这个逻辑,所以其算力肯定是由下游应用方来付出算力成本的。
第二类,是关于部分字段变更的问题。将它转移到数据湖去实现了,这其实也是前文强调流数据平台时,原有的方案存了一个全量数据的基线。新方案里,是把该部分挪到实时数据湖去读,因为它是形成全量数据的高频快照的目标。实时湖的一些界定,最后会再一同讨论下。
上述说的数据结构变更耦合,我认为该问题实际上是所有的问题里最严重的。对此问题的解决方法,同样是通过 schema registry。当然这并不是 schema registry 技术,或者这种组件原生去解决的,而是在此基础上进行了一些定制化的改造。
希望达到的目的是下游的系统可以做个性化的领域。只要下游关注的这些字段无变更,即使上游有一些其他变更,下游也无需因此重新投产,来做程序的开发变更,这是希望达到的目的。同时,上下游解耦,也能控制上游变更带来的无效的下游改造成本,避免无效变更。
第三类问题,解决的新方式,会提供一个 SDK。在这种原生接口的情况下带来的影响,通过 SDK 的方式,能够做到一定的能力。实则这也是对平台化能力的一种解读。平台其实与它所采用的核心的技术组件还是有所差异。从平台角度来讲,还是应该有更高的边界,不是把组件的原生接口开放出去,如此才有更多的工作空间。
第四类,剥离资源平台。这点是由于第一点把逻辑与算力分离出去了,因此 Flink 便不会作为平台里边的强依赖,实时流数据平台也在光大内部会把它称为数据总线,这才成立。就是因为其总线的意义更多的是在于数据的传输,以及传输过程当中的管理,而并非在于对数据进行复杂的业务逻辑的加工。这种加工能力可以在某些场景下游去申请,但并非平台所具有的刚性需求,这样一来促使平台的定位更清晰,功能更聚焦。
实时流数据平台的新办法
(一)消息管理转变为数据管理
上述内容,就问题部分提到了一些针对性的解决方法,其中侧重提到了 schema registry,此处详细阐述下。简单来说,它是 schema 的一个注册库或是一个存储库。当然 schema 的支持其实是指一类的解决方案。换句话来说,它会有不同的产品。
其实 Kafka 会有一个相应的附加的套件,叫 Kafka Schema Registry。当然比如说有一些其他的,当时大概调研了两三种,都能实现类似的功能,包括现在这两年应用比较多的Pulsar,Kafka的竞品。Pulsar 其实也提供类似 schema 的管理工具。
整体而言,schema有一个集中的存储和管理,这样上下游有更好的对数据统一的解读方式。其过程实际上它可以集中化的来做管理,因为序列化、反序列化都是围绕 schema 进行的。
该方式我认为非常符合上文提到的一些诉求,它将原来的一个相对黑盒的消息,上下游自己去约定,中间的消息队列其实并不了解value里边的数据构成是怎么样的。现在通过新方式,实际上把结构体打开了。然后可以通过 schema 的统一管控去了解这些数据,进一步讲其实还可以做数据治理的一些工作。
上述内容讲了 schema 加入进来以后的变化。下图列举了具体服务的一些特性,其特性单独特指的就是 Kafka Schema Registry。
schema 绝对还有一个关键点,即支持模式演化,模式演化如何理解?刚才提到了一个数据,会对应给它生成一个schema,用于反序列化。实则它是可以支持不同的 schema 的。
(二)平台作为数据属主,上下游解耦
当上游系统众多,结构变更频繁时,线下通知机制总会出现遗漏,需要在生产环境人工介入调整,运维成本高。基于 schema 管理实现的自愈机制,可以大幅降低平台的运维成本。下游系统个性化订阅( schema registry ),避免无效变更。
该部分其实也是光大很关注的一点,因为 schema,前文讲到了上游原系统的数据库表,它一定会发生变更,意味着 schema 在整个表的生命周期里面,它的 schema 一定会发生变化。而这是一个普遍存在的现象。
当发生变化之后,在生产者、消费者之间如何以最小的变更成本,保证数据流整体的通畅,这其中会涉及到兼容性问题,不同 schema 之间的兼容性,比如说上文提到若下游只是关注它其中的几个字段,其实下游可以有一个独立定义的 schema,做整个数据的反序列化。
上图中简单列了下,关于光大大数据团队选择的 schema 组件所支持的几种兼容类型。大家也可到网上具体看一看,由于图中描述的文字较多,便不再展开逐一讲。综上所述,可了解到怎么用schema演化的兼容性机制,来实现订阅。
(三)提供SDK,封装接口
原有平台接入方式复杂,应用开发门槛高,而应用多样的接入方式又推高了平台的维护成本。通过 SDK 封装实现低成本接入,平台界面与内部组件界面相分离,提升架构灵活性。
接下来,还需侧重阐述前文提到的 SDK 封装,这也是基于现有平台的问题,所对应给出的一些解决方案。
最开始最直接的一种方式,实质是希望屏蔽原生组件的变化。再者提供 SDK 以后,把整个平台的一些复杂性可以封装在其中。其实结合上图延展开来,可以看到 SDK 对于 schema 这部分复杂性的封装能够做到什么样子。
这张图与上图(暂放此处,便于查看),稍微有些变化。
其变化的核心是将 schema 的管理机制,以及基于 schema 的使用都封在了平台内。光大将整个 schema 的注册集中地放到平台来做,也就是说从具体的操作层面可以去这样解释。
整个的复杂性通过SDK,完全封闭在了平台体系里。既做 schema 的统一的管控,也做 schema 在数据读取过程中间的使用,对于消费者来讲,它其实做到了一个最简化。这是我认为 SDK 对于复杂性屏蔽所带来的典型的一个优点。
前文讲的 SDK 也好, schema 也好,都是围绕光大实时流数据平台的设计理念,做的更具化的一些设计和技术上的一些选择。
(四)剥离资源平台属性
前文其实还提到过“实时数据湖”这一概念,此处也用一页PPT稍作阐述。
当然,实时数据湖其实是近一两年非常热门的一个话题,互联网公司可能也有很多应用。包括光大,现在我们也已经开始建设,我认为有些典型的差异,可结合下图所示内容进一步浏览。
整体来讲,光大把实时数据湖作为一个微批的面向数据集合的操作,想降低原来在准实时上面所承担的一些场景,然后让它回归到流本身。至此,本文中就一些关键点的阐述便接近尾声了。
方案的成功与总结
总结下纯消息队列管理实时流数据存在的问题:
光大原来的平台叫准实时数据平台,本身是一个纯消息管理、消息队列管理为内核去完成的方案。其方案中存在一些典型的问题:以消息为主,所以它的数据管理能力不足。
第二是数据结构在上下游的应用上面,有非常紧密的耦合。一旦上游有变动,下游都要跟随变动。而上游的,其实完全是出于其设计目标,因此整个变动是一个不可控的。
第三是原生接口的变动,也会波及到所有的应用,因此缺乏一个中间可弹性控制的空间。
第四个是微批操作不够友好。因为 Kafka 特定的存储结构,造成它在某些场景下其实主要是读了,而读的性能比较差。
第五个是由于采用了一些方案去解决数据管理能力,带来了整个数据平台和资源平台同时具有两个属性,这种叠加造成了对于系统定位上的一些拉扯。
相应地,我们的解决思路,其实主要有三点:
通过 schema 库的方式来实现真正的数据的管理,而不是消息的管理。从而也能实现平台真正变成数据属主,因为在原有的模式下,它更多的像是一个通路,或者说当上游有些变更、有些问题之时,没有很强的控制力 就把这些因为变更和问题推到下游去。然而当通过 schema 强化了它的数据管理以后,平台则真正变成了属主,可以控制这些问题。
通过 SDK 来屏蔽这种复杂性和原生接口的变化。
把微批操作转移到数据湖的方案里面去搞定。