从离线仓到实时仓的变革

时间:2023-01-17 18:07:54

实时数仓,并不是一个新概念,它是数据架构不断变化和演进的结果。如果一定要追溯实时数仓的发展历程,应该从OLTP和OLAP的分道扬镳开始。

数据仓库的发展史

数据仓库的概念是于 90 年代,由 Bill Inmon 提出。当时的背景是,传统的 OLTP 数据库无法很好的支持长周期分析决策场 景。所以,今天实时数据仓库概念与传统离线数仓有有哪些却别,我们要结合着 OLTP 数据库当时的状态来对比理解。

从离线仓到实时仓的变革

我们所常说的企业数据仓库Enterprise Data Warehouse (EDW) ,就是一个用于聚合不同来源的数据(比如事务系统、关系数据库和操作数据库),然后方便进行数据访问、分析和报告的系统(例如销售交易数据、移动应用数据和CRM数据),只要数据汇集到数仓中,整个企业都访问和使用,从而方便大家来全面的了解业务。我们的数据工程师和业务分析师可以将这些不同来源的相关数据应用于商业智能(BI)和人工智能(AI)等方面,以便带来更好的预测,并最终为我们作出更好的业务决策。

传统意义上的数据仓库主要处理T+1数据,即今天产生的数据分析结果明天才能看到,T+1的概念来源于股票交易,是一种股票交易制度,即当日买进的股票要到下一个交易日才能卖出。

随着互联网以及很多行业线上业务的快速发展,让数据体量以前所未有的速度增长,数据时效性在企业运营中的重要性日益凸现,企业对海量数据的处理有了更高要求,如非结构化数据处理、快速批处理、实时数据处理、全量数据挖掘等。由于传统数据仓库侧重结构化数据,建模路径较长,面对大规模数据处理能力有限,企业急需提升大数据处理时效,以更经济的方式发掘数据价值。

从离线仓到实时仓的变革

离线数仓分层

在了解数仓如何实时处理之前,我们先来了解数据的分层。每个企业根据自己的业务需求可以分成不同的层次,但是最基础的分层思想,理论上数据分为三个层:贴源层(ODS)、数据仓库层(DW)、数据服务层(APP/DWA)。基于这个基础分层之上满足不同的业务需求。

ODS:Operation Data Store,也称为贴源层。数据仓库源头系统的数据表通常会原封不动的存储一份,这称为ODS层,是后续数据仓库加工数据的来源。

DW数据分层,由下到上一般分为DWD,DWB,DWS。

DWD:Data Warehouse Details 细节数据层,是业务层与数据仓库的隔离层。主要对ODS数据层做一些数据清洗(去除空值、脏数据、超过极限范)和规范化的操作。

DWB:Data Warehouse Base 数据基础层,存储的是客观数据,一般用作中间层,可以认为是大量指标的数据层。

DWS:Data Warehouse Service 数据服务层,基于DWB上的基础数据,主要是对用户行为进行轻度聚合,整合汇总成分析某一个主题域的服务数据层,一般是宽表。用于提供后续的业务查询,OLAP分析,数据分发等。

数据服务层/应用层(APP/DWA):该层主要是提供数据产品和数据分析使用的数据,我们通过说的报表数据,或者说那种大宽表,一般就放在这里。

从离线仓到实时仓的变革离线大数据架构

离线数仓,其实简单点来说,就是原来的传统数仓,数据以T+1的形式计算好放在那里,给前台的各种分析应用提供算好的数据。到了大数据时代,这种模式被称为“大数据的批处理”。

Lambda与Kappa架构

当前,数据仓库被分为离线数仓和实时数仓,离线数仓一般是传统的T+1型数据ETL方案,而实时数仓一般是分钟级甚至是秒级ETL方案。并且,离线数仓和实时数仓的底层架构也不一样,离线数仓一般采用传统大数据架构模式搭建,而实时数仓则采用Lambda、Kappa等架构搭建。

从离线仓到实时仓的变革

Lambda架构由Storm的作者Nathan Marz提出。旨在设计出一个能满足。实时大数据系统关键特性的架构,具有高容错、低延时和可扩展等特。

