一种hadoop集群运行ETL流程的方法及装置
【技术领域】
本发明涉及数据处理技术领域,提供了一种hadoop集群运行ETL流程的方法及装置。
【背景技术】
ETL是数据处理、构建数据仓库的一个重要工具软件,完成异构数据源的抽取、清洗转换和加载的一个过程。传统的ETL一般是把流程发布到一个集中的ETL服务器节点上运行,所有的流程或流程内组件的运行均采用多线程机制,再多的流程也只能在一个单一节点运行,并且一个大数据的处理流程,也无法提高数据处理的性能。
Hadoop大数据平台在大数据处理中已经取得相当广泛的应用。MapReduce是面向大数据并行处理的计算模型、框架和平台,提供了一种简便的并行程序设计方法,用Map和Reduce两个函数编程实现基本的并行计算任务,提供了抽象的操作和并行编程接口,以简单方便地完成大规模数据的编程和计算处理。
ETL配置的流程一般为DAG有向无环图,但hadoop提供的两个简单的map reduce函数只能完成简单DAG图的运行,无法完成稍微复杂一点DAG图的运行。而且,Hadoop虽然也提供了ChainMapper和ChainReducer的链式map reduce,但在数据源的分区、分区数据源读取、ETL流程运行完整性、使用的方便灵活性和通用性等方面都存在一定的缺陷。
鉴于此,克服上述现有技术所存在的缺陷是本技术领域亟待解决的问题。
【发明内容】
本发明需要解决的技术问题是:
传统的ETL一般是把流程发布到一个集中的ETL服务器节点上运行,再多的流程也只能在一个单一节点运行,数据处理性能较差;如果利用hadoop提供的map reduce函数则只能完成简单DAG图的运行,且在数据源的分区、分区数据源读取、ETL流程运行完整性、使用的方便灵活性和通用性等方面都存在一定的缺陷。
本发明通过如下技术方案来解决上述技术问题:
第一方面,本发明提供了一种hadoop集群运行ETL流程的方法,包括:
根据ETL流程中的reduce节点,将ETL流程分解为一个或多个MRWork;其中,每个MRWork的组件在一个map reduce中运行;
对于每个MRWork,MR Job通过自定义DelegateInputFormat,分别将MRWork的每个数据源都拆分为多个分片数据源;
MR Job通过自定义DelegateMapper重写Mapper的run方法,来并发运行MRWork中的mapper graph;其中,MRWork中的mapper数由MRWork的数据源总分片数决定;
MR Job通过自定义DelegateReducer重写Reducer的run方法,来并发运行MRWork中的reducer graph;其中,MRWork中的reducer数根据reduce节点和/或hadoop集群可申请container数进行设置。
优选的,在所述MR Job通过自定义DelegateReducer来运行MRWork中的reducergraph之后,所述方法还包括:
通过重写map reduce的OutputFormat为DummyOutputFormat来设置MR Job输出,并提交MRWork所在的MR Job。
优选的,当ETL流程被分解为多个MRWork时,按照所述多个MRWork之间的依赖关系,先后处理每一个MRWork。
优选的,对于任一MRWork,MRWork的运行依赖于其他MRWork的FileSink节点;则在处理该MRWork时,当该MRWork所依赖的FileSink组件运行完成后,再提交该MRWork运行。
优选的,所述MR Job通过自定义DelegateInputFormat,分别将MRWork的每个数据源都拆分为多个分片数据源,具体为:
MR Job设置InputFormat为自定义的DelegateInputFormat,以便由DelegateInputFormat委托处理MRWork每个数据源的SourceInputFormat;
每个SourceInputFormat通过重写getSplits,实现对应数据源的分片以及对分片的读取。
优选的,在每个SourceInputFormat重写getSplits之后,所述方法还包括:
每个SourceInputFormat通过重写createRecordReader来实现自己数据源的读取;其中,对于hadoop map reduce框架本身支持读取的数据源,实现分片数据源数据格式的record reader接口;对于hadoop map reduce框架本身不支持读取或支持度不满足要求的数据源,将createRecordReader定义为DummyRecordReader,数据源读取不会访问,直接在mapper graph实现自己数据源的读取,也就是子流程的数据源节点的读取,只不过只能读取自己分片split的部分数据。
优选的,所述reduce节点为排序组件、聚合组件、连接组件、增量比对组件或去重复组件。
优选的,如果ETL流程中无reduce节点,则将ETL流程分解为一个MRWork,对应在一个map reduce中运行;
如果ETL流程中有X个reduce节点,且ETL流程中没有不带reduce节点的分支,则将ETL流程分解为X个MRWork;
如果ETL流程中有X个reduce节点,且ETL流程中含有不带reduce节点的分支,则将ETL流程分解为X+1个MRWork;其中,X≥1。
优选的,所述MRWork中的reducer数根据reduce节点和/或hadoop集群可申请container数进行设置,具体包括:
如果ETL流程中无reduce节点,则MRWork中的reducer数设置为0;
如果ETL流程中有reduce节点,且reduce节点为排序组件,则MRWork中的reducer数设置为1;
如果ETL流程中有reduce节点,且reduce节点为连接组件、聚合组件、增量比对组件或去重复组件,则MRWork中的reducer数根据hadoop集群可申请container数设置为1个或多个。
第二方面,本发明提供了一种hadoop集群运行ETL流程的装置,包括至少一个处理器和存储器,所述至少一个处理器和存储器之间通过数据总线连接,所述存储器存储有可被所述至少一个处理器执行的指令,所述指令在被所述处理器执行后,用于完成第一方面所述的hadoop集群运行ETL流程的方法。
与现有技术相比,本发明的有益效果是:
本发明实现了基于hadoop的分布式ETL框架,这种分布式ETL将流程分解为一个或多个MRWork提交到hadoop集群环境中执行,并且把数据源拆分为多个分片数据源,从而把流程分解为多个子流程,这些子流程可并发运行于hadoop集群环境,可以极大提高流程并发处理能力;另外,reducer数可根据reduce节点和/或hadoop集群可申请container数设置,通过设置合适的reduce任务数,可极大提高流程并发处理能力。
【附图说明】
为了更清楚地说明本发明实施例的技术方案,下面将对本发明实施例中所需要使用的附图作简单地介绍。显而易见地,下面所描述的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1为本发明实施例提供的一种hadoop集群运行ETL流程的方法流程图;
图2为本发明实施例提供的一种ETL流程在无reduce节点有一个数据源时的分解示意图;
图3为本发明实施例提供的一种ETL流程在无reduce节点有多个数据源时的分解示意图;
图4为本发明实施例提供的一种ETL流程在有一个reduce节点一个数据源时的分解示意图;
图5为本发明实施例提供的一种ETL流程在有一个reduce节点多个数据源时的分解示意图;
图6为本发明实施例提供的一种ETL流程在有多个reduce节点一个数据源时的分解示意图;
图7为本发明实施例提供的一种hadoop集群运行ETL流程的实时监控方法流程图;
图8为本发明实施例提供的一种hadoop集群运行ETL流程中调用RPC服务进行监控的示意图;
图9为本发明实施例提供的一种hadoop集群运行ETL流程的装置架构图。
【具体实施方式】
为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。
在本发明各实施例中,符号“/”表示同时具有两种功能的含义,而对于符号“A和/或B”则表明由该符号连接的前后对象之间的组合包括“A”、“B”、“A和B”三种情况。
此外,下面所描述的本发明各个实施方式中所涉及到的技术特征只要彼此之间未构成冲突就可以相互组合。下面就参考附图和实施例结合来详细说明本发明。
实施例1:
基于传统ETL数据处理性能的制约以及简单使用hadoop存在的问题,本发明实施例提供了一种hadoop集群运行ETL流程的方法,实现了基于hadoop的分布式ETL框架。如图1所示,本发明实施例提供的hadoop集群运行ETL流程的方法主要包括以下步骤:
步骤201,根据ETL流程中的reduce节点,将ETL流程分解为一个或多个MRWork;其中,每个MRWork的组件在一个map reduce中运行。
这里将ETL流程分解为一个或多个MRWork(即Map Reduce Work,表示ETL流程分解后得到的子流程信息封装类),也就是将ETL流程提交到了hadoop集群环境中执行;其中,一个MRWork对应一个map reduce。一个MRWork的所有组件,通常是一部分在mapper中运行,称为mapper graph;一部分在reducer中运行,称为reducer graph;在本发明实施例中,mapper和reducer的具体数量设置及运行情况将在后文展开介绍,此处不做赘述。
在ETL流程中,可能存在reduce节点也可能不存在reduce节点:如果数据处理只需要流式处理,则无reduce节点;如果需要数据具备一定的顺序性(如此才能高效率运算处理),则存在reduce节点,例如聚合组件、连接组件、增量比对组件或去重复组件等等。其中,排序组件也不支持流式处理,需要接收到最后一条数据,才能输出排序结果,也是reduce组件。那么,在进行流程分解时,如果ETL流程中无reduce节点,则将ETL流程分解为一个MRWork,对应在一个map reduce中运行。如果ETL流程中有X个reduce节点,且ETL流程中没有不带reduce节点的分支,则将ETL流程分解为X个MRWork,对应在X个map reduce中运行,X≥1;即此时MRWork的数量与reduce节点的数量是一致的,且map reduce中既有mapper又有reducer。如果ETL流程中有X个reduce节点,且ETL流程中含有不带reduce节点的分支,则将ETL流程分解为X+1个MRWork,对应在X+1个map reduce中运行;其中,所有不带reduce节点的分支,组成一个MRWork。其中,MRWork数据结构大致如下:
public class MRWork
{
……
private Map<ActivityBean,ActivityBean[]>multiMapSourceActivityBeansMap;
private ActivityBean[]reuduceActivityBeans;
private long[]dependentFileSinkNodeIds;
……
}
在上述数据结构中,ActivityBean为每个组件属性保存者;
multiMapSourceActivityBeansMap为定义的一个map变量,其中的key为数据源组件source ActivityBean,value为数据源对应的在map中运行的组件ActivityBeans。其中,一个map可能会对应有一个或多个数据源;例如,排序组件对应一个数据源,而联合组件、连接组件等可对应多个数据源,具体可参考实施例2中给出的几个实例;
reduceActivityBeans中的第一个组件ActivityBean为reduce节点,reuduceActivityBeans所有的组件在reduce的一个或多个reducer任务中运行。
由前文可知,ETL流程有可能被拆分为一个或多个MRWork,当ETL流程被分解为一个MRWork时,直接运行处理该MRWork即可;而当ETL流程被分解为多个MRWork时,则需要按照多个MRWork之间的依赖关系,先后处理每一个MRWork。具体地,对于任一MRWork,MRWork的运行依赖于其他MRWork的FileSink节点(即Hdfs文件写入节点),则在处理该MRWork时,需要等该MRWork所依赖的所有FileSink组件运行完成后,再提交该MRWork运行。在上述数据结构中,dependentFileSinkNodeIds即为MRWork所依赖的其他MRWork的FileSink节点,则所有依赖的FileSink组件运行完成后,方可提交MRWork运行。
步骤202,对于每个MRWork,MR Job通过自定义DelegateInputFormat,分别将MRWork的每个数据源都拆分为多个分片数据源。
具体过程如下:MR Job(即Map Reduce Job)设置InputFormat为自定义的DelegateInputFormat,DelegateInputFormat委托处理MRWork每个数据源的SourceInputFormat;每个SourceInputFormat通过重写getSplits,实现对应数据源的分片splits以及对分片的读取recordReader。其中,DelegateInputFormat为派生于map reduce的InputFormat类,getSplits为InputFortmat的方法,表示获取数据源的分片。其中,MRWork的数据源总分片splits数决定了mapper数,合适的splits分片可以极大提高流程并发处理能力。换句话说,这里将数据源拆分为多个分片数据源,一个分片split对应一个mapper,从而把整个流程分解为多个mapper子流程,这些mapper子流程可并发运行于hadoop集群环境,从而极大提高流程并发处理能力。以表数据源为例,在进行分片时,分区表一般可根据分区来进行分片,非分区表一般可选取某个字段进行范围划分来进行分片。
另外,每个SourceInputFormat还需要通过重写createRecordReader来实现自己数据源的读取;其中,createRecordReader为InputFortmat的方法,表示创建数据源记录的读取。其中,对于hadoop map reduce框架本身支持读取的数据源,例如hdfs文件读取以及hbase读取的数据源,需实现该分片数据源数据格式的record reader接口;对于hadoopmap reduce框架本身不支持读取的数据源,或者支持度不满足要求(即虽然支持读取但支持不太好)的数据源,例如数据库表或视图数据源,则不用特意实现record reader接口,而是将createRecordReader定义为DummyRecordReader,数据源读取不会访问,直接在mappergraph实现自己数据源的读取,也就是子流程的数据源节点的读取,只不过只能读取自己分片split的部分数据;其中,DummyRecordReader为派生于map reduce的RecordReader。
步骤203,MR Job通过自定义DelegateMapper重写Mapper的run方法,来并发运行MRWork中的mapper graph;其中,MRWork中的mapper数由MRWork的数据源总分片数决定。
其中,DelegateMapper为派生于map reduce的Mapper类。一个MRWork的所有组件,部分或全部在mapper中运行,这些组件对应的Graph称为mapper graph;MR Job通过自定义DelegateMapper来运行mapper graph。前面已经提到,MRWork中的mapper数由MRWork的数据源总分片数决定,即每个mapper对应一个分片数据源split,且每个mapper相当于一个子流程,所有的mapper可以在hadoop集群环境中并发运行。每个split指定了数据源读取的范围,设置数据源节点的split分片范围,运行mapper graph。其中,对于hadoop map reduce框架本身支持的hdfs文件读取以及hbase读取的数据源,需实现该分片split数据源数据格式的record reader接口,该mapper graph的数据源定义为reader的一个fetch(即获取)动作,读取的数据传递给后续节点;对于hadoop map reduce框架本身支持不太好的数据源的读取,需要在mapper graph实现自己数据源的读取,也就是子流程数据源的读取
步骤204,MR Job通过自定义DelegateReducer重写Reducer的run方法,来并发运行MRWork中的reducer graph;其中,MRWork中的reducer数根据reduce节点和/或hadoop集群可申请container数进行设置。
其中,DelegateReducer为派生于map reduce的Reducer类,container表示容器。一个MRWork的所有组件,可能部分在reducer中运行,这些组件对应的Graph称为reducergraph;reducer中运行的流程的源节点从reducer context获取数据,然后传递给reducergraph中的后续节点。其中,reducer context表示与Map reduce交互的上下文接口,可接收规约后的key/values。reducer数可以是0、一个或多个,当有多个reducer时,每个reducer也相当于一个子流程,所有的reducer可以在hadoop集群环境中并发运行。其中,reducer数可根据reduce节点和/或hadoop集群可申请container数进行设置,具体如下:
如果ETL流程中无reduce节点,则此时分解后的MRWork中无reduce组件,MRWork中的reducer数设置为0。如果ETL流程中有reduce节点,且reduce节点为排序组件,则MRWork中的reducer数设置为1。如果ETL流程中有reduce节点,且reduce节点为排序组件以外的其他组件,例如连接组件、聚合组件、增量比对组件或去重复组件等,则MRWork中的reducer数根据hadoop集群可申请container数灵活设置为1个或多个;此时,在条件允许的情况下reducer数设置越多,流程并发处理能力就越强。因此,通过合理设置reducer并发数,可以极大提高流程并发处理能力。
进一步地,在运行MRWork中的reducer graph之后,即步骤204之后,所述方法还可包括:
步骤205,通过重写map reduce的OutputFormat为DummyOutputFormat来设置MRJob输出,并提交MRWork所在的MR Job。
其中,DummyOutputFormat为派生于map reduceOutputFormat的类。通过重写mapreduce的OutputFormat为DummyOutputFormat,运行ETL流程不需要额外的输出,所有的数据处理都在ETL流程内部处理。设置好MR Job输出后,即可提交MRWork所在的MR Job,以便实现MRWork的运行。
整个运行过程大致如下:
Configuration conf=new Configuration();
//conf设置MRWork属性
Job job=Job.getInstance(conf,"etl mr");
job.setInputFormatClass(DelegateInputFormat.class);
job.setMapperClass(DelegateMapper.class);
job.setReducerClass(DelegateReducer.class);
//无reduce节点时,num_reduces设置为0;如果是排序组件,num_reduces设置为1;其它根据hadoop container可用资源设置大小,提高流程并发处理能力;
job.setNumReduceTasks(num_reduces);
job.setOutputFormatClass(DummyOutputFormat.class);
job.waitForCompletion(false).
本发明实施例提供的上述方法实现了基于hadoop的分布式ETL框架,这种分布式ETL将流程分解为一个或多个MRWork提交到hadoop集群环境中执行,每个MRWork的组件在一个map reduce中运行;并且把每个数据源拆分为多个分片数据源,从而把流程分解为多个mapper子流程,这些子流程可并发运行于hadoop集群环境,且mapper数由MRWork的数据源总分片数决定,因此通过合适的splits分片可以极大提高流程并发处理能力。
如果数据处理只需要流式处理,则只需要在mapper中处理,不需要启动reducer;如果数据处理需要数据具备一定的顺序性,比如聚合、连接、增量比对、去重复,此时mapreduce中的reduce可以予以应用,即部分流程可以在reducer中运行。因此,这时通过合理设置reducer的并发任务数,可以极大提高流程并发处理能力。另外,通过重写map reduce的OutputFormat为DummyOutputFormat来设置MR Job输出,使得运行ETL流程不需要额外的输出,所有的数据处理都可在ETL流程内部处理。
实施例2:
在上述实施例1提供的一种hadoop集群运行ETL流程的方法的基础上,本发明实施例中进一步给出几个具体实例,介绍在不同的应用场景中分别如何使用实施例1中的方法在hadoop集群中运行ETL流程。
结合图2,在第一个具体实例中,对应的应用场景为:原始ETL流程中无reduce节点,有一个数据源,如图2左侧所示。由于无reduce节点,所以ETL流程分解成一个MRWork,对应在一个map reduce中运行,如图2中右侧所示。这里的数据源以表数据源为例,通过TableSourceInputFormat对表数据源进行分片以及获取表数据源的分片splits;其中,TableSourceInputFormat表示派生于map reduce InputFormat的类。分片后得到n个分片表数据源,分别记为split1、split2、......、splitn,从而将整个流程分为n个子流程,如图2中右侧所示。其中,在进行分片时,分区表一般可根据分区来分片,非分区表一般可选取某个字段进行范围划分来分片。
在该map reduce中,一个分片表数据源split对应一个mapper,则mapper的数量也为n;由于ETL流程无reduce节点,则该map reduce中无reduce组件,设置reducer数为0;也就是说,图中右侧的n个子流程均对应mapper,无reducer。其中,DelegateMapper的mappergraph组件节点由分片表数据源split、数据清洗转换组件、数据装载组件组成,由这些组件以及它们的连接构造Graph,每个mapper的run方法运行自己分片表数据源及后续组件组成的mapper graph。
结合图3,在第二个具体实例中,对应的应用场景为:原始ETL流程中无reduce节点,有多个数据源;此处以两个数据源为例,分别记为数据源1和数据源2,如图3左侧所示。由于无reduce节点,所以分解成一个MRWork,对应在一个map reduce中运行,如图3中右侧所示。这里分别对两个数据源进行分片,每个数据源分片后均得到n个分片数据源,分别记为split1、split2、......、splitn;所有数据源的总分片数为2n,从而将整个流程分为2n个子流程,如图3中右侧所示。
在该map reduce中,一个分片数据源split对应一个mapper,则mapper的数量也为2n;由于ETL流程无reduce节点,则该map reduce中无reduce组件,设置reducer数为0;也就是说,图中右侧的2n个子流程均对应mapper,无reducer。其中,DelegateMapper的mappergraph组件节点由分片数据源split、联合组件和数据装载组件组成,由这些组件以及它们的连接构造Graph,每个mapper的run方法运行自己分片数据源及后续组件组成的mappergraph。联合组件与单服务器ETL上处理方式稍有不同,每个联合组件只有一个数据源。
结合图4,在第三个具体实例中,对应的应用场景为:原始ETL流程中带有一个reduce节点,有一个数据源;此处以reduce节点为排序组件为例,如图4左侧所示。由于带有一个reduce节点,所以分解成一个MRWork,对应在一个map reduce中运行,且map reduce中既有mapper又有reducer,如图4中右侧所示。这里对数据源进行分片,得到n个分片数据源,分别记为split1、split2、......、splitn,如图4中右侧所示。
该MRWork存在reduce组件,即排序组件。排序组件被拆成两部分,一部分在mapper的run方法中运行,为sort reduce sink;一部分在reducer的run方法中运行,为sortreduce source;其中,sort reduce sink表示数据以key/value结构写入mapper context的节点,sort reduce source表示从reducer contrext接收key/values的节点)。其中,mapper数还是由数据源的总分片数来决定,即n个mapper,对应n个子流程;而由于是排序,reducer数设置为1,数据装载这个reducer graph只在一个reduce任务中运行,对应1个子流程;整个流程实际上分解为n+1个子流程。
结合图5,在第四个具体实例中,对应的应用场景为:原始ETL流程中带有一个reduce节点,有多个数据源。此处以reduce节点为连接组件为例,数据源以两个为例,分别记为数据源1和数据源2,如图5左侧所示。由于带有一个reduce节点,所以分解成一个MRWork,对应在一个map reduce中运行,且map reduce中既有mapper又有reducer,如图5中右侧所示。这里分别对两个数据源进行分片,每个数据源分片后均得到n个分片数据源,分别记为split1、split2、......、splitn;所有数据源的总分片数为2n,如图5中右侧所示。
该MRWork存在reduce组件,即连接组件。连接组件被拆成两部分,一部分在mapper的run方法中运行,为join reduce sink;一部分在reducer的run方法中运行,为joinreduce source;其中,join reduce sink表示数据以key/value结构写入mapper context的节点,join reduce source表示从reducer contrext接收key/values,然后进行连接处理的节点。mapper数还是由数据源的分片来决定,即2n个mapper,对应2n个子流程;而由于是连接,reducer数可以根据hadoop集群可申请container数进行灵活设置,数据装载这个reducer graph可在一个或多个reduce任务中并发运行。图5中以设置两个reducer为例(但并不唯一限定),对应两个子流程,则整个流程实际上分解为2n+2个子流程。
结合图6,在第五个具体实例中,对应的应用场景为:原始ETL流程中带有多个reduce节点,有一个数据源。此处以带有两个reduce节点,且reduce节点为排序组件为例,分别记为排序组件1和排序组件2,如图6左侧所示。由于带有两个reduce节点,所以分解成两个MRWork,分别记为MRWork1和MRWork2,对应在两个map reduce中运行,且两个mapreduce中都是既有mapper又有reducer。
这里两个reduce排序组件共用一个数据源,数据源、排序组件1、数据装载组件1和fileSink组件组成第一个MRWork1,且数据源仍被拆分为n个分片数据源;fileSource(即fileSink组件生成的HDFS文件数据源)、排序组件2和数据装载组件2则组成第二个MRWork2,且MRWork2依赖MRWork1的fileSink组件,则MRWork2需在MRWork1的fileSink组件运行完成后再提交运行。其中,每个MRWork的具体处理方式可参考前四个具体实例,在此不做赘述。
实施例3:
前面实施例1和实施例2中提供的hadoop集群运行ETL流程的方法,实现了基于hadoop的分布式ETL框架,极大提高了ETL流程并发处理能力,但是,在流程运行提高并发处理能力的同时,通常还需要监控运行的ETL流程,实时或间隔关注流程运行统计信息,比如数据抽取数量、清洗转换数量以及装载数量的统计。流程运行的速度到底怎么样?每个组件节点状态如何?每个组件节点处理速度到底怎么样?单一服务器版本ETL比较容易解决这些问题,一个节点最多就是多线程运行,一定在一个JVM里面运行;而分布式ETL中一个节点被分解到多个任务中并发执行,每一个任务在hadoop yarn的container中运行,都是一个单独的JVM。所以,如何监控运行的ETL流程、收集汇总流程运行信息是分布式ETL框架必须考虑和解决的问题。
因此,在上述hadoop集群运行ETL流程的方法的基础上,本发明进一步提供了一种hadoop集群运行ETL流程的实时监控方法。
结合图3和图4,所述实时监控方法主要包括以下步骤:
步骤301,ETL hadoop执行引擎启动时部署监控端RPC服务,以便各container调用访问监控端RPC服务,进而在运行过程中实时通知监控端流程运行状态、节点运行状态以及节点运行统计信息。
需要说明的是,ETL hadoop执行引擎启动时部署的监控端RPC服务,可以供所有提交运行的ETL流程的所有container访问,而无需每运行一个ETL流程或每分解一个子流程,监控端就部署启动RPC服务。也就是说,当ETL流程提交到hadoop yarn container运行时,监控端已经部署有RPC服务,供container中运行的graph调用。
监控端部署的RPC服务,具体是供container中运行的mapper graph或reducergraph调用访问,进而将流程运行状态、节点运行状态、节点运行统计信息等监控信息实时通知给监控端。其中,监控端流程执行通知RPC服务的接口定义如下:
public interface FlowExecuteNotifyService
{
……
void notifyFlowStarted(long executeId,FlowMonitorBeanflowMonitorBean);
void notifyFlowFinished(long executeId,FlowMonitorBeanflowMonitorBean);
void notifyActivityStarted(long executeId,ActivityMonitorBeanactivityMonitorBean);
void notifyActivityFinished(long executeId,ActivityMonitorBeanactivityMonitorBean);
……
}
其中,每个ETL流程具备唯一的ExecuteID,每当提交一个ETL流程到hadoop运行时,监控端就会增加一个与该ETL流程的唯一ExecuteID相关联的MapReduceFlow,以便与各container进行交互,进而获取流程运行状态、节点运行状态以及节点运行统计信息;当ETL流程整体运行完成时,监控端清除该ETL流程ExecuteID对应的MapReduceFlow。其中,MapReduceFlow表示提交流程各自运行、监控流程运行的类。
进一步地,所述MapReduceFlow对应每个组件节点分别生成MRActivityNodeMonitor(即监视器),用于监控对应节点活动的状态以及节点在每个container中的运行情况。ETL流程分解后的所有MRWorks以及所有生成的MRActivityNodeMonitors共同构成了MapReduceFlow的基本组成部分。其中,MRActivityNodeMonitor的大致数据结构如下:
public class MRActivityNodeMonitor
{
……
private ActivityState activityState=ActivityState.NEW;
//mrWorkId---->mapSourceReduceNodeIdlist
private Map<String,List<String>>mrWorkSourceReduceNodeMap;
private ActivityBean activityBean;
private int containerCount=0;
private List<ContainerExecutor>startedContainerList;
private Map<ContainerExecutor,ActivityMonitoBean>finishedContainerMap;
private AtomicInteger finishedContainerCount=new AtomicInteger(0);
……
}
各组件节点的activityState(即运行状态)有五种:ActivityState.NEW(未运行)、ActivityState.RUNNING(运行中)、ActivityState.SUCCEEDED(运行成功)、ActivityState.FAILED(运行失败)以及ActivityState.CANCELED(运行取消)。mrWorkSourceReduceNodeMap表示该ActivityBean可能对应多个MRWork。
containerCount表示该ActivityBean活动运行于hadoopcontainer的总数;startedContainerList表示已经启动运行的ContainerExecutor的列表;finishedContainerMap表示已经运行完成的ContainerExecutor以及ActivityMonitorBean;finishedContainerCount表示ActivityBean活动已经运行完成的hadoop container数。
继续结合图4,对于任一container,container启动后运行graph之前,需要访问监控端并注册ContainerExecutor,方便后续监控端访问container进而间隔刷新container内部各节点的运行统计信息;其中,ContainerExecutor为方便监控端访问container的一个封装类。container启动mapper graph或reducer graph后,在运行过程中便会实时通知监控端流程运行状态、节点运行状态以及节点运行统计信息等监控信息,具体过程如下:
(1)流程运行开始状态的通知:graph开始运行后,通知监控端RPC服务对应的子流程开始运行,使得监控端获取流程的监控信息FlowMonitorBean。
每个ETL流程具备唯一的ExecuteID,且该ETL流程对应的多个子流程也具备与ETL流程相同的ExecuteID,则当监控端首次接收到任一子流程开始运行的通知后,监控端即可通过ExecuteID找到运行的ETL流程的MapReduceFlow,如果MapReduceFlow当前运行状态为NEW状态,则设置为RUNNING状态。也就是说,只要有一个子流程开始运行之后,即可认为整个ETL流程已经开始运行,后续其他子流程发送来的开始运行的通知可暂且忽略。其中,所述FlowMonitorBean包括流程运行状态、流程运行起始时间、流程消息(特别是异常消息),以及流程运行于container的host和port等属性。
(2)节点运行开始状态的通知:graph内部各节点开始运行后,通知监控端RPC服务节点开始运行,使得监控端获取节点的监控信息ActivityMonitorBean。
对于graph内部的任一节点,在监控端接收到该节点开始运行的通知后,将该节点的运行状态设置为ActivityState.RUNNING状态。进一步地,监控端获取该节点对应的MRActivityNodeMonitor以及发送通知的container对应的ContainerExecutor,并在MRActivityNodeMonitor的startedContainerList中增加该ContainerExecutor,表征当前节点在该ContainerExecutor已经启动运行,以便后续步骤302中监控端间隔刷新该节点的运行统计信息使用。其中,所述ActivityMonitorBean包括节点运行状态、节点运行起始时间、节点消息(特别是异常消息)、节点运行统计信息,以及节点运行于container的host和port等属性。
(3)节点运行结束状态的通知:graph内部各节点运行完成后,通知监控端RPC服务节点运行完成,使得监控端获取节点的监控信息ActivityMonitorBean。
监控端接收到任一节点运行完成的通知后,获取该节点对应的MRActivityNodeMonitor以及发送通知的container对应的ContainerExecutor,并在MRActivityNodeMonitor的finishedContainerMap中增加<ContainerExecutor,ActivityMonitorBean>,以便后续步骤302中监控端间隔刷新该节点的运行统计信息使用,以及当该节点在各container运行完成时,通过合并得到该节点总的运行统计信息。
其中,当containerCount=0时,MRActivityNodeMonitor通过mrWorkSourceReduceNodeMap以及MRWork获取containerCount,并将finishedContainerCount增加1后与containerCount比较;如果二者相等,则表明该节点对应的MRActivityNodeMonitor运行完成,该节点整体运行结束,此时合并MRActivityNodeMonitor的运行统计信息,即可得到该节点的运行统计信息ActivityMonitorStatsBean[]。
(4)流程运行结束状态的通知:graph运行完成后,通知监控端RPC服务对应的子流程运行完成,使得监控端获取流程的监控信息FlowMonitorBean。
此处可设置container对应的ContainerExecutor运行完成标志,监控端可合并处理mapper或reducer关于流程运行状态的实时通知,即合并处理每个container发送来的实时通知,当每个container对应的ContainerExecutor均运行完成后(即每个子流程运行完成后),则认为整个ETL流程运行完成。或者,当ETL流程中每个ActivityBean对应的MRActivityNodeMonitor均运行完成后,认为整个ETL流程运行完成。否则,只能是部分子流程运行完成。
步骤302,container启动时部署container RPC服务并向监控端注册ContainerExecutor,以便监控端间隔调用访问container RPC服务,进而间隔刷新container内部各节点的运行统计信息。
其中,监控端部署的container注册RPC服务接口定义如下:
public interface YarnContainerManagementService
{
registerContainer(longexecuteId,long mrWorkId,longmapSourceReduceNodeActivityId,String containerHostAdress,int containerport,long containerId);
}
Container向监控端注册时,通过executeID关联到MapReduceFlow,MapReduceFlow增加该container对应的ContainerExecutor。Container向监控端注册成功后,监控端才可间隔刷新container。
container中部署RPC服务可供监控端间隔刷新节点的运行统计信息ActivityMonitorStatsBean[],这里监控端通过获取节点在各container中的数据处理记录条数来得到节点的运行统计信息。其中,containerRPC服务的接口定义如下:
public interface FlowExecutorService
{
ActivityMonitorStatsBean[]refreshDataFlowStats(long executeId,longrefreshActivityIdList);
}
每个ETL流程具备唯一的ExecuteID(前面已经提到),且流程内部每个节点组件具备自己的ActivityID,则节点在各container中的数据处理记录条数的获取过程具体为:结合ExecuteID与ActivityID找到节点对应的DataFlowActivity,并通过访问DataFlowActivity获取对应节点的数据处理记录条数。其中,DataFlowActivity为ETL中节点数据处理运行的类,DataFlowActivity内部提供用于访问数据处理记录条数的接口,且DataFlowActivity为数据源节点、数据清洗转换节点或数据装载节点;数据源节点提供接口访问数据读取记录条数,数据清洗转换节点提供接口访问数据清洗转换记录条数,数据装载节点提供接口访问记录数据插入条数、数据更新条数和数据删除条数。ActivityMonitorStatsBean封装了所有这些统计信息。
通过MRActivityNodeMonitor以及监控端注册的ContainerExecutors,监控端间隔刷新各container中正在运行的节点,并获取节点间隔时间内在各container中的数据处理记录条数,通过合并统计得到运行中的节点的运行统计信息,即合并运行中的节点在各container中的数据处理记录条数,进而获取节点的实时运行速度;节点运行结束后,监控端通过合并节点在各container中的运行统计信息,即合并统计节点在各container中的数据处理记录条数,得到节点总的运行统计信息,进而获取流程节点的平均运行速度。
简而言之,在container开始运行之后,各组件节点的运行信息都会被加到对应的MRActivityNodeMonitor中,由MRActivityNodeMonitor统计对应组件节点的运行信息,监控端通过访问container即可获取各组件节点的运行信息,并且每隔预设时间段进行信息刷新。其中,对于运行已完成的container,对应的container RPC服务则已经关闭,监控端不能再访问;因此,在进行信息刷新时,运行完的container的信息已经保存在MRActivityNodeMonitor中,此时只刷新未运行完成(即运行中)的container的信息,合并统计节点在各个运行中的container中的信息即可。任一节点运行完成后,合并对应MRActivityNodeMonitor中的finishedContainerMap保存的信息,即可得到该节点的总运行统计信息和最终的平均运行速度。
本发明实施例提供的上述监控方法主要针对基于hadoop的分布式ETL框架而设计,分别在监控端和各container中部署RPC服务,container启动RPC服务后向监控端注册,使得监控端和container之间可以互相调用访问。如此一来,监控端不仅可实时获取流程运行状态以及流程内部各组件节点运行状态,监控运行中的ETL流程;还可获取container内部各节点活动的运行统计信息,从而准确地掌握流程运行速度,有效解决了分布式ETL框架中的流程监控和信息汇总的问题。
实施例4:
在上述实施例1和实施例2提供的hadoop集群运行ETL流程的方法的基础上,本发明还提供了一种可用于实现上述方法的hadoop集群运行ETL流程的装置,如图9所示,是本发明实施例的装置架构示意图。本实施例的hadoop集群运行ETL流程的装置包括一个或多个处理器21以及存储器22。其中,图9中以一个处理器21为例。
所述处理器21和所述存储器22可以通过总线或者其他方式连接,图9中以通过总线连接为例。
所述存储器22作为一种hadoop集群运行ETL流程的方法非易失性计算机可读存储介质,可用于存储非易失性软件程序、非易失性计算机可执行程序以及模块,如实施例1中的hadoop集群运行ETL流程的方法。所述处理器21通过运行存储在所述存储器22中的非易失性软件程序、指令以及模块,从而执行hadoop集群运行ETL流程的装置的各种功能应用以及数据处理,即实现实施例1和实施例2的hadoop集群运行ETL流程的方法。
所述存储器22可以包括高速随机存取存储器,还可以包括非易失性存储器,例如至少一个磁盘存储器件、闪存器件、或其他非易失性固态存储器件。在一些实施例中,所述存储器22可选包括相对于所述处理器21远程设置的存储器,这些远程存储器可以通过网络连接至所述处理器21。上述网络的实例包括但不限于互联网、企业内部网、局域网、移动通信网及其组合。
所述程序指令/模块存储在所述存储器22中,当被所述一个或者多个处理器21执行时,执行上述实施例1中的hadoop集群运行ETL流程的方法,例如,执行以上描述的图1所示的各个步骤。
本领域普通技术人员可以理解实施例的各种方法中的全部或部分步骤是可以通过程序来指令相关的硬件来完成,该程序可以存储于一计算机可读存储介质中,存储介质可以包括:只读存储器(ROM,Read Only Memory)、随机存取存储器(RAM,Random AccessMemory)、磁盘或光盘等。
以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。