[toc]html
版权声明:本文为Heriam博主原创文章,遵循CC 4.0 BY-SA 版权协议,转载请附上原文出处连接和本声明。算法
原文连接:https://jiang-hao.com/articles/2019/big-data-lambda-architecture.htmlsql
“咱们正在从IT时代走向DT时代(数据时代)。IT和DT之间,不只仅是技术的变革,更是思想意识的变革,IT主要是为自我服务,用来更好地自我控制和管理,DT则是激活生产力,让别人活得比你好”数据库
——阿里巴巴董事局主席马云。编程
数据量从M的级别到G的级别到如今T的级、P的级别。数据量的变化数据管理系统(DBMS)和数仓系统(DW)也在悄然的变化着。 传统应用的数据系统架构设计时,应用直接访问数据库系统。当用户访问量增长时,数据库没法支撑日益增加的用户请求的负载时,从而致使数据库服务器没法及时响应用户请求,出现超时的错误。出现这种状况之后,在系统架构上就采用下图的架构,在数据库和应用中间过一层缓冲隔离,缓解数据库的读写压力。服务器
然而,当用户访问量持续增长时,就须要考虑读写分离技术(Master-Slave)架构则以下图,分库分表技术。如今,架构变得愈来愈复杂了,增长队列、分区、复制等处理逻辑。应用程序须要了解数据库的schema,才能访问到正确的数据。网络
商业现实已经发生了变化,因此如今更快作出的决定更有价值。除此以外,技术也在不断发展。Kafka,Storm,Trident,Samza,Spark,Flink,Parquet,Avro,Cloud providers等都是工程师和企业普遍采用的流行语。所以,现代基于Hadoop的M/R管道(使用Kafka,Avro和数据仓库等现代二进制格式,即Amazon Redshift,用于临时查询)可能采用如下方式:架构
这看起来至关不错,但它仍然是一种传统的批处理方式,具备全部已知的缺点,主要缘由是客户端的数据在批处理花费大量时间完成以前的数据处理时,新的数据已经进入而致使数据过期。app
对低成本规模化的需求促令人们开始使用分布式文件系统,例如 HDFS和基于批量数据的计算系统(MapReduce 做业)。可是这种系统很难作到低延迟。用 Storm 开发的实时流处理技术能够帮助解决延迟性的问题,但并不完美。其中的一个缘由是,Storm 不支持 exactly-once 语义,所以不能保证状态数据的正确性,另外它也不支持基于事件时间的处理。有以上需求的用户不得不在本身的应用程序代码中加入这些功能。后来出现了一种混合分析的方法,它将上述两个方案结合起来,既保证低延迟,又保障正确性。这个方法被称做 Lambda 架构,它经过批量 MapReduce做业提供了虽有些延迟可是结果准确的计算,同时经过Storm将最新数据的计算结果初步展现出来。框架
Lambda架构是由Storm的做者Nathan Marz提出的一个实时大数据处理框架。Marz在Twitter工做期间开发了著名的实时大数据处理框架Storm,Lambda架构是其根据多年进行分布式大数据系统的经验总结提炼而成。Lambda架构的目标是设计出一个能知足实时大数据系统关键特性的架构,包括有:高容错、低延时和可扩展等。Lambda架构整合离线计算和实时计算,融合不可变性(Immunability),读写分离和复杂性隔离等一系列架构原则,可集成Hadoop,Kafka,Storm,Spark,Hbase等各种大数据组件。
Marz认为大数据系统应具备如下的关键特性:
Note:xpleaf我的认为Robust应该翻译为健壮性,而不是鲁棒性,由于鲁棒性从字面上理解很难明白是什么意思,但健壮性在计算机领域当中应该是一听就懂的。
为了设计出能知足前述的大数据关键特性的系统,咱们须要对数据系统有本质性的理解。咱们可将数据系统简化为:
数据系统 = 数据 + 查询
从而从数据和查询两方面来认识大数据系统的本质。
数据的特性: when & what
咱们先从“数据”的特性谈起。数据是一个不可分割的单位,数据有两个关键的性质:When和What。
数据的存储:Store Everything Rawly and Immutably
根据上述对数据本质特性的分析,Lamba架构中对数据的存储采用的方式是:数据不可变,存储全部数据。
经过采用不可变方式存储全部的数据,能够有以下好处:
当前业界有不少采用不可变数据模型来存储全部数据的例子。好比分布式数据库Datomic,基于不可变数据模型来存储数据,从而简化了设计。分布式消息中间件Kafka,基于Log日志,以追加append-only的方式来存储消息。
查询的本质
查询是个什么概念?Marz给查询以下一个简单的定义:
Query = Function(All Data)
该等式的含义是:查询是应用于数据集上的函数。该定义看似简单,却几乎囊括了数据库和数据系统的全部领域:RDBMS、索引、OLAP、OLTP、MapReduce、EFL、分布式文件系统、NoSQL等均可以用这个等式来表示。
让咱们进一步深刻看一下函数的特性,从而挖掘函数自身的特色来执行查询。 有一类称为Monoid特性的函数应用很是普遍。Monoid的概念来源于范畴学(Category Theory),其一个重要特性是知足结合律。如整数的加法就知足Monoid特性:
(a+b)+c=a+(b+c)
不知足Monoid特性的函数不少时候能够转化成多个知足Monoid特性的函数的运算。如多个数的平均值Avg函数,多个平均值无法直接经过结合来获得最终的平均值,可是能够拆成分母除以分子,分母和分子都是整数的加法,从而知足Monoid特性。
Monoid的结合律特性在分布式计算中极其重要,知足Monoid特性意味着咱们能够将计算分解到多台机器并行运算,而后再结合各自的部分运算结果获得最终结果。同时也意味着部分运算结果能够储存下来被别的运算共享利用(若是该运算也包含相同的部分子运算),从而减小重复运算的工做量。
有了上面对数据系统本质的探讨,下面咱们来讨论大数据系统的关键问题:如何实时地在任意大数据集上进行查询?大数据再加上实时计算,问题的难度比较大。
最简单的方法是,根据前述的查询等式Query = Function(All Data)
,在全体数据集上在线运行查询函数获得结果。但若是数据量比较大,该方法的计算代价太大了,因此不现实。
Lambda架构经过分解的三层架构来解决该问题:Batch Layer,Speed Layer和Serving Layer。
理想状态下,任何数据访问均可以从表达式Query= function(all data)开始,可是,若数据达到至关大的一个级别(例如PB),且还须要支持实时查询时,就须要耗费很是庞大的资源。一个解决方式是预运算查询函数(precomputed query function)。书中将这种预运算查询函数称之为Batch View(A),这样当须要执行查询时,能够从Batch View中读取结果。这样一个预先运算好的View是能够创建索引的,于是能够支持随机读取(B)。因而系统就变成:
(A)batch view = function(all data)
(B)query = function(batch view)
在Lambda架构中,实现(A)batch view =function(all data)的部分称之为Batch Layer。Batch Layer的功能主要有两点:
存储数据集
根据前述对数据When&What特性的讨论,Batch Layer采用不可变模型存储全部的数据。由于数据量比较大,能够采用HDFS之类的大数据储存方案。若是须要按照数据产生的时间前后顺序存放数据,能够考虑如InfluxDB之类的时间序列数据库(TSDB)存储方案。
构建查询View
上面说到根据等式Query = Function(All Data),在全体数据集上在线运行查询函数获得结果的代价太大。但若是咱们预先在数据集上计算并保存查询函数的结果,查询的时候就能够直接返回结果(或经过简单的加工运算就可获得结果)而无需从新进行完整费时的计算了。这儿能够把Batch Layer当作是一个数据预处理的过程。咱们把针对查询预先计算并保存的结果称为View,View是Lambda架构的一个核心概念,它是针对查询的优化,经过View便可以快速获得查询结果。
显然,batch view是一个批处理过程,如采用Hadoop或spark支持的map-reduce方式。采用这种方式计算获得的每一个view都支持再次计算,且每次计算的结果都相同。Batch Layer的工做能够简单的用以下伪码表示:
该工做看似简单,实质很是强大。任何人为或机器发生的错误,均可以经过修正错误后从新计算来恢复获得正确结果。
对View的理解
View是一个和业务关联性比较大的概念,View的建立须要从业务自身的需求出发。一个通用的数据库查询系统,查询对应的函数变幻无穷,不可能穷举。可是若是从业务自身的需求出发,能够发现业务所须要的查询经常是有限的。Batch Layer须要作的一件重要的工做就是根据业务的需求,考察可能须要的各类查询,根据查询定义其在数据集上对应的Views。
Batch Layer的Immutable data模型和Views
以下图agent id=50023的人,在10:00:06分的时候,状态是calling,在10:00:10的时候状态为waiting。在传统的数据库设计中,直接后面的纪录覆盖前面的纪录,而在Immutable数据模型中,不会对原有数据进行更改,而是采用插入修改纪录的形式更改历史纪录。
上文所说起的View是上图中预先计算获得的相关视图,例如:2016-06-21当天全部上线的agent数,每条热线、公司下上线的Agent数。根据业务须要,预先计算出结果。此过程至关于传统数仓建模的应用层,应用层也是根据业务场景,预先加工出的view。
Batch Layer能够很好的处理离线数据,但有不少场景数据不断实时生成,而且须要实时查询处理。Speed Layer正是用来处理增量的实时数据。
Speed Layer和Batch Layer比较相似,对数据进行计算并生成Realtime View,其主要区别在于:
综上所诉,Speed Layer是Batch Layer在实时性上的一个补充。Speed Layer可总结为:
(C)realtime view=function(realtime view,new data)
注意,realtime view是基于新数据和已有的realtime view。
Lambda架构将数据处理分解为Batch Layer和Speed Layer有以下优势:
如前所述,任何传入查询都必须经过合并来自批量视图和实时视图的结果来获得答案,所以这些视图须要知足Monoid的结合律特性。须要注意的一点是,实时视图是之前的实时视图和新数据增量的函数,所以可使用增量算法。批处理视图是全部数据的函数,所以应该在那里使用重算算法。
Lambda架构的Serving Layer用于响应用户的查询请求,合并Batch View和Realtime View中的结果数据集到最终的数据集。
这儿涉及到数据如何合并的问题。前面咱们讨论了查询函数的Monoid性质,若是查询函数知足Monoid性质,即知足结合律,只须要简单的合并Batch View和Realtime View中的结果数据集便可。不然的话,能够把查询函数转换成多个知足Monoid性质的查询函数的运算,单独对每一个知足Monoid性质的查询函数进行Batch View和Realtime View中的结果数据集合并,而后再计算获得最终的结果数据集。另外也能够根据业务自身的特性,运用业务自身的规则来对Batch View和Realtime View中的结果数据集合并。
综上所诉,Serving Layer采用以下等式表示:
(D)query=function(batch view, realtime view)
上面分别讨论了Lambda架构的三层:Batch Layer,Speed Layer和Serving Layer。总结下来,Lambda架构就是以下的三个等式:
batch view = function(all data) realtime view = function(realtime view, new data) query = function(batch view, realtime view)
下图给出了Lambda架构的一个完整视图和流程。
数据流进入系统后,同时发往Batch Layer和Speed Layer处理。Batch Layer以不可变模型离线存储全部数据集,经过在全体数据集上不断从新计算构建查询所对应的Batch Views。Speed Layer处理增量的实时数据流,不断更新查询所对应的Realtime Views。Serving Layer响应用户的查询请求,合并Batch View和Realtime View中的结果数据集到最终的数据集。
下图给出了Lambda架构中各组件在大数据生态系统中和阿里集团的经常使用组件。数据流存储选用不可变日志的分布式系统Kafka、TT、Metaq;BatchLayer数据集的存储选用Hadoop的HDFS或者阿里云的ODPS;BatchView的加工采用MapReduce;BatchView数据的存储采用Mysql(查询少许的最近结果数据)、Hbase(查询大量的历史结果数据)。SpeedLayer采用增量数据处理Storm、Flink;RealtimeView增量结果数据集采用内存数据库Redis。
另外一个实现版本:
根据batch layer的特色,具有存储(HDFS)和计算(MapReduce)的Hadoop显然是第一人选,而batch view 能够是hadoop自己的hdfs 或者基于hdfs的所构建的相似hive那样的仓库,speed layer由于时效性的影响,采用实时流式处理系统,例如strom或者spark streaming, 而speed view 能够存在HBase 或者其余相似的Nosql数据库。server layer 提供用户查询的方法,采用facebook 开源的Impala,统一入口查询。或者本身实现hive和HBase统一查询。这是两年前的文章,当时spark 还没那么火,如今看来spark能够直接做为batch和speed层的替代者了。
Lambda架构是个通用框架,各个层选型时不要局限时上面给出的组件,特别是对于View的选型。从我对Lambda架构的实践来看,由于View是个和业务关联性很是大的概念,View选择组件时关键是要根据业务的需求,来选择最适合查询的组件。不一样的View组件的选择要深刻挖掘数据和计算自身的特色,从而选择出最适合数据和计算自身特色的组件,同时不一样的View能够选择不一样的组件。
在过去Lambda数据架构成为每个公司大数据平台必备的架构,它解决了一个公司大数据批量离线处理和实时数据处理的需求。一个典型的Lambda架构以下:
数据从底层的数据源开始,通过各类各样的格式进入大数据平台,在大数据平台中通过Kafka、Flume等数据组件进行收集,而后分红两条线进行计算。一条线是进入流式计算平台(例如 Storm、Flink或者Spark Streaming),去计算实时的一些指标;另外一条线进入批量数据处理离线计算平台(例如Mapreduce、Hive,Spark SQL),去计算T+1的相关业务指标,这些指标须要隔日才能看见。
Lambda架构经历多年的发展,其优势是稳定,对于实时计算部分的计算成本可控,批量处理能够用晚上的时间来总体批量计算,这样把实时计算和离线计算高峰分开,这种架构支撑了数据行业的早期发展,可是它也有一些致命缺点,并在大数据3.0时代愈来愈不适应数据分析业务的需求。缺点以下:
也就是因为Lambda架构的以上局限性,Kappa应运而生,它比Lambda架构更加灵活和精简,具体将另文介绍。
Kappa架构: