流批一体是一种架构思想,这种思想说的是同一个业务,使用同一个sql逻辑,在既可以满足流处理计算同时也可以满足批处理任务的计算。
从效率层面来说,批处理只能以t+1的形式呈现业务数据,流处理只能以t+0的形式呈现业务数据,当二者独立时企业需要运行两套代码,开发、运维、人力成本高,呈现周期长。而流批一体则使用一套代码呈现两套业务数据,开发、运维成本降低一半,实效性显著提升。
那么,什么又是流批一体数据仓库呢?简单点说,它是将异构源的数据使用同一套计算引擎并结合数据仓库理论所特有的资料存储架构完成实时、离线分析业务的数据集合。
该数据集合具以下特点:
面向主题:数据仓库按照一定主题域组织数据;
易于集成:消除源数据中的不一致性,保证企业全局信息的一致性;
相对稳定:集合中数据长期保留,只需定期加载、刷新;
预测趋势:数据中存放历史信息,可对企业发展历程和未来趋势做出定量分析和预测。
随着客户体量增大,客户需求逐步增加,面对PB级别的批数据和流数据的处理需求,数栈技术团队面临越来越多的挑战,在这个过程中逐步完善了数栈数仓架构体系。从2017年的基于传统架构的批处理经过4年迭代到基于混合架构的流批一体数仓,如图:
数栈流批一体架构混合数仓演进过程示意图
1. 基于传统架构的批处理
互联网诞生之初虽然数据量暴增,单日事实表条数达千万级别,但客户需求场景更多是“t+1”形式,只需对当日、当周、当月数据进行分析,这些诉求仅离线分析就可满足。
恰逢hadoop生态刚刚兴起之时,数栈技术团队基于数据暴增存储紧张的困境搭载Hadoop生态链,将数据周期性导入HDFS,利用Hadoop平台Hive做数据仓库就可实现对HDFS上的海量数据集进行离线分析。
这一阶段其实与互联网本质架构没有过多变化,仍是将数据周期性装载然后分析,只是使用的技术由经典的数仓工具转型到了大数据工具。
2. 基于Lambda架构的流批独立
随着网络、通信技术发展,“隔日达”的数据已不能满足客户的需求场景,他们更期待实时数据呈现,这样无论是在金融、证券交易还是零售、港口的实时监控预警等场景下,决策者都可以第一时间做出有利判断,提升效率减少损失。
为应对这种变化,数栈技术团队结合当时主流大数据处理技术,在原有的HIVE数仓上,增加了当时最先进的流批一体计算引擎Spark来加快离线计算性能。同时在原有的离线大数据架构上,增加了一条基于Kafka存储以及Flink计算引擎的流处理链路用于完成实时性要求较高的指标计算。
虽然使用Spark和Flink计算引擎满足了客户对于实时数据的场景呈现,但由于Spark虽然理念上是流批一体但本质上还是基于批来实现流,在实效上仍存在一定的硬伤。而同期的Flink计算引擎并不完善,数栈技术团队于是对Flink功能进行了一定的扩展。
在此过程中同步孵化出了可以完成更多数据源同步的FlinkX和可以通过Sql对更多的数据源进行实时计算并写入的FlinkStreamSql。(取之开源,馈之开源。数栈技术团队已将它们分享到了Github上,有需要的同学可以点原读原文查看。)
这一阶段数栈技术团队通过自研的FlinkX和FlinkStreamSql,在原有的离线链路上新增了流计算链路用于实时数据分析,完成了从传统大数据架构到Lambda架构的转变。
Lambda架构的核心思想是将业务进行拆分,实时性要求高的业务走实时计算方案,实时性要求低的业务走离线计算方案,最后由数据服务层对全部数据进行分析汇总供下游使用。
Lambda架构流批独立处理流程图
3. 基于Kappa架构的实时处理
Lambda架构的搭载基本满足了客户对于实时数据的诉求,大量客户通过数栈DTinsight实现数据赋能生产任务的需求,在每日数以万计的数据量下,数栈DTinsight也能保持稳定的运行,为客户在数据驱动业务上提供了强有力的后盾。
虽然Lambda架构满足了客户在业务上对于实时性的需求,但随着企业发展业务量也在逐步增加,导致开发与运维成本逐步增加。此时Flink流处理技术也逐步成熟,Flink Exactly-Once和状态计算已完全可以保证计算最终结果的准确性,因此数栈技术团队开始关注在Lambda架构的基础上如何做出调整。
LinkedIn的前首席工程师杰伊·克雷普斯(Jay Kreps)曾针对Lambda架构提出过一个改进观点:改进Lambda架构中的Speed Layer,使它既能够进行实时数据处理,同时也有能力在业务逻辑更新的情况下重新处理以前处理过的历史数据。
受到Kreps的启发,数栈团队推荐实时业务较多的客户将Kafka的数据日志保留日期,当流任务发生了代码变动或者需要对上游进行回溯计算时,只需要保持原来的Job N不动,然后再启动一个作业Job N+1,指定历史数据的offset进行计算并写入到一张新的N+1表中,当Job N+1的计算进度赶上Job的进度后,可以将原来的Job N任务替换成Job N+1,下游的业务程序只需要根据Job N+1生成的表进行分析或者展示。这样就可以将离线链路层去掉,减少客户额外开发及维护代码的工作量,同时统一了业务的计算口径。
Lambda架构的的缺点在于需要维护两个复杂的分布式系统中产生相同结果的代码,而通过增加并行度以及重播历史数据的方式去重新处理实时数据可以有效的代替离线数据处理系统。这样架构既简单也避免了维护两套系统代码还需要保持结果一致的问题。
Kappa架构实时数仓流程图
4. 基于Kappa+Lambda混合架构的流批一体数仓
通过Lambda架构和Kappa架构,数栈可以解决大部分企业面临的实时场景和开发运维需求,但也有些企业对于实时业务需求较高就会发生因极端数据乱序导致实时计算数据不准确,那么这个时候流任务就面临着数据质量上的问题。
针对于这种情况数栈技术团队结合Kappa架构和Lambda架构的优势,通过Labmda架构中离线链路对实时链路产出数据周期性校订,同时结合FlinkX内核支持流批一体的特性,在计算层基于FlinkX计算引擎来统一完成整个链路中计算任务,以此来保证数据的最终一致性。
FlinkX是一款基于Flink的流批统一的数据同步以及SQL计算工具。既可以采集静态的数据,比如MySQL,HDFS中的业务数据,也可以采集实时变化的数据,比如MySQL、 Binlog、Kafka等。在FlinkX1.12中,也会将FlinkStreamSql融合其中,使得FlinkX1.12既能通过同步任务采集静态、动态的数据,又能通过SQL任务对采集后的数据根据业务时效性进行流批处理。
在数栈中,FlinkX的流批一体的实现是体现在数据采集层以及数据计算层。
1. 数据采集层
从数据的时态来讲,可以将数据分为实时数据和离线数据。比如像Kafka、EMQ这类高吞吐量的消息中间件它们通常持有的是源源不断的数据,所以可以通过FlinkX的实时采集任务对数据进行实时的落库,以便后续的任务进行近实时、准实时的业务计算。像Mysql、Oracle这类OLTP数据库通常是持有的历史的事务数据,这类数据都是以天、月为时间单位进行存储与计算,因此可以通过FlinkX的离线同步任务将这类数据间隔性增量或者全量同步到我们的OLAP数仓或者数据湖中,然后根据各类业务指标对数据进行分层以及跑批分析。
另外,除了将数据采集到存储层,还会根据数据治理中定义的数据规范并结合数仓规范,通过FlinkX的同步任务完成对数据的清洗、转换以及维度补全,以此提高数据的有效性以及业务计算的准确性。
2. 数据计算层
当数据被采集到指定的存储层后,会结合存储类型以及业务时效性对数据进行常规的业务计算。FlinkX Sql能支持流批计算的能力来源于Flink内核在1.12版本中对元数据的统一管理以及在DataStream API上支持批执行模式,这样增强了作业的可复用性和可维护性,使得FlinkX 作业可以在流和批两种执行模式之间自由进行切换并只需要维护一套代码,无需重新写任何代码。而且,相比于开源的Flink,FlinkX 1.12 不仅提供了更多的Source以及Sink来支持对各类数据源的实时以及离线计算还实现了脏数据管理插件,让客户在ETL阶段针对错误不合规的数据能够由感知以及容错处理能力。
FlinkX在数栈中实现流批一体流程图
3. 数栈流批一体在数仓上的实践
下面结合架构图场景讲述下数栈流批一体的做法。
场景:股票交易中K线有分时图、日线图、周线图等之分,用户股票交易完成后需要在K线上显示买卖点和成交金额。
数栈未实现流批一体处理方式:
对于上面这个场景数栈未实现流批一体前的做法是分时图的买卖点会采用Flink计算,日K、周K等的买卖点通过配置周期Spark任务进行计算,即经典的Lambda架构,这种架构的痛点是比较明显的,维护两套代码开发效率低、两套计算引擎成本高、数据口径不一致。
数栈实现流批一体后处理方式:
在数栈平台先选择创建实时采集和数据同步任务将业务库数据采集到Kafka和Iceberg,即数仓的ODS层。实时数仓和离线数仓从ODS到DWD层数据清洗和数据打宽的处理逻辑是一样的,表定义结构也是保持一致的,所以这一步只需要实现一套Flink SQL数栈平台会自动翻译成Flink Stream和Flink Batch任务即可用于实时数仓又可以用于离线数仓。实时数仓和离线数仓DWS层分别存放分时图买卖点信息和日K、周K等数据,两边处理逻辑不同所以在这一层需要根据业务开发两套SQL, Stream Flink SQL对接实时数仓DWD层数据实时计算分时图买卖点,Batch Flink SQL对接离线数仓DWD层数据周期调度计算日K、周K等买卖点数据。应用层服务直接从DWS层获取买卖点数据进行展示。
通过实例我们可以看到数栈选择了Iceberg作为流批一体的存储层,原因如下:
1. Iceberg存储的是原始数据,数据结构可以多样化;
2. Iceberg支持多种计算模型,是一个通用化设计的Table Format,完美地解耦了计算引擎和底下的存储系统;
3. Iceberg底层存储支持灵活,一般用 S3、OSS、HDFS 这种廉价的分布式文件系统,采用特定的文件格式和缓存就可以对应场景的数据分析需求;
4. Iceberg项目背后的社区资源非常丰富,在国内外已经有不少大公司将海量的数据跑在Iceberg上;
5. Iceberg保存全量数据,当流计算任务有重跑历史数据的需求时可从Iceberg读取数据然后无缝切换到Kafka即可。
随着大数据领域不断发展,企业对于业务场景的诉求从离线的满足到高实时性的要求,数栈产品也在这一过程中进行着不断的迭代升级,为企业在提升数据计算结果质量,提升企业业务研发效率,降低企业维护成本上提供了有力帮助。
1. 提升数据计算结果质量
高质量、高准确度的数据有利于企业做优秀的决策,数栈基于混合架构的流批一体数仓将计算引擎进行了统一,解决了不同引擎两套代码之间的SQL逻辑不能复用问题,让数据在一致性和质量上得到了保障。
2. 提升企业业务研发效率
从业务开发到上线,业务开发人员只需要针对业务开发一套SQL任务,随后根据业务延时标准在流批计算之间进行灵活切换即可。应用端开发人员也只需要针对业务拼接一套SQL封装逻辑。
3. 提升企业资源利用率,降低维护成本
企业用户的实时、离线业务只需要运行在同一套计算引擎上即可。无需为运行实时、离线业务的不同计算引擎分别购置高配的硬件资源。而针对业务变更,开发人员也只需要修改对应的SQL任务,无需考虑实时、离线任务分别修改。
虽然FlinkX SQL在一定程度提升了流批计算的能力,但批处理在实效上还有待提高,下一步数栈技术团队将从Flink源码层面去对算子以及Task进行一些优化,提高批处理层面计算效率降低企业时间成本。同时进一步统一数据源中元数据标准,让企业在数据治理过程中所涉及的数据字典、数据血缘、数据质量、权限管理等模块在后续使用层面可快速被响应,减少企业管理成本。
数栈流批一体架构,通过迭代已实现实时数仓+OLAP场景结合,只需一套代码就可进行多个计算处理模式,不仅满足了企业低延迟、高时效的业务驱动需求,同时也降低了企业开发、运维、人工成本。当然这只是流批一体探索的第一步,数栈技术团队将继续在数据存储层面进行深挖,将数据仓库的便捷管理、高质量数据特性与数据湖的可探索、高灵活性相融合,完成数栈在数据仓库到湖仓一体的转变,实现对未知数据先统一存储再灵活探索的能力,在数据架构层面更进一步。