Lambda架构整合离线计算和实时计算,融合不可变(Immutability,读写分离和隔离 一系列构原则,可集成Hadoop,Kafka,Storm,Spark,HBase等各类大数据组件。

Lambda架构的主要思想就是将大数据系统构建为多个层次,三层架构:批处理层、实时处理层、服务层 ,如下图

批处理层:批量处理数据,生成离线结果

实时处理层:实时处理在线数据,生成增量结果

服务层:结合离线、在线计算结果,推送上层

1批处理层

在Lambda架构中,实现batch view = function(all data)的部分被称之为 batch layer。它承担了两个职责:

存储Master Dataset,这是一个不变的持续增长的数据集

针对这个Master Dataset进行预运算

显然,Batch Layer执行的是批量处理,例如Hadoop或者Spark支持的Map-Reduce方式。 它的执行方式可以用一段伪代码来表示。

2实时处理层

只要batch layer完成对batch view的预计算,serving layer就会对其进行 更新。这意味着在运行预计算时进入的数据不会马上呈现到batch view中。这对于 要求完全实时的数据系统而言是不能接受的。要解决这个问题,就要通过speed layer。从对数据的处理来看,speed layer与batch layer非常相似,它们之间最大的 区别是前者只处理最近的数据,后者则要处理所有的数据。

3服务层

Batch Layer通过对master dataset执行查询获得了batch view,而 Serving Layer就要负责对batch view进行操作,从而为最终的实时查询提供支撑。因此Serving Layer的职责包含:

对batch view的随机访问

更新batch view Serving Layer应该是一个专用的分布式数据库,例如Elephant

DB,以支持对batch view的加载、随机读取以及更新。

注意,它并不支持对batch view的随机写,因为随机写会为数据库引来许多复杂 性。简单的特性才能使系统变得更健壮、可预测、易配置,也易于运维。

Lambda架构组件选型

数据流存储可选用基于不 可变日志的分布式消息系统Kafka;Batch Layer数据集的存储可选用Hadoop的 HDFS,或者是阿里云的ODPS;Batch View的预计算可以选用MapReduce或 Spark;Batch View自身结果数据的存储可使用MySQL(查询少量的最近结果数 据),或HBase(查询大量的历史结果数据)。Speed Layer增量数据的处理可选用 Storm或Spark Streaming;Realtime View增量结果数据集为了满足实时更新的效 率,可选用Redis等内存NoSQL

Lambda架构组件选型原则

Lambda架构是个通用框架,各个层选型时不要局限时上面给出的组件,特别是对于View的选型。从我对Lambda架构的实践来看,因为View是个和业务关联 性非常大的概念,View选择组件时关键是要根据业务的需求,来选择最适合查询的 组件。不同的View组件的选择要深入挖掘数据和计算自身的特点,从而选择出最适 合数据和计算自身特点的组件,同时不同的View可以选择不同的组件。

Lambda架构优缺点

优点:

实时:低延迟处理数据

可重计算:由于数据不可变,重新计算一样可以得到正确的结果

容错:第二点带来的,程序bug、系统问题等,可以重新计算

复杂性分离、读写分离

缺点:

开发和运维的复杂性:Lambda需要将所有的算法实现两次,一次是为批处理系统,另一次是为实时系统,还要求查询得到的是两个系统结果的合并

既然 Lambda 架构难保证数据一致性,双倍维护系统成本,那么一套系统解决批处理和流处理的诉求就产生了,对应的解决方案便是 Kappa 架构(即批流一体)。

Kappa 实现原理

Kappa 架构在 Lambda 架构的基础上移除了批处理层,利用流计算的分布式特征,加大流数据的时间窗口,统一批处理和流处理,处理后的数据可以直接给到业务层使用。因为在 Kappa 架构下,作业处理的是所有历史数据和当前数据,其产生的结果我们称之为实时批视图(Realtime_Batch_View)。

从离线仓到实时仓的变革

在 Kappa 架构中,输入数据在源端采集后通常存储在 Kafka 中,在流处理程序需要升级迭代时,会启动一个新版本作业(StreamJob_Version_N+1), 该作业会从 Kafka 中读取所有历史数据和新增数据,直到追上旧版本作业(StreamJob_Version_N),旧的作业版本才可以停掉。Kappa 架构通过这种方法升级流处理程序。

Kappa 架构的流处理系统通常使用 Spark Streaming 或者 Flink 等实现,服务层通常使用MySQL 或 HBase 等实现。

Kappa 优势与不足

优点:由于所有数据都通过流处理计算,开发人员只需要维护实时处理模块,不需要离线实时数据合并,运维简单,生产统一。

缺点:(1) 依赖 Kafka 等消息队列来保存所有历史,而 Kafka 难以实现数据的查询、更新和纠错,发生故障或者升级时需要重做所有历史,周期较长;(2) Kappa 主要是针对不可变更数据,无法实时汇集多个可变数据源形成的数据集快照,不适合即席查询。

Kappa 架构实际应用起来有较大的局限性,因此 Kappa 架构在业内生产落地的案例不多见,且场景比较单一。

湖仓一体能否解决实时问题?

时下热门的湖仓一体能否解决实时问题呢?湖仓一体有何标准?Gartner 认为湖仓一体是将数据湖的灵活性和数仓的易用性、规范性、高性能结合起来的融合架构,无数据孤岛。

作为数据湖和数据仓库的完美结合,新一代的湖仓一体架构重点关注和解决了近年来数字化转型带来的业务需求和技术难点,具体包括如下以下方面:

实时性成为了提升企业竞争力的核心手段。目前的湖、仓、或者湖仓分体都是基于 T+1 设计的,面对 T+0 的实时按需分析,用户的需求无法满足。

所有用户(BI 用户、数据科学家等)可以共享同一份数据,避免数据孤岛。

超高并发能力,支持数十万用户使用复杂分析查询并发访问同一份数据。

传统 Hadoop 在事务支持等方面的不足被大家诟病,在高速发展之后未能延续热度,持续引领数据管理,因此事务支持在湖仓一体架构中应得到改善和提升。

为释放数据价值提升企业智能化水平,数据科学家等用户角色必须通过多种类型数据进行全域数据挖掘,包括但不限于历史的、实时的、在线的、离线的、内部的、外部的、结构化的、非结构化数据。

云原生数据库实现完全的存算分离

云原生数据库已经逐渐成熟,基于存算分离技术,可以给用户带来多种价值:降低技术门槛、减少维护成本、提升用户体验、节省资源费用,已成为了湖仓一体落地的重要法门。

云原生数据库(如 Snowflake)突破了传统 MPP 和 Hadoop 的局限性,实现了存算完全分离,计算和存储可部署在不同物理集群,并通过虚拟计算集群技术实现了高并发,同时保障事务支持,成为湖仓一体实现的关键技术。

严格来说,无论是数据库,还是湖仓方案,都不是真正的实时数仓,但却满足了实时数仓需求。通过云原生数据库、数仓以及湖仓的方式,任意时间点的历史数据都可以通过 T+0 快照得到(为了节省存储,T+0 快照可以拉链形式存储在实时数仓 ODS 中,所以快照视图可以理解为实时拉链),这样离线查询可以在实时数仓中完成,离线查询结果可以包含最新的实时数据,完全不再需要通过传统MPP+Hadoop湖仓分体组合来处理离线跑批及分析查询。

所以,未来实时数仓的走向,更多是一种混合架构。

混合架构,如何破局?

我们可以使用混合架构,解决Lamdba在流的缺陷,Kappa在批的痛点,Kappa+在端到端的不足。

混合架构,综合Lamdba、Kappa和Kappa+的优势,使用Hudi或Iceberg作为批和流的统一存储层,并且提供端到端的流和批的一体化,使得既能保证流的实时性,又能具备批的稳健性。

我们来看如何实现。

1、统一数据采集层。

数据源:在数据源层面,分为日志类和业务类,使用一致的的采集方法。

使用Flink CDC统一采集,经Kafka传输到数据存储层。

这样不需要再维护Sqoop和另一套采集系统。

2、统一数据存储层。

可使用Hudi或Iceberg作为流批一体的统一存储层。

统一存储数仓的ODS、DWD、DWS、DWT、DM各层数据。

(1)存储原始数据,数据结构多样化。

(2)支持多种计算模型,解耦计算引擎和存储系统。

(3)支持灵活廉价的底层存储,可使用本地HDFS、或云上对象存储S3、OSS。

(4)支持事务ACID。

3、统一元数据层。

使用Flink Catalog统一元数据管理,例如数据库、表、分区、视图以及外部系统。

Catalog提供统一API,统一管理元数据,使其可从TableAPI和SQL查询语句中访问。

使用Flink Catalog解决了大数据引擎不同元数据格式造成的复杂问题,并且Catalog与Hive MetaStore兼容。

4、统一计算引擎层。

使用Flink Unified DataStream统一计算引擎层。

Flink Unified DataStream能更好支持流和批两种计算模式。

Unified DataStream统一和简化了以前流批要分别使用DataStream和Dataset的繁琐。

并且Unified DataStream针对Unbounded场景,在磁盘I/O访问,序列化和反序列化做了优化,使得Unbounded和Bounded的效率、可用性、易用性都得到很大提升。

5、统一SQL引擎层。

可使用Flink SQL或Presto/Trino。

Flink SQL将流处理和批处理统一,支持大部分标准SQL的语法和语义。

6、展示层。

结果视图需要支持低延迟的查询分析,通常需将数据结果存储到列存分析系统,可使用Clickhouse和Presto/Trino。

从实现上看,Lambda plus架构利用Flink流表的相互转化实现了同一计算逻辑只需一套代码即可在流处理与批处理两种模式下得到一致结果,而且通过Flink cdc、状态计算等特性实现了历史数据+增量流水的连续处理,比如系统启动时利用Flink cdc先装载历史数据,再通过监听binlog将数据变动流水接入Flink;或者利用Flink state&checkpoint特性从指定checkpoint恢复,以便在流水上接续计算,这样即可实现基于历史数据增量计算的目的。

总结:

整体来看,数仓架构经历了最初的传统数仓架构——离线数仓库——离线大数据架构、Lambda 架构、Kappa 架构以及 Flink 的火热带出的流批一体架构。随着数据架构技术不断演进,本质是在往流批一体的方向发展,让用户能以最自然、最小的成本完成实时计算。