Lambda架构是由Storm的做者Nathan Marz提出的一个实时大数据处理框架。Marz在Twitter工做期间开发了著名的实时大数据处理框架Storm,Lambda架构是其根据多年进行分布式大数据系统的经验总结提炼而成。算法
Lambda架构的目标是设计出一个能知足实时大数据系统关键特性的架构,包括有:高容错、低延时和可扩展等。Lambda架构整合离线计算和实时计算,融合不可变性(Immunability),读写分离和复杂性隔离等一系列架构原则,可集成Hadoop,Kafka,Storm,Spark,Hbase等各种大数据组件。数据库
Marz认为大数据系统应具备如下的关键特性:网络
Robust and fault-tolerant(容错性和鲁棒性):对大规模分布式系统来讲,机器是不可靠的,可能会当机,可是系统须要是健壮、行为正确的,即便是遇到机器错误。除了机器错误,人更可能会犯错误。在软件开发中不免会有一些Bug,系统必须对有Bug的程序写入的错误数据有足够的适应能力,因此比机器容错性更加剧要的容错性是人为操做容错性。对于大规模的分布式系统来讲,人和机器的错误天天均可能会发生,如何应对人和机器的错误,让系统可以从错误中快速恢复尤为重要。架构
Low latency reads and updates(低延时):不少应用对于读和写操做的延时要求很是高,要求对更新和查询的响应是低延时的。app
Scalable(横向扩容):当数据量/负载增大时,可扩展性的系统经过增长更多的机器资源来维持性能。也就是常说的系统须要线性可扩展,一般采用scale out(经过增长机器的个数)而不是scale up(经过加强机器的性能)。框架
General(通用性):系统须要可以适应普遍的应用,包括金融领域、社交网络、电子商务数据分析等。分布式
Extensible(可扩展):须要增长新功能、新特性时,可扩展的系统能以最小的开发代价来增长新功能。函数
Allows ad hoc queries(方便查询):数据中蕴含有价值,须要可以方便、快速的查询出所须要的数据。oop
Minimal maintenance(易于维护):系统要想作到易于维护,其关键是控制其复杂性,越是复杂的系统越容易出错、越难维护。性能
Debuggable(易调试):当出问题时,系统须要有足够的信息来调试错误,找到问题的根源。其关键是可以追根溯源到每一个数据生成点。
为了设计出能知足前述的大数据关键特性的系统,咱们须要对数据系统有本质性的理解。咱们可将数据系统简化为:
数据系统 = 数据 + 查询
从而从数据和查询两方面来认识大数据系统的本质。
咱们先从“数据”的特性谈起。数据是一个不可分割的单位,数据有两个关键的性质:When和What。
When是指数据是与时间相关的,数据必定是在某个时间点产生的。好比Log日志就隐含着按照时间前后顺序产生的数据,Log前面的日志数据必定先于Log后面的日志数据产生;消息系统中消息的接受者必定是在消息的发送者发送消息后接收到的消息。相比于数据库,数据库中表的记录就丢失了时间前后顺序的信息,中间某条记录多是在最后一条记录产生后发生更新的。对于分布式系统,数据的时间特性尤为重要。分布式系统中数据可能产生于不一样的系统中,时间决定了数据发生的全局前后顺序。好比对一个值作算术运算,先+2,后*3,与先*3,后+2,获得的结果彻底不一样。数据的时间性质决定了数据的全局发生前后,也就决定了数据的结果。
What是指数据的自己。因为数据跟某个时间点相关,因此数据的自己是不可变的(immutable),过往的数据已经成为事实(Fact),你不可能回到过去的某个时间点去改变数据事实。这也就意味着对数据的操做其实只有两种:读取已存在的数据和添加更多的新数据。采用数据库的记法,CRUD就变成了CR,Update和Delete本质上实际上是新产生的数据信息,用C来记录。
根据上述对数据本质特性的分析,Lamba架构中对数据的存储采用的方式是:数据不可变,存储全部数据。
经过采用不可变方式存储全部的数据,能够有以下好处:
简单。采用不可变的数据模型,存储数据时只须要简单的往主数据集后追加数据便可。相比于采用可变的数据模型,为了Update操做,数据一般须要被索引,从而能快速找到要更新的数据去作更新操做。
应对人为和机器的错误。前述中提到人和机器天天均可能会出错,如何应对人和机器的错误,让系统可以从错误中快速恢复极其重要。不可变性(Immutability)和从新计算(Recomputation)则是应对人为和机器错误的经常使用方法。采用可变数据模型,引起错误的数据有可能被覆盖而丢失。相比于采用不可变的数据模型,由于全部的数据都在,引起错误的数据也在。修复的方法就能够简单的是遍历数据集上存储的全部的数据,丢弃错误的数据,从新计算获得Views(View的概念参考4.1.2)。从新计算的关键点在于利用数据的时间特性决定的全局次序,依次顺序从新执行,必然能获得正确的结果。
当前业界有不少采用不可变数据模型来存储全部数据的例子。好比分布式数据库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。
Batch Layer的功能主要有两点:
根据前述对数据When&What特性的讨论,Batch Layer采用不可变模型存储全部的数据。由于数据量比较大,能够采用HDFS之类的大数据储存方案。若是须要按照数据产生的时间前后顺序存放数据,能够考虑如InfluxDB之类的时间序列数据库(TSDB)存储方案。
上面说到根据等式Query = Function(All Data),在全体数据集上在线运行查询函数获得结果的代价太大。但若是咱们预先在数据集上计算并保存查询函数的结果,查询的时候就能够直接返回结果(或经过简单的加工运算就可获得结果)而无需从新进行完整费时的计算了。这儿能够把Batch Layer当作是一个数据预处理的过程。咱们把针对查询预先计算并保存的结果称为View,View是Lamba架构的一个核心概念,它是针对查询的优化,经过View便可以快速获得查询结果。
若是采用HDFS来储存数据,咱们就可使用MapReduce来在数据集上构建查询的View。Batch Layer的工做能够简单的用以下伪码表示:
该工做看似简单,实质很是强大。任何人为或机器发生的错误,均可以经过修正错误后从新计算来恢复获得正确结果。
对View的理解:
View是一个和业务关联性比较大的概念,View的建立须要从业务自身的需求出发。一个通用的数据库查询系统,查询对应的函数变幻无穷,不可能穷举。可是若是从业务自身的需求出发,能够发现业务所须要的查询经常是有限的。Batch Layer须要作的一件重要的工做就是根据业务的需求,考察可能须要的各类查询,根据查询定义其在数据集上对应的Views。
Batch Layer能够很好的处理离线数据,但有不少场景数据不断实时生成,而且须要实时查询处理。Speed Layer正是用来处理增量的实时数据。
Speed Layer和Batch Layer比较相似,对数据进行计算并生成Realtime View,其主要区别在于:
Speed Layer处理的数据是最近的增量数据流,Batch Layer处理的全体数据集
Speed Layer为了效率,接收到新数据时不断更新Realtime View,而Batch Layer根据全体离线数据集直接获得Batch View。
Lambda架构将数据处理分解为Batch Layer和Speed Layer有以下优势:
容错性。Speed Layer中处理的数据也不断写入Batch Layer,当Batch Layer中从新计算的数据集包含Speed Layer处理的数据集后,当前的Realtime View就能够丢弃,这也就意味着Speed Layer处理中引入的错误,在Batch Layer从新计算时均可以获得修正。这点也能够当作是CAP理论中的最终一致性(Eventual Consistency)的体现。
复杂性隔离。Batch Layer处理的是离线数据,能够很好的掌控。Speed Layer采用增量算法处理实时数据,复杂性比Batch Layer要高不少。经过分开Batch Layer和Speed Layer,把复杂性隔离到Speed Layer,能够很好的提升整个系统的鲁棒性和可靠性。
Lambda架构的Serving Layer用于响应用户的查询请求,合并Batch View和Realtime View中的结果数据集到最终的数据集。
这儿涉及到数据如何合并的问题。前面咱们讨论了查询函数的Monoid性质,若是查询函数知足Monoid性质,即知足结合率,只须要简单的合并Batch View和Realtime View中的结果数据集便可。不然的话,能够把查询函数转换成多个知足Monoid性质的查询函数的运算,单独对每一个知足Monoid性质的查询函数进行Batch View和Realtime View中的结果数据集合并,而后再计算获得最终的结果数据集。另外也能够根据业务自身的特性,运用业务自身的规则来对Batch View和Realtime View中的结果数据集合并。
上面分别讨论了Lambda架构的三层:Batch Layer,Speed Layer和Serving Layer。下图给出了Lambda架构的一个完整视图和流程。
数据流进入系统后,同时发往Batch Layer和Speed Layer处理。Batch Layer以不可变模型离线存储全部数据集,经过在全体数据集上不断从新计算构建查询所对应的Batch Views。Speed Layer处理增量的实时数据流,不断更新查询所对应的Realtime Views。Serving Layer响应用户的查询请求,合并Batch View和Realtime 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架构是个通用框架,各个层选型时不要局限时上面给出的组件,特别是对于View的选型。从我对Lambda架构的实践来看,由于View是个和业务关联性很是大的概念,View选择组件时关键是要根据业务的需求,来选择最适合查询的组件。不一样的View组件的选择要深刻挖掘数据和计算自身的特色,从而选择出最适合数据和计算自身特色的组件,同时不一样的View能够选择不一样的组件。
在Lambda架构身上能够看到不少现有设计思想和架构的影子,如Event Sourcing和CQRS,这儿咱们把它们和Lambda架构作一结合对比,从而去更深刻的理解Lambda架构。
事件溯源(Event Sourcing)是由大名鼎鼎的Martin Flower大叔提出来的架构模式。Event Sourcing本质上是一种数据持久化的方式,它将引起变化的事件(Event)自己存储下来。相比于传统数据是持久化方式,存储的是事件引起的结果,而非事件自己,这样咱们在保存结果的同时,实际上失去了追溯致使结果缘由的机会。
这儿能够看到Lambda架构中数据集的存储和Event Sourcing中的思想是彻底一致的,本质都是采用不可变的数据模型存储引起变化的事件而非变化产生的结果。从而在发生错误的时候,可以追本溯源,找到发生错误的根源,经过从新计算丢弃错误的信息来恢复系统,达到系统的容错性。
CQRS (Command Query Responsibility Segregation)将对数据的修改操做和查询操做分离,其本质和Lambda架构同样,也是一种形式的读写分离。在Lambda架构中,数据以不可变的方式存储下来(写操做),转换成查询所对应的Views,查询从View中直接获得结果数据(读操做)。
读写分离将读和写两个视角进行分离,带来的好处是复杂性的隔离,从而简化系统的设计。相比于传统作法中的将读和写操做放在一块儿的处理方式,对于读写操做业务很是复杂的系统,只会使系统变得异常复杂,难以维护。
本文介绍了Lambda架构的基本概念。Lambda架构经过对数据和查询的本质认识,融合了不可变性(Immunability),读写分离和复杂性隔离等一系列架构原则,将大数据处理系统划分为Batch Layer, Speed Layer和Serving Layer三层,从而设计出一个能知足实时大数据系统关键特性(如高容错、低延时和可扩展等)的架构。Lambda架构做为一个通用的大数据处理框架,能够很方便的集成Hadoop,Kafka,Storm,Spark,Hbase等各种大数据组件。