实时数仓之 Kappa 架构与 Lambda 架构(建议收藏!)
Posted 大数据羊说
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实时数仓之 Kappa 架构与 Lambda 架构(建议收藏!)相关的知识,希望对你有一定的参考价值。
数据仓库是一个
面向主题的
(Subject Oriented)、集成的
(Integrate)、相对稳定的
(Non-Volatile)、反映历史变化
(Time Variant)的数据集合,用于支持管理决策。数据仓库概念是 Inmon 于 1990 年提出并给出了完整的建设方法。随着互联网时代来临,数据量暴增,开始使用 大数据工具 来替代经典数仓中的传统工具。此时仅仅是工具的取代,架构上并没有根本的区别,可以把这个架构叫做离线大数据架构
后来随着业务实时性要求的不断提高,人们开始在 离线大数据架构 基础上加了一个加速层,使用流处理技术直接完成那些实时性要求较高的指标计算,这便是 Lambda 架构。
再后来,实时的业务越来越多,事件化的数据源也越来越多,实时处理从次要部分变成了主要部分,架构也做了相应调整,出现了以实时事件处理为核心的 Kappa 架构。
数据源通过离线的方式导入到离线数仓中。下游应用根据业务需求选择直接读取 DM 或加一层数据服务,比如 mysql 或 Redis。数据仓库从模型层面分为三层:
ODS,操作数据层,保存原始数据;
DWD,数据仓库明细层,根据主题定义好事实与维度表,保存最细粒度的事实数据;
DM,数据集市/轻度汇总层,在 DWD 层的基础之上根据不同的业务需求做轻度汇总;
如果要细分,分为五层:
ODS 层
ODS 层
: Operation Data Store,数据准备区,贴源层。直接接入源数据的:业务库、埋点日志、消息队列等。ODS 层数数据仓库的准备区DW数仓
DWD 层
:Data Warehouse Details,数据明细层,属于业务层和数据仓库层的隔离层,把持和 ODS 层相同颗粒度。进行数据清洗和规范化操作,去空值/脏数据、离群值等。
DWM 层
:Data Warehouse middle,数据中间层,在 DWD 的基础上进行轻微的聚合操作,算出相应的统计指标
DWS 层
:Data warehouse service,数据服务层,在 DWM 的基础上,整合汇总一个主题的数据服务层。汇总结果一般为宽表,用于 OLAP、数据分发等。ADS层
ADS 层
:Application data service, 数据应用层,存放在 ES,Redis、PostgreSql 等系统中,供数据分析和挖掘使用。典型的数仓存储是 HDFS/Hive,ETL 可以是 MapReduce 脚本或 HiveSQL。
数仓分层的优点:
划清层次结构:每一个数据分层都有它的作用域,这样我们在使用表的时候能更方便地定位和理解。 数据血缘追踪:简单来讲可以这样理解,我们最终给下游是直接能使用的业务表,但是它的来源有很多,如果有一张来源表出问题了,我们希望能够快速准确地定位到问题,并清楚它的危害范围。 减少重复开发:规范数据分层,开发一些通用的中间层数据,能够减少极大的重复计算。 把复杂问题简单化。将一个复杂的任务分解成多个步骤来完成,每一层只处理单一的步骤,比较简单和容易理解。而且便于维护数据的准确性,当数据出现问题之后,可以不用修复所有的数据,只需要从有问题的步骤开始修复。 屏蔽原始数据的异常。屏蔽业务的影响,不必改一次业务就需要重新接入数据。 随着大数据应用的发展,人们逐渐对系统的实时性提出了要求,为了计算一些实时指标,就在原来离线数仓的基础上增加了一个实时计算的链路,并对数据源做流式改造(即把数据发送到消息队列),实时计算去订阅消息队列,直接完成指标增量的计算,推送到下游的数据服务中去,由数据服务层完成离线&实时结果的合并。
Lambda 架构(Lambda Architecture)是由 Twitter 工程师南森·马茨(Nathan Marz)提出的大数据处理架构。这一架构的提出基于马茨在 BackType 和 Twitter 上的分布式数据处理系统的经验。
Lambda 架构使开发人员能够构建大规模分布式数据处理系统。它具有很好的灵活性和可扩展性,也对硬件故障和人为失误有很好的容错性。
Lambda 架构总共由三层系统组成:
批处理层(Batch Layer)
,速度处理层(Speed Layer
),以及用于响应查询的服务层(Serving Layer)
。在 Lambda 架构中,每层都有自己所肩负的任务。
批处理层 存储管理主数据集(不可变的数据集)和预先批处理计算好的视图。
批处理层 使用可处理大量数据的分布式处理系统预先计算结果。它通过处理所有的已有历史数据来实现数据的准确性。这意味着它是基于完整的数据集来重新计算的,能够修复任何错误,然后更新现有的数据视图。输出通常存储在只读数据库中,更新则完全取代现有的预先计算好的视图。
速度处理层 会实时处理新来的大数据。
速度层 通过提供最新数据的实时视图来最小化延迟。速度层所生成的数据视图可能不如批处理层最终生成的视图那样准确或完整,但它们几乎在收到数据后立即可用。而当同样的数据在批处理层处理完成后,在速度层的数据就可以被替代掉了。
Lambda 架构问题:
虽然 Lambda 架构使用起来十分灵活,并且可以适用于很多的应用场景,但在实际应用的时候,Lambda 架构也存在着一些不足,主要表现在它的维护很复杂。
(1)同样的需求需要开发两套一样的代码:这是 Lambda 架构最大的问题,两套代码不仅仅意味着开发困难(同样的需求,一个在批处理引擎上实现,一个在流处理引擎上实现,还要分别构造数据测试保证两者结果一致),后期维护更加困难,比如需求变更后需要分别更改两套代码,独立测试结果,且两个作业需要同步上线。
(2)资源占用增多:同样的逻辑计算两次,整体资源占用会增多(多出实时计算这部分)
Lambda 架构虽然满足了实时的需求,但带来了更多的开发与运维工作,其架构背景是流处理引擎还不完善,流处理的结果只作为临时的、近似的值提供参考。后来随着 Flink 等流处理引擎的出现,流处理技术很成熟了,这时为了解决两套代码的问题,LickedIn 的 Jay Kreps 提出了 Kappa 架构。
Kappa 架构可以认为是 Lambda 架构的简化版(只要移除 lambda 架构中的批处理部分即可)。
在 Kappa 架构中,需求修改或历史数据重新处理都通过上游重放完成。
Kappa 架构最大的问题是流式重新处理历史的吞吐能力会低于批处理,但这个可以通过增加计算资源来弥补。
Kappa 架构的重新处理过程:
重新处理是人们对 Kappa 架构最担心的点,但实际上并不复杂:
(1)选择一个具有重放功能的、能够保存历史数据并支持多消费者的消息队列,根据需求设置历史数据保存的时长,比如 Kafka,可以保存全部历史数据。
(2)当某个或某些指标有重新处理的需求时,按照新逻辑写一个新作业,然后从上游消息队列的最开始重新消费,把结果写到一个新的下游表中。
(3)当新作业赶上进度后,应用切换数据源,读取 2 中产生的新结果表。
(4)停止老的作业,删除老的结果表。
如下图所示:
在真实的场景中,很多时候并不是完全规范的 Lambda
架构或Kappa
架构,可以是两者的混合
,比如大部分实时指标使用Kappa
架构完成计算,少量关键指标(比如金额相关)使用Lambda
架构用批处理重新计算,增加一次校对过程。
Kappa
架构并不是中间结果完全不落地,现在很多大数据系统都需要支持机器学习(离线训练),所以实时中间结果需要落地对应的存储引擎供机器学习使用
,另外有时候还需要对明细数据查询,这种场景也需要把实时明细层写出到对应的引擎中。End
实时数仓方案如何选型和构建
目录
- 一、为何需要实时数仓架构
- 二、数仓如何分层 & 各层用途
- 三、数仓分层的必要性
- 四、从Lambda架构说起
- 五、Kappa架构解决哪些问题
- 六、深入实时数仓架构
- 七、具体选型建议
- 八、大厂方案分享
- 九、结语 & 延申思考
- 延申思考
导读:随着数字化进程的推进,企业产生的数据越来越多,与此同时企业对数据的需求也变得越来越复杂多样。
如何解决大规模复杂数据的存储和计算,已经成为很多企业必须面对的问题?这值得我们深思。
一、为何需要实时数仓架构
最初企业存储数据都在数仓中存储,但是随着数据量的增大,传统数据的方案在时效性上和数据维护上变得越来越困难。实时数仓架构应运而生。
然而问题并不是这么简单,在具体方案落地上实时数仓有很多方案可以选择,那么面对不同的业务和应用场景我们到底应该选择哪种技术方案呢?这是困扰好多大数据架构师的问题。
本文就针对该问题梳理了市场上常见的实时数仓方案和对应的应用场景。以便大家在选择或者使用实时数仓架构时能够有的放矢。
当然,在职业规划中,对应于想要成为大架构师的你而言,通过本文阅读你将会让你了解大数据架构必须掌握的数仓知识。尤其在实时数仓各种方案对比上会让你对数仓的理解更上一层楼。
另外,即便你不是大数据方面的研发人员,这一篇中处理数据的流程和思路,也一样会对你日常的工作有所帮助。
二、数仓如何分层 & 各层用途
在介绍实时数仓前,我们先回顾下离线数仓的分层架构,这将对我们后面理解实时数仓架构设计具有很大帮助。
数仓一般分为:ODS层、DWD层、DWS层和ADS层。这里我会分别展开说一下。这部分内容大家了解数仓中每层数据的特点即可,具体研发中同学们可以根据项目再做深入体会。
1)ODS层:ODS是数据接入层,所有进入数据的数据首先会接入ODS层。一般来说ODS层的数据是多复杂多样的。从数据粒度上看ODS层是粒度最细的数据层。
2)DWD层:为数据仓库层,数据明细层的数据应是经过ODS清洗,转后的一致的、准确的、干净的数据。DWD层数据粒度通常和ODS的粒度相同,不同的是该层的数据质量更高,字段更全面等。在数据明细层会保存BI系统中所有的历史数据,例如保存近10年来的数据。
3)DWS层:数据集市层,该层数据是面向主题来组织数据的,通常是星形或雪花结构的数据。从数据粒度来说,这层的数据是轻度汇总级的数据,已经不存在明细数据了。
4)ADS层:数据应用层,它是完全为了满足具体的分析需求而构建的数据,也是星形或雪花结构的数据。从数据粒度来说是高度汇总的数据。其汇总的目标主要是按照应用需求进行的。
三、数仓分层的必要性
那么数仓为什么要分层,数仓分层后有哪些好处呢?数仓分层是一个比较麻烦且耗费工作成本的一个事情,只有理解了数仓分层到底有哪些好处,我们才能理解数仓分层的必要性。
数仓分层的总体思路是用空间换时间,其目的是通过数仓分层,使得数仓能够更好地应对需求的变更,和提高数据的稳定性。
1)用空间换时间:通过大量的预处理来提升应用系统的用户体验(效率),因此数据仓库会存在大量冗余的数据。
2)能更好地应对需求的变更:如果不分层的话,如果源业务系统的业务规则发生变化,将会影响整个数据清洗过程,工作量巨大。
3)提高数据处理过程的稳定性:通过数据分层管理可以简化数据清洗的过程,因为把原来一步的工作分到了多个步骤去完成,相当于把一个复杂的工作拆成了多个简单的工作,每一层的处理逻辑都相对简单和容易理解。
这样我们比较容易保证每一个步骤的正确性,当数据发生错误的时候,往往我们只需要局部调整某个步骤即可。
前面介绍了数仓分层的一些基本理论,这将对我们后面理解实时数仓的各种架构打下一些理论知识基础。下面为大家梳理下市场上常见的实时数仓方案和对应的应用场景。
四、从Lambda架构说起
大部分实时数仓,其实是从Lambda架构演化而来的,因此在介绍实时数仓方案前我们先回顾下Lambda架构。
Lambda架构将数据分为实时数据和离线数据。
针对实时数据使用流式计算引擎进行计算(例如Flink),针对离线数据使用批量计算引擎(例如Spark)计算。然后分别将计算结果存储在不同的存储引擎上对外提供数据服务。
这种架构的优点是离线数据和实时数据各自计算,既能保障实时为业务提供服务,又能保障历史数据的快速分析。它分别结合了离线计算引擎与流式计算引擎二者的优势。
但是有一个缺点是离线数据和实时数据的一致性比较难保障,一般在离线数据产生后会使用离线数据清洗实时数据来保障数据的强一致性。
五、Kappa架构解决哪些问题
接下来要讲的这种架构,它是基于Lambda架构上的优化版本,Kappa架构。这种架构将数据源的数据全部转换为流式数据,并将计算统一到流式计算引擎上。
这种方式的特点使架构变得更加简单,但是不足之处是需要保障数据都是实时的数据,如果数据是离线的话也需要转化为流式数据的架构进行数据处理,具体架构可结合这张图来看。
六、深入实时数仓架构
实时数仓的查询需求
在正式讨论实时数仓前,我们先看下行业对实时数仓的主要需求,这有助于我们理解实时数仓各种方案设计的初衷,了解它是基于哪些需求应运而生的。
这也将帮助我们从更多维度上思考需求、条件、落地难点等等一些关键要素之间如何评估和权衡,最终实现是基于现有条件下的功能如何将其价值最大化。
传统意义上我们通常将数据处理分为离线的和实时的。对于实时处理场景,我们一般又可以分为两类:
一类诸如监控报警类、大屏展示类场景要求秒级甚至毫秒级;另一类诸如大部分实时报表的需求通常没有非常高的时效性要求,一般分钟级别,比如10分钟甚至30分钟以内都可接受。
基于以上查询需求,业界常见的实时数仓方案有这几种。
目前老的项目大部分还在使用的标准分层体现+流计算+批量计算的方案。未来大家可能都会迁移到标准分层体系+流计算+数据湖,和基于全场景MPP数据库实现的方案上,我也会重点介绍这两个方案,也希望大家能够多花点时间加以理解。
方案 1:Kappa 架构
首先咱们看下Kappa架构,Kappa架构将多源数据(用户日志,系统日志,BinLog日志)实时地发送到Kafka。
然后通过Flink集群,按照不同的业务构建不同的流式计算任务,对数据进行数据分析和处理,并将计算结果输出到MySQL/ElasticSearch/HBase/Druid/KUDU等对应的数据源中,最终提供应用进行数据查询或者多维分析。
这种方案的好处有二,方案简单;数据实时。不过有两个缺点:
一个是用户每产生一个新的报表需求,都需要开发一个Flink流式计算任务,数据开发的人力成本和时间成本都较高。
第二个是对于每天需要接入近百亿的数据平台,如果要分析近一个月的数据,则需要的Flink集群规模要求很大,且需要将很多计算的中间数据存储在内存中以便多流Join。
方案 2:基于标准分层 + 流计算
为了解决方案1中将所有数据放在一个层出现的开发维护成本高等问题,于是出现了基于标准分层+流计算的方案。
接下来咱们看下这种方案,在传统数仓的分层标准上构建实时数仓,将数据分为ODS、DWD、DWS、ADS层。首先将各种来源的数据接入ODS贴源数据层,再对ODS层的数据使用Flink的实时计算进行过滤、清洗、转化、关联等操作,形成针对不同业务主题的DWD数据明细层,并将数据发送到Kafka集群。
之后在DWD基础上,再使用Flink实时计算进行轻度的汇总操作,形成一定程度上方便查询的DWS轻度汇总层。最后再面向业务需求,在DWS层基础上进一步对数据进行组织进入ADS数据应用层,业务在数据应用层的基础上支持用户画像、用户报表等业务场景。
这种方案的优点是:各层数据职责清晰。缺点是多个Flink集群维护起来复杂,并且过多的数据驻留在Flink集群内也会增大集群的负载,不支持upset操作,同时Schema维护麻烦。
方案 3:标准分层体现+流计算+批量计算
为了解决方案2不支持upset和schema维护复杂等问题。我们在方案2的基础上加入基于HDFS加Spark离线的方案。也就是离线数仓和实时数仓并行流转的方案。
这种方案带来的优点是:既支持实时的OLAP查询,也支持离线的大规模数据分析。但是带来了问题这样的几个问题。
数据质量管理复杂:需要构建一套兼容离线数据和实时数据血缘关系的数据管理体系,本身就是一个复杂的工程问题。离线数据和实时数据Schema统一困难。架构不支持upset。
方案 4:标准分层体系+流计算+数据湖
随着技术的发展,为了解决数据质量管理和upset 问题。出现了流批一体架构,这种架构基于数据湖三剑客 Delta Lake / Hudi / Iceberg 实现 + Spark 实现。
我们以Iceberg为例介绍下这种方案的架构,从下图可以看到这方案和前面的方案2很相似,只是在数据存储层将Kafka换为了Iceberg。
它有这样的几个特点,其中第2、3点,尤为重要,需要特别关注下,这也是这个方案和其他方案的重要差别。
01.在编程上将流计算和批计算统一到同一个SQL引擎上,基于同一个Flink SQL既可以进行流计算,也可以进行批计算。
02.将流计算和批计算的存储进行了统一,也就是统一到Iceberg/HDFS上,这样数据的血缘关系的和数据质量体系的建立也变得简单了。
03.由于存储层统一,数据的Schema也自然统一起来了,这样相对流批单独两条计算逻辑来说,处理逻辑和元数据管理的逻辑都得到了统一。
04.数据中间的各层(ODS、DWD、DWS、ADS)数据,都支持OLAP的实时查询。
那么为什么 Iceberg 能承担起实时数仓的方案呢,主要原因是它解决了长久以来流批统一时的这些难题:
1.同时支持流式写入和增量拉取。
2.解决小文件多的问题。数据湖实现了相关合并小文件的接口,Spark / Flink上层引擎可以周期性地调用接口进行小文件合并。
3.支持批量以及流式的 Upsert(Delete) 功能。批量Upsert / Delete功能主要用于离线数据修正。流式upsert场景前面介绍了,主要是流处理场景下经过窗口时间聚合之后有延迟数据到来的话会有更新的需求。这类需求是需要一个可以支持更新的存储系统的,而离线数仓做更新的话需要全量数据覆盖,这也是离线数仓做不到实时的关键原因之一,数据湖是需要解决掉这个问题的。
4.同时 Iceberg 还支持比较完整的OLAP生态。比如支持Hive / Spark / Presto / Impala 等 OLAP 查询引擎,提供高效的多维聚合查询性能。
Iceberg 实战
上面介绍了基于Iceberg的标准分层体系+流计算+数据湖的架构,下面咱们从实战角度看下Iceberg如何使用。
iceberg写入流式数据代码实现如下:
data.writeStream.format("iceberg")
.outputMode("append")
.trigger(Trigger.ProcessingTime(1, TimeUnit.MINUTES)).option("data_path", tableIdentifier)
.option("checkpointLocation", checkpointPath)
.start()
上述代码会将data_path下的数据以流的形式,实时加入到系统中进行计算。
iceberg数据过滤代码实现如下:
Table table = ... Actions.forTable(table).rewriteDataFiles() .filter(Expressions.equal("date", "2022-03-18"))
.targetSizeInBytes(500 * 1024 * 1024) // 500 MB
.execute();
上述代码过滤出date为2022-03-18的数据。
方案 5:基于全场景MPP数据库实现
前面的四种方案,是基于数仓方案的优化。方案仍然属于比较复杂的,如果我能提供一个数据库既能满足海量数据的存储,也能实现快速分析,那岂不是很方便。这时候便出现了以StartRocks和ClickHouse为代表的全场景MPP数据库。
1.基于Darios或者ClickHouse构建实时数仓。来看下具体的实现方式:将数据源上的实时数据直接写入消费服务。
2.对于数据源为离线文件的情况有两种处理方式,一种是将文件转为流式数据写入Kafka,另外一种情况是直接将文件通过SQL导入ClickHouse集群。
3.ClickHouse接入Kafka消息并将数据写入对应的原始表,基于原始表可以构建物化视图、Project等实现数据聚合和统计分析。
4.应用服务基于ClickHouse数据对外提供BI、统计报表、告警规则等服务。
七、具体选型建议
对于这5种方案,在具体选型中,我们要根据具体业务需求、团队规模等进行技术方案选型。
说到这儿,我有这样的几点具体建议,希望或多或少可以给你提供一些可供参考、借鉴的新视角或者新思路。
(1)对于业务简单,且以流式数据为主数据流的大数据架构可以采用Kappa架构。
(2)如果业务以流计算为主,对数据分层,数据权限,多主题数据要求比较高,建议使用方案2的基于标准分层+流计算。
(3)如果业务的流数据是批数据都比较多,且流数据和批数据直接的关联性不大,建议使用方案3的标准分层体现+流计算+批量计算。这种情况下分别能发挥流式计算和批量计算各自的优势。
(4)方案4是一个比较完善的数仓方案,要支持更大规模的和复杂的应用场景,建议大数据研发人员在20以上的团队,可以重点考虑。
(5)对于大数据研发组团队为10人左右,要维护像方案2、3、4那样以ODS、DWD、DWS、ADS数据分层的方式进行实时数仓建设的话,就需要投入更多的资源。建议使用方案5一站式实现简单的实时数仓。
八、大厂方案分享
介绍了这么多实时数仓方案,那么很多小伙伴会问了,大厂到底用的那种方案呢?其实每个大厂根据自己业务特点的不同,也会选择不同的解决方案。下面为大家简要分享下OPPO、滴滴和比特大陆的方案,以便大家能够更好地理解这篇分享中五种架构的具体落地。
不过具体架构细节我不会进行过多的介绍,有了前面的内容基础,相信大家再通过架构图就能很快了解每个架构的特点。这里只是希望大家能够通过大厂的经验,明白他们架构设计的初衷和要解决的具体问题,同时也给我们的架构设计提供一些思路。
举例来说,OPPO的实时计算平台架构,其方案其实类似于方案2的基于标准分层+流计算。
滴滴的大数据平台架构是这样的,它的方案其实类似于方案2的基于标准分层+流计算。
再结合比特大陆的方案看下,其方案类型方案3的标准分层体现+流计算+批量计算,同时也引入了ClickHouse,可以看到比特大陆的数据方案是很复杂的。
九、结语 & 延申思考
本文介绍了市面上常见实时数仓方案,并对不同方案的优缺点进行了介绍。在使用过程中我们需要根据自己的业务场景选择合适的架构。
另外想说明的是实时数仓方案并不是“搬过来”,而是根据业务“演化来”的,具体设计的时候需要根据自身业务情况,找到最适合自己当下的实时数仓架构。
延申思考
我们在实时数仓的构建过程中比较大的争议是采用标准分层体系+流计算+数据湖的方案,还是试用基于全场景MPP数据库实现。
在讨论过程中大家比较大的分歧是基于全场景MPP数据库实现到底算是一个数仓方案不,毕竟该方案没有标准的数仓分层的思想,而是围绕大规模数据统计的需求来实现的。
但是我的观点是:一切方案都需要以实际需求为出发点,我们的80%的需求就是在一个180多个字段的大宽表(每天80亿条,3TB数据量)上可以灵活的统计分析,快速为业务决策提供依据。因此我们选择了基于全场景MPP数据库方案。
新的技术层出不穷,对我们技术人来说尝鲜是很爽的一件事情,但是实际落地还是建议大家把需求收敛好后再做决策,保持冷静的思维,有时候适当地“让子弹飞一会”也是有好处的。
今天的分享到这里就结束了,期待留言区里的进一步交流,也可以把它分享给你的朋友。我们后续再会。
以上是关于实时数仓之 Kappa 架构与 Lambda 架构(建议收藏!)的主要内容,如果未能解决你的问题,请参考以下文章