导读:近年来随着随着开源社区的发展,越来越多新的技术被开源,例如雅虎开源的Hadoop分布式计算框架,到UC伯克利分校开源的Apache Spark等,而伴随着这些技术的发展,促使着企业数据架构的演进,从传统的关系型数据存储架构,逐步演化为分布式处理和存储的架构
01 传统数据基础架构
如图所示,传统的单体数据架构(Monolithic Architecture)中最大的特点便是集中式数据存储,企业内部可能有诸多的系统,例如Web业务系统,订单系统,CRM系统,ERP系统,监控系统等,这些系统的事务性数据都主要基于集中式的关系性数据库(DBMS)实现存储,大多数将架构分为计算层和存储层,存储层负责企业内系统的数据访问,且具有最终的数据一致性保障,这些数据反映了当前的业务状态,例如系统的订单交易量,网站的活跃用户数,每个用户的交易额变化等,所有的更新操作均需要借助于数据库实现。
单体架构的初期效率很高,但是随着时间推移,业务越来越多,系统逐渐变得大,越来越难以维护和升级,数据库是唯一的准确数据源,每个应用都需要访问数据库来获取对应的数据,如果数据库发生改变或者出现问题,则将对整个业务系统都会产生影响。
随着微服务架构(Microservices Architecture)的出现,企业开始则逐渐采用微服务作为企业业务系统的架构体系,微服务架构的核心思想是,一个应用是由多个小的、相互独立的、微服务组成,这些服务运行在自己的进程中,开发和发布都没有依赖。不同的服务能依据不同的业务需求,构建的不同的技术架构之上,能够聚焦在有限的业务功能。
微服务架构将系统拆解成不同的独立的服务模块,每个模块分别使用各自独立的数据库,这种模式解决了业务系统拓展的问题,但是也带了新的问题,就是业务交易数据过于分散在不同的系统中,很难将数据进行集中化管理,对于企业内部进行数据分析或者数据挖掘之类的应用,则需要通过从不同的数据库之上进行数据抽取,将数据从数据库中周期性地同步到数据仓库中,然后在数据仓库之上进行数据的抽取、转换、加载(ETL),从而构建成不同的数据集市和应用,提供给业务系统使用。
02 大数据数据架构
起初数据仓库主要还是构建在关系型数据库之上,例如Oracle,Mysql等数据库,但是随着企业数据量的增长,传统的关系型数据库已经无法支撑大规模数据集的存储和分析,越来越多的企业开始选择基于Hadoop构建企业级大数据平台。同时众多Sql-On-Hadoop技术方案的提出,也让企业在Hadoop上构建不同类型的数据应用变得简单而高效,例如通过使用Apache Hive进行数据ETL处理,通过使用Apache Impala进行实时交互性查询等。
大数据技术的兴起,让企业能够更加灵活高效地使用自己的业务数据,从数据中提取出更多重要的价值,并将数据分析和挖掘出来的结果应用在企业的决策、营销、管理等方面。但不可避免的是,随着越来越多新技术的出现与使用,让企业的数据平台出现了前所未有的复杂度,企业内部一套数据管理平台可能会借助众多开源技术组件。例如企业在构建企业数据仓库过程中,数据往往都是周期性的从业务系统中同步到大数据平台,完成一系列ETL转换动作之后,最终形成数据集市等应用。但对于不同类型的应用对时间要求是不同的,例如对于普通报表平台只要按天输出当日统计销售报表即可,但是对于一些时间要求比较高的应用,比如实时报表统计,必须非常低的延时展示统计结果,人们更关注的是当前的结果。为了解决这种问题,业界提出一套Lambda架构方案来处理不同类型的数据,如图1-2所示,大数据平台中包含批量计算的Batch Layer和实时计算的Speed Layer,通过在一套平台中将两个方案整合在一起,如使用Hadoop MapReduce进行批量数据的处理,使用Apache Storm进行实时数据的处理。这种架构在一定程度上解决了不同计算类型的问题,但是所带来的问题是在于框架太多导致平台复杂度过高,运维成本高等。在一套资源管理平台中管理不同类型的计算框架使用也是非常困难的事情,总而言之Lambda架构是构建大数据应用程序的一种很有效的解决方案,但是还不是最完美的方案。
随着Apache Spark的分布式内存处理框架的出现,提出了将数据切分成微批的处理模式进行流式数据处理,从而能达到在一套计算框架内统一批量计算和流式计算,但主要因为Spark因为本身就是批处理模式的原因,即使数据批次被切分的再细,还是会存在一定的时延,并不能完美且高效的处理原生的数据流,从而不能更好的处理流式数据,可以说Spark的出现本质是在一定程度上对Hadoop架构进行了一定的升级和优化,但是却并没有颠覆性地改变。
03 有状态流计算架构
回归数据产生的本质,其实是一条条真实存在的事件,前面提到的不同的架构其实都在一定程度违背了这种本质,需要通过在一定范围内延时折中方式对业务数据进行处理,最终得到基于业务数据统计的准确结果,实际上基于流式计算技术局限性的原因,很难在数据产生的过程中进行计算,直接产生统计结果,因为这不仅对系统有非常高的要求,还必须要满足高性能,高吞吐,低延时等众多目标。但是技术对完美的追求从来都是无止境的,企业需要更快速的统计出准确的结果,以满足他们对于实时计算业务的需求。
有状态流计算架构的提出,从不同程度上满足了企业的这种需求,企业基于实时的流式数据中,维护所有计算过程的中间状态,所谓状态就是计算过程中产生的中间计算结果,每次计算新的数据进入到流式系统中都是基于中间状态结果的基础之上进行运算,最终产生预期的统计结果,这种方式最大的优势是不需要将原始数据重新从存储中拿出来,从而进行全量计算,因为这种计算方式代价可能是非常高的。从另一个角度讲,这也是对批量ETL方案的补充,用户无需在通过调度和协调各种批量计算工具,从数据仓库中获取数据统计结果,然后落地存储,想象一下这些操作全部都可以经过流式数据中完成,就可以减轻用户对其他框架的依赖,减少中间计算过程中的时间损耗。
如果计算的结果都能保持一致,实时计算能够在很短的时间内统计出结果,批量计算则需要等待一定时间段内得出,相信大多数用户会选择使用有状态流进行数据处理,而传统的批量计算模式将逐渐被替代。
04 为什么会是Flink
有状态流计算将会随着技术的发展,逐步成为企业作为构建数据平台的架构模式,而这种技术实现的开源方案目前从社区来看,能够满足的就是Apache Flink。Flink通过实现Google Dataflow流式计算模型实现了高吞吐,低延迟,高性能兼具实时流式计算框架。同时Flink支持高效容错的状态管理,Flink能够将其状态维护在内存或RockDB数据库中,为了防止状态在计算过程中因为系统异常而出现丢失,Flink周期性的通过分布式快照技术CheckPoints实现状态的持久化维护,使得在系统即使在停机或者异常的情况下都能正确的进行状态恢复,从而保证在任何时间都能计算出正确的结果。
数据架构的演变过程,伴随着技术的不断迭代更新,Flink具有先进的架构理念,以及诸多的优秀特性,以及完善的编程接口,而Flink也在每一次的Release版本中,不断推出新的特性,例如Queryable State功能的提出,将直接容许用户通过远程的方式直接获取流式计算任务的状态信息,也就是说数据不需要落地数据库就能直接从流式应用中直接查询出,对于实时交互式的查询业务可以直接从Flink的状态中查询最新的结果,当然这个功能目前还属于Beta版本,但是相信在不久的未来,会变得越来越完善,那时Flink将不仅作为实时流式处理的框架,更多的可能会成为一套实时的存储引擎,会让更多的用户从有状态计算的技术中获取收益。
同时支持高吞吐、低延迟、高性能
Flink是一套集高吞吐,低延迟,高性能三者于一身的分布式流式数据处理框架。非常成熟的计算框架Apache Spark也只能兼顾高吞吐和高性能特性,在Spark Streaming流式计算中无法做到低延迟保障;而Apache Storm只能支持低延迟和高性能特性,但是无法满足高吞吐的要求。而对于满足高吞吐,低延迟,高性能这三个目标对分布式流式计算框架是非常重要的。
支持事件时间(Event Time)概念
在流式计算领域中,窗口计算的地位举足轻重,但目前大多数计算框架窗口计算所采用的都是系统时间(Process Time),也是事件传输到计算框架处理时,系统主机的当前时间,Flink能够支持基于事件时间(Event Time)语义的进行窗口计算,就是使用事件产生的时间,这种时间机制使得事件即使无序到达甚至延迟到达,数据流都能够计算出精确的结果,同时保持了事件原本产生时的在时间维度的特点,而不受网络传输或者计算框架的影响。
支持有状态计算
Flink在1.4版本中实现了状态管理,所谓状态就是在流式计算过程中将算子的中间结果数据的保存在内存或者DB中,等下一个事件进入接着从状态中获取中间结果进行计算,从而无需基于全部的原始数据统计结果,这种做法极大地提升了系统的性能,同时也降低了计算过程的耗时。对于数据量非常大且逻辑运算非常复杂的流式运算,基于状态的流式计算则显得非常使用。
支持高度灵活的窗口(Window)操作
在流处理应用中,数据是连续不断的,需要通过窗口的方式对流数据进行一定范围的聚合计算,例如统计在过去的1分钟内有多少用户点击了某一网页,在这种情况下,我们必须定义一个窗口,用来收集最近一分钟内的数据,并对这个窗口内的数据再进行计算。Flink将窗口划分为基于Time、Count、Session,以及Data-driven等类型的窗口操作,窗口能够用灵活的触发条件定制化从而达到对复杂的流传输模式的支持,不同的窗口操作应用能够反馈出真实事件产生的情况,用户可以定义不同的窗口触发机制来满足不同的需求。
基于轻量级分布式快照(Snapshot)实现的容错
Flink能够分布式运行在上千个节点之上,将一个大型计算的流程拆解成小的计算过程,然后将计算过程分布到单台并行节点上进行处理。在任务执行过程中,能够自动的发现事件处理过程中的错误而导致数据不一致的问题,常见的错误类型例如:节点宕机,或者网路传输问题,或是由于用户因为升级或修复问题而导致计算服务重启等。在这些情况下,通过基于分布式快照技术的Checkpoints,将执行过程中的任务信息进行持久化存储,一旦任务出现异常宕机,Flink能够进行任务的自动恢复,从而确保数据在处理过程中的一致性。
基于JVM实现独立的内存管理
内存管理是每套计算框架需要重点考虑的领域,尤其对于计算量比较大的计算场景,数据在内存中该如何进行管理,针对内存管理这块,Flink实现了自身管理内存的机制,尽可能减少Full GC对系统的影响。另外通过自定义序列化/反序列化方法将所有的对象转换成二进制在内存中存储,降低数据存储的大小,更加有效的对内存空间进行利用,降低GC所带来的性能下降或者任务停止的风险,同时提升了分布式处理过数据传输的性能。因此Flink较其他分布式处理的框架则会显得更加稳定,不会因为JVM GC等问题而导致整个应用宕机的问题。
Save Points(保存点)
对于7*24小时运行的流式应用,数据源源不断的接入,在一段时间内应用的终止都有可能导致数据的丢失或者计算结果的不准确性,例如进行版本的升级,停机运维操作等,都能导致这种情况发生。然而值得一提的是Flink通过其Save Points技术能够将任务执行的快照(Snapshot)保存在存储介质上,等待任务重启的时候可以直接从实现保存的Save Points恢复原有的计算状态,使得任务继续按照停机之前的状态继续运行,Save Points技术可以让用户更好的管理和运维实时流式应用。
同时Flink除了上述的特性之外也具有其他非常优秀的特性,可以让用户有更多选择。Flink具备非常多的优秀特性,这不仅让Flink在社区的知名度越来越高,也吸引了众多的企业参与研发和使用Flink这项技术。