一种Flink框架运行ETL的流程方法和装置与流程

文档序号:29791611发布日期:2022-04-23 17:47阅读:68来源:国知局
一种flink框架运行etl的流程方法和装置【
技术领域
:】1.本发明涉及数据处理
技术领域
:,特别是涉及一种flink框架运行etl的流程方法和装置。
背景技术
::2.etl是数据处理、构建数据仓库的一个重要工具软件,它完成异构数据源的抽取、清洗转换,然后加载的一个过程。传统的etl一般是把流程发布到一个集中的etl服务器节点上运行,所有的流程或流程内组件的运行采用多线程机制,再多的流程也只能在一个单一节点运行,并且一个大数据的处理流程,也无法提高数据处理的性能。3.flink大数据平台在大数据处理中已经取得相当广泛的应用,是一个分布式处理引擎框架,用于对无界和有界数据流进行有状态计算,具备极高的故障恢复性能和容错性能。4.如果etl流程能够提交到flink框架运行,可以极大提高流程并发执行能力,并且可以充分利用流式处理的有状态计算来提高流程运行稳定可靠性。5.由于flink提交任务需要构建一个sourcestream-》transformstream-》streamsink的操作,因此,现有技术中若要将etl流程直接在flink的sourcestream-》transformstream-》streamsink的操作中实现,必定会涉及重新实现数据处理逻辑代码,需要破坏etl流程的完整性。6.flink与kafka具有天然紧密联系,flink内置了比较完善的kafka读取与装载,并且利用有状态计算,能做到故障恢复的exactly-once。但是绝大部分etl组件实现在flink框架并没有提供支撑。比如关系数据库的表装载,需要支持插入更新、数据库连接connection重试、装载过程中出现报错数据的错误输出处理等等处理过程,在etl的表装载已经有很完善、高效率、很稳定的实现,如果把这部分实现代码重写到flink算子的processfunction或sinkfunction,一定会造成系统的代码冗余、维护繁杂、不稳定性。我们可以把某些组件的集合构造一个dag图,放在flink的processfunction中运行,不用在processfunction重写数据处理的代码。etl流程中的组件可以分为两类,一类是直接使用flink提供的算子实现,另一类就是完全使用etl的处理实现。不能把etl组件与flink算子一一对应来进行etl组件的数据处理。7.鉴于此,克服该现有技术所存在的缺陷是本
技术领域
:亟待解决的问题。技术实现要素:8.本发明要解决的技术问题是提供一种flink框架运行etl的流程方法。9.本发明进一步要解决的技术问题是提供一种flink框架运行etl的流程分解装置。10.本发明采用如下技术方案:11.第一方面,一种flink框架运行etl的流程分解方法和装置,流程分解方法包括:12.将etl组件分解,并构造etl组件分解后的有向无环图flinkfuncdag;13.etl组件分解后的子流程在flink算子的sourcefunction与processfunction中运行;flink的sourcefunction多任务并发读取数据源数据;flink的processfunction多任务并发处理数据。14.优选的,所述构造etl组件分解后的有向无环图flinkfuncdag,具体包括:15.etl增加内置虚拟组件messagecollector与processsource;16.所述messagecollector为flinkfuncdag的消息发送组件,通过flink算子的sourcecontext或collector发送转换后的消息到下一个flink算子;17.processsource为flinkfuncdag的数据源组件,上一个flink算子通过processelement或flatmap方法将所述消息推送给消息队列,processsource组件从消息队列读取上游算子发送的消息;18.flink算子的function内初始化并启动flinkfuncdag的运行,完成消息的转换处理。19.优选的,所述etl组件分解,具体包括:20.遍历etl的有向无环图dag,识别出一个或者多个splitting属性的节点;其中,所述splitting属性节点包括数据源节点、flink_message_shared_node属性的节点与需要转化为flink算子的节点中的一个或者多个;21.按照etl流程dag有向无环图节点先后顺序,从数据源节点开始,以相邻的两个所述splitting属性的节点作为依据,生成由相邻的两个所述splitting属性的节点之间的一个或者多个etl节点以及节点之间的连接线构成的etl流程子集,在flink算子中使用;构造这两个splitting属性的节点之间所对应的flinkapi语句操作算子链;22.其中,在生成所述子集过程中,为每一个所述etl流程子集分别构建type_flink_process_source节点用于接收上一个flink算子输出的数据集或者数据流,以及type_flink_process_sink节点用于将etl子流程转换处理后的数据发送给下一个flink算子;从而将etl的处理过程承载到flink框架中完成。23.优选的,所述etl组件分解后在flink的sourcefunction或者flink的processfunction中运行,具体包括:24.flink的sourcefunction通过run方法的参数sourcecontext将从数据源节点读取到的数据发送到下游子集的flink算子;processfunction通过processelement或flatmap方法将接收到的消息推送到消息队列,processsource组件从消息队列读取上游算子发送的消息,并在flinkfuncdag进行消息的转换处理,转换后的数据通过参数collector发送到下游子集的flink算子。25.优选的,所述flink的sourcefunction多任务并发读取数据源数据,具体包括:26.etl流程中包括至少一个数据源节点,所述etl流程中的数据源节点对应为flink的sourcefunction的类型包括有界流可分片数据源、有界流非并行数据源、无界流数据源与flinkconnector提供的sourcefunction实现数据源数据的读取,通过将数据源进行分片或分区,flink的sourcefunction多任务并发读取分片或分区后的数据源。27.优选的,所述的需要转化为flink算子的节点具体包括flink_reduce_node属性的节点与flink_connector_node属性的节点;28.搜索出etl流程中所有的需要转化为flink算子的节点,所述节点的上游一直到数据源节点的路由线设置为flink_message_shared_router属性。29.优选的,数据源节点开始,如果节点存在至少两个分支路由线,并且有至少两个分支路由线被设置为flink_message_shared_router属性,则所述节点为flink_message_shared_node属性的节点,设置flink_message_shared_node属性;30.其中需要转化为flink算子的节点不设置为flink_message_shared_node节点。31.优选的,遍历etl的有向无环图dag,识别出数据源节点、flink_reduce_node属性的节点与flink_connector_node属性的节点,并根据所述flink_reduce_node属性的节点与flink_connector_node属性的节点识别出所有flink_message_shared_node属性的节点,将所述数据源节点、flink_reduce_node属性的节点、flink_connector_node属性的节点与flink_message_shared_node属性的节点设置为splitting属性的节点;32.以相邻的两个所述splitting属性的节点作为依据,生成由相邻的两个所述splitting属性的节点之间的一个或者多个etl节点构成的子集。33.优选的,所述flink算子被调用时,构造所述etl流程子集的dag并运行;所述相邻splitting属性的节点之间构造一条flinkapi操作算子链,所述相邻splitting属性的节点中的前一个splitting属性的节点对应的flink算子的输出数据流或数据集作为所述flinkapi操作算子链的输入,所述flinkapi操作算子链的输入后续构造一个使用所述etl流程子集的flink算子。34.第二方面,一种flink框架运行etl的流程装置,其特征在于,flink框架运行etl的流程装置包括至少一个处理器,以及,与所述至少一个处理器通信连接的存储器;其中,所述存储器存储有可被所述至少一个处理器执行的指令,所述指令被所述处理器执行,用于所述的flink框架运行etl的流程方法。35.本发明专利就etl流程翻译转化成flink操作算子链提供了一种高效稳定便利方法。不用在操作算子function重新实现数据处理逻辑代码,不破坏流程的完整性,基本保存单服务器版etl流程原有的顺序性,并且与单服务器etldag运行逻辑一致,完全重用etl运行流程逻辑实现;既可以使用flink内置的算子提供的function或内置的connector提供的function,又可以完全使用etl组件进行数据的计算处理;任何etl流程都可以翻译转化成flink的操作算子链,提交给flink框架执行,具备通用便利性,完全避免flink算子中人工编写数据处理逻辑代码。【附图说明】36.为了更清楚地说明本发明实施例的技术方案,下面将对本发明实施例中所需要使用的附图作简单地介绍。显而易见地,下面所描述的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。37.图1是本发明实施例提供的一种flink框架运行etl的流程方法的方法流程图;38.图2是本发明实施例提供的一种flink框架运行etl的流程方法的流程示意图;39.图3是本发明实施例提供的一种flink框架运行etl的流程方法的etl流程的dag示意图;40.图4是本发明实施例提供的一种flink框架运行etl的流程方法flink框架下运行的dag示意图;41.图5是本发明实施例提供的一种flink框架运行etl的流程方法在flink框架下运行的dag示意图;42.图6是本发明实施例提供的一种flink框架运行etl的流程方法在flink框架下运行的dag示意图;43.图7是本发明实施例提供的一种flink框架运行etl的流程方法在flink框架下运行的dag示意图;44.图8是本发明实施例提供的一种flink框架运行etl的流程方法在flink框架下运行的dag示意图;45.图9是本发明实施例提供的一种flink框架运行etl的流程方法在flink框架下运行的dag示意图;46.图10是本发明实施例提供的一种flink框架运行etl的流程装置的装置示意图。【具体实施方式】47.为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。48.此外,下面所描述的本发明各个实施方式中所涉及到的技术特征只要彼此之间未构成冲突就可以相互组合。49.实施例1:50.本发明实施例1提供了一种flink框架运行etl的流程方法和装置。51.如图1所示,一种flink框架运行etl的流程方法,流程方法包括:52.步骤101中,将etl组件分解,并构造etl组件分解后的有向无环图flinkfuncdag;53.步骤102中,etl组件分解后的子流程在flink算子的sourcefunction与processfunction中运行;54.步骤103中,flink的sourcefunction多任务并发读取数据源数据;55.步骤104中,flink的processfunction多任务并发处理数据。56.将etl流程发布到flink框架运行,需要将etl流程的组件做合适拆分,拆分成多个子集,每个子集由一个或者多个etl节点构成,每个子集封装到flink操作算子执行;etl组件构成dag图,在sourcefunction与processfunction中运行,其中,etl的数据源读取放到自定义sourcefunction中运行或者flink的sourcefunction,etl的清洗转换组件放到processfunction中运行,kafka装载可直接使用flink自带的flinkkafkaproducer。57.本发明把etl组件的集合构造一个dag图,放在flink的processfunction中运行,不用在processfunction重写数据处理的代码,避免把代码重写到flink算子的processfunction或sinkfunction,从而导致系统的代码冗余、维护繁杂、不稳定性。58.在本发明中,需要将etl组件的集合构造一个dag图,放在flink中运行,因此存在以下优选方法:59.etl增加内置虚拟组件messagecollector与processsource;60.所述messagecollector为flinkfuncdag的消息发送组件,通过flink算子的sourcecontext或collector发送转换后的消息到下一个flink算子;61.processsource为flinkfuncdag的数据源组件,上一个flink算子通过processelement或flatmap方法将所述消息推送给消息队列,processsource组件从消息队列读取上游算子发送的消息;62.flink算子的function内初始化并启动flinkfuncdag的运行,完成消息的转换处理。63.flinkfuncdag在flink中运行时,所述sourcefunction中的flinkfuncdag运行于run方法,数据源分片或分区的flinkfuncdag同步运行完毕,获取下一个分片或分区,重新构造flinkfuncdag运行;processfunction中的flinkfuncdag在processfunction初始化后异步运行,flinkfuncdag流程数据源读取processelement传入的数据。64.遍历etl的有向无环图dag,识别出一个或者多个splitting属性的节点;其中,所述splitting属性节点包括数据源节点、flink_message_shared_node属性的节点与需要转化为flink算子的节点中的一个或者多个;65.etl流程中数据源节点为流程的起始节点,存在一个输出,没有输入,使用flink的sourcefunction生成数据供后续算子作为输入使用,其中所述数据包括dataset或datastream,也就是数据集或数据流;66.etl流程中的消息分享节点为定义为flink_message_shared_node属性的节点,所述节点转换为flinkapi操作算子时存在一个输入与一个输出,所述消息分享节点的后续节点存在至少两个节点需要转化为flink算子;67.etl流程中的缩减节点为定义为flink_reduce_node属性的节点,所述节点转换为flinkapi操作算子时存在一个或者多个输入与一个输出;68.etl流程中的连接节点为定义为flink_connector_node属性的节点,所述节点转换为flinkapi操作算子时存在一个输入,所述节点运行处理数据后直接进行装载;69.所述消息分享节点、连接节点和缩减节点都是接收上一个节点的输出数据后,生成一个新的输出数据,输出给后续算子。70.由于在以flink框架运行etl流程的方法中,需要根据etl组件节点集合构造flinkapi语句,而一条flinkapi语句使用一个或多个输入,一个输出,需要将两个flink_splitting_node之间组件集合运行在flink算子里面,因此存在以下优选方案:71.将所述消息分享节点、连接节点与缩减节点均定义为flink_splitting_node属性的节点。72.根据相邻的splitting属性的节点之间的etl节点集合,构造flinkapi语句,优选的:73.按照etl流程dag有向无环图节点先后顺序,从数据源节点开始,以相邻的两个所述splitting属性的节点作为依据,生成由相邻的两个所述splitting属性的节点之间的一个或者多个etl节点以及节点之间的连接线构成的etl流程子集,在flink算子中使用;构造所述两个相邻splitting属性的节点之间所对应的flinkapi语句操作算子链;74.从数据源节点开始每一个分支搜索下一个splitting属性的节点,如果所述splitting属性的节点为空,则从上一轮搜索开始中间搜索到的所有节点以及节点之间的路由线构成组成一个集合,将所述集合在一个flink算子processfunction中运行;如果所述搜索到的splitting属性的节点不为空,则从上一轮搜索开始中间搜索到的所有节点以及节点之间的路由线构成组成一个集合,将所述集合在一个flink算子processfunction中运行,然后作为splittingnode算子的输入。75.其中,在生成所述子集过程中,为每一个所述etl流程子集分别构建type_flink_process_source节点用于接收上一个flink算子输出的数据集或者数据流,以及type_flink_process_sink节点用于将etl流程子集转换处理后的数据发送给下一个flink算子;从而将etl的处理过程承载到flink框架中完成。76.优选的,所述type_flink_process_source节点为flink算子processfunction,所述flink算子processfunction的输入为上一个flink算子的输出,所述flink算子processfunction的输出为下一个子集中flink算子processfunction的输入或者etl输出节点,其中flink算子为splittingnode算子,按照上述步骤处理各个splittingnode算子,从而将etl的处理过程承载到flink框架中完成。77.其中消息从上游子集的flink算子发送给下游子集的flink算子的数据处理过程具体为:78.flink的sourcefunction通过run方法的参数sourcecontext将从数据源节点读取到的数据发送到下游子集的flink算子;processfunction通过processelement或flatmap方法将接收到的消息推送到消息队列,processsource组件从消息队列读取上游算子发送的消息,并在flinkfuncdag进行消息的转换处理,转换后的数据通过参数collector发送到下游子集的flink算子。79.通过数据源分片或分区方式,flink的sourcefunction多任务并发读取数据源,可以极大提高etl流程并发处理能力,因此,还涉及以下优选方法:80.etl流程中包括至少一个数据源节点,所述etl流程中的数据源节点对应为flink的sourcefunction的类型包括有界流可分片数据源、有界流非并行数据源、无界流数据源与flinkconnector提供的sourcefunction实现数据源数据的读取,通过将数据源进行分片或分区,flink的sourcefunction多任务并发读取分片或分区后的数据源。81.所述etl流程中的数据源节点对应为flink的sourcefunction的类型不同时的情况具体如下:82.所述数据源为有界流可分片数据源时,自定义boundedstreamsourcefunction派生自flink的inputformatsourcefunction;自定义boundedstreamsourceinputformat派生自flink的richinputformat;boundedstreamsourceinputformat重写createinputsplits方法,实现数据源的分片,供boundedstreamsourcefunction算子子任务使用;boundedstreamsourcefunction重写run方法,获取分片split,然后进行数据源的分片所对应的部分数据读取操作,发送给下游算子。83.所述数据源为有界流非并行数据源时,仅存在一个任务读取数据;自定义nonparallelsourcefunction派生自flink的richsourcefunction,重写run方法。84.所述数据源为无界流数据源:自定义unboundedstreamfunction派生自flink的richparallelsourcefunction,重写run方法,获取数据源数据,然后发送给下游算子。85.所述flinkconnector提供的sourcefunction实现数据源数据读取时,存在多任务分区并发读取,可直接使用。86.由于需要遍历etl的有向无环图dag,确定出一个或者多个splitting属性的节点,但所述识别splitting属性的节点的流程中,仅能识别出flink的算子的节点,而所述flink_message_shared_node属性的节点并非flink算子的节点,因此需要设置出flink_message_shared_node属性的节点,存在以下优选方法:87.如图2所示,flink框架运行etl的流程分解流程如下:88.步骤201中,遍历etl的dag,识别出数据源节点与flink算子的节点;89.步骤202中,所述识别出来的flink算子的节点的上游一直到数据源节点的路由线设置为flink_message_shared_router属性;90.所述flink算子的节点具体包括flink_reduce_node属性的节点与flink_connector_node属性的节点91.步骤203中,数据源节点开始,如果存在节点存在至少两个分支路由线,并且有至少两个分支路由线被设置为flink_message_shared_router属性,则所述节点为flink_message_shared_node属性的节点,设置flink_message_shared_node属性。92.步骤204中,将数据源节点、flink算子的节点以及flinkmessagesharednode属性的节点定义为splitting属性的节点;93.步骤205中,识别出所有flink_message_shared_node属性的节点,则确定出etl的有向无环图dag中所有splitting属性的节点,以相邻的所述splitting属性的节点作为依据,生成由相邻的所述splitting属性的节点之间的一个或者多个etl节点以及节点之间的连接线构成的etl流程子集,所述etl流程子集在flink算子中使用。94.所述flink算子被调用时,构造所述etl流程子集的dag并运行;所述相邻splitting属性的节点之间构造一条flinkapi操作算子链,所述相邻splitting属性的节点中的前一个splitting属性的节点对应的flink算子的输出数据流或数据集作为所述flinkapi操作算子链的输入,所述flinkapi操作算子链的输入后续构造一个使用所述etl流程子集的flink算子。95.其中所述flink算子为flatmap算子或者transform算子。96.当所述相邻splitting属性的节点中的后一个splitting属性的节点为flink_message_shared_node属性的节点时,所述后一个splitting属性的节点不转化为对应的flink算子;97.当所述相邻splitting属性的节点中的后一个splitting属性的节点不为flink_message_shared_node属性的节点时,所述后一个splitting属性的节点需要转化为对应的flink算子,所述flink算子输入为两个相邻splitting属性的节点之间etl流程子集的flink算子的输出。98.其中所述与splitting属性的节点对应的flink算子为:kafka装载节点对应kafkasink算子;排序组件对应flink的sortpartitionoperator算子;连接组件与增量比对组件对应flink的cogroupoperator算子;聚合组件对应flink的groupreduceopetator算子;上述flink算子的输入为使用etl流程子集的flatmap算子或transform算子的输出。99.步骤206中,在生成所述子集过程中,为每一个所述子集分别构建type_flink_process_source节点用于接收上一个flink算子输出的数据集或者数据流,以及type_flink_process_sink节点用于将作为子集的自己输出的数据集或者数据流传递给下一个子集或者etl输出节点;从而将etl的处理过程承载到flink框架中完成。100.所述flink_reduce_node属性的节点对上游接收的数据进行缓存,然后进行数据处理,输出结果;而etl流程中非reduce节点对接收的仅一条数据进行计算处理,然后对下游输出处理后的数据;101.所述flink_connector_node属性的节点使用flink提供的connector,已封装完善了数据的读取与装载;102.由于所述flink算子存在输出为数据集或者数据流两种情况,因此,本发明还存在以下优选设计:103.在所述flink算子输出的是数据集时,相应etl流程子集在flatmap算子的函数etldatasetprocessfunction中处理,所述方法还包括:104.所述etldatasetprocessfunction派生于flink的richflatmapfunction;重定义richflatmapfunction的flatmap函数功能,所述richflatmapfunction接收一条数据消息message后,直接通过消息队列存取的方式发送给所述etldatasetprocessfunction在open函数初始化并启动的etl流程子集运行中的数据源节点type_flink_process_source组件,然后由etl流程子集进行计算处理,由所述etl流程子集的type_flink_process_sink组件调用collector函数发送给下一个flink算子;105.其中,所述数据消息message为etl组件之间传递的数据封装对象。106.优选的,所述数据集对象为数据源节点type_flink_process_source与数据源节点type_flink_process_sink,所述数据源节点type_flink_process_source接收上一个子集的输出数据集,所述数据源节点type_flink_process_sink将经过转换生成的数据发送给下一个子集;其中,所述子集在flink的flatmap算子的richflatmapfunction代码中使用,所述richflatmapfunction代码的定义由本领域技术人员自行设计。107.在所述flink算子输出的是数据流类型,所述etl流程子集在transform算子的etlprocessfunction中处理,方法具体包括:108.所述etlprocessfunction派生于flink的processfunction;重定义processfunction的processelement函数功能,所述processfunction接收一条数据消息message后,直接通过消息队列存取的方式发送给所述etlprocessfunction在open函数初始化并启动的etl流程子集运行中的数据源节点type_flink_process_source组件,然后由etl流程子集进行计算处理,由所述etl流程子集的type_flink_process_sink组件调用collector函数发送给下一个flink算子;109.其中,所述数据消息message为etl组件之间传递的数据封装对象。110.原本flink提供的processfunction是通过processelement函数接受一个消息数据message,然后经过计算处理,通过参数collector发送给下一个算子;本方法中所述processfunction仅仅接收一条数据消息message,然后直接通过消息队列存取的方式发送给该etlprocessfunction在open初始化启动的etl子流程运行中的数据源节点type_flink_process_source,由所述etl子流程进行计算处理,所述子流程的type_flink_process_sink节点调用collector发送给下一个子集的算子。111.由于需要生成由相邻的所述splitting属性的节点之间的一个或者多个etl节点构成的子集,但在etl的有向无环图dag中遍历找到一个splitting属性的节点,存在所述splitting属性的节点之后仅包含非splitting属性的节点的情况,因此还存在以下优选方法:112.位于所述splitting属性的节点后的非splitting属性的节点构成的一个子集;其中,所述子集无后续splitting属性的节点,不用输出数据集或者数据流供后续flink算子使用;113.为所述子集构造一个type_flink_process_source节点接收上一个算子的输出数据,对于所述子集不构造type_flink_process_sink节点。114.所述找到的splitting属性的节点后续无splittingnode时,后续所有节点以及节点之间的路由线构成的一个组件子集,由于无后续splittingnode,不用输出数据集供后续算子使用,所以这个子集只需构造一个数据源节点type_flink_process_source接收上一个算子的输出数据集,同样,所述子集在flink的flatmap算子的richflatmapfunction代码使用;其中,所述richflatmapfunction代码的定义由本领域技术人员自行设计。115.对于子集构造一个数据源节点type_flink_process_source接收上一个算子的输出数据集,对于所述子集不构造type_flink_process_sink节点情况,相应的flink架构采用api算子etldatasetprocessfunction运行,则方法具体包括:116.在flink中richflatmapfunction基础上衍生etldatasetprocessfunction函数,所述etldatasetprocessfunction函数调用flatmap函数,所述flatmap函数仅仅接收一条数据消息message后,直接通过消息队列存取的方式发送给所述etldatasetprocessfunction在open初始化启动的etl子集流程运行中的数据源节点type_flink_process_source组件后,由etl子集流程进行计算处理,由该子流程的type_flink_process_sink组件调用collector发送给下一个子集;117.其中,所述数据消息message为输出数据集在数据流传输模式下的输出给下一子集的数据形式。118.原本flink提供的richflatmapfunction是通过flatmap算子接受一个消息数据message,然后经过计算处理,通过参数collector发送给下一个子集的算子;而在本方法中所述flatmap算子只接收一条数据消息message,通过消息队列存取的方式发送给所述function在open初始化启动的etl子流程运行中的数据源节点type_flink_process_source组件,由etl子流程进行计算处理,由所述子流程的type_flink_process_sink组件调用collector发送给下一个算子;所述flatmap算子的etldatasetprocessfunction实现flink的richflatmapfunction接口,具体如下:[0119][0120]实施例2:[0121]本发明实施例2提供了一种flink框架运行etl的流程方法,本实施例2相比实施例1在更加实际的场景下来展现本方案的实施流程。[0122]如图3所示,本实施例中etl流程存在一个数据源节点、三个转换节点与两个转载节点。[0123]其中etl流程里面的节点以及节点之间的路由线构造dag有向无环图;[0124]数据源节点读取数据并发送到后续转换节点1;[0125]转换节点1读取数据并运行完成后发送给后续转换节点2与转换节点3;[0126]转换节点2与转换节点3读取数据并运行完成后分别发送给转载节点1与转载节点2;[0127]转载节点1与转载节点2对接收到的数据完成装载,流程运行完毕。[0128]如图4所示,流程提交到flink执行,需要构造flink操作算子链,flink操作算子为:[0129]streamexecutionenvironmentenv=[0130]streamexecutionenvironment.getexecutionenvironment();[0131]datastreamtransform1datastream=[0132]env.addsource(source).process(transform1);[0133]transform1datastream.process(transform2).addsink(sink1);[0134]transform1datastream.process(transform3).addsink(sink2);[0135]env.execute();[0136]source算子执行该source的sourcefunction,读取数据以数据流的形式发送到后续算子。[0137]transform1、transform2、transform3各自接收到对应数据后,transform1、transform2、transform3的processfunction执行各自的数据转换,生成新的数据流发送到后续节点;[0138]其中,transform1生成的数据流作为transform2、transform3数据流源头共享使用。[0139]transform2与transform3生成的数据流发送到后续的sink算子,装载写入相应的目的。[0140]基于datastream的flink的sourcefunction一般通过run方法的参数sourcecontext把读取到的数据发送到下游flink算子;本发明在flink的sourcefunction内部构造组件集合的dag有向无环图flinkfuncdag;etl的读取组件为flinkfuncdag的数据源读取组件,读取组件后续连接一个数据转发节点messagecollector作为flinkfuncdag的消息发送组件,所述发送组件使用sourcecontext发送消息到下游flink算子;所述flink框架中数据读取完全使用etl的读取组件代码,不用重新编写实现数据读取逻辑代码。[0141]boundedstreamsourceinputformatextendsrichinputformat《message,inputsplit》[0142]{[0143]publicinputsplit[]createinputsplits(intminnumsplits)[0144]{[0145][0146]splititerator为boundedstreamsourceinputformat的createinputsplits得到的数据源分片的迭代器;所述各个数据读取任务创建自己的splititerator,迭代获取split。[0147]所述run函数中,构造分片split对应的flinkfuncdag,flinkfuncdag由两个组件数据读取组件、messagecollector组件以及这两个组件的连接线组成;同步运行flinkfuncdag,此流程运行完毕,该分片数据读取发送完毕,再继续处理下一个split;数据读取组件读取分片split的数据,发送到后续组件messagecollector,messagecollector收到上游组件数据后,通过sourcecontext发送给后续算子。[0148]datastream流式数据读取,除了可以自定义sourcefunction,flink框架还提供的操作算子kafkaconnector实现了kafka读写功能,通过有状态计算,实现exactly-once语义;etlkafka读取、装载翻译转化成kafkaconnector算子提供的flinkkafkaconsumer、flinkkafkaproducer,能够保障etl流程运行的稳定可靠性。[0149]基于数据集dataset方式读取etl中数据源节点时数据源时,一般[0150]自定义boundedstreamsourceinputformat派生自flink的richinputformat。[0151][0152]customsoureinputformat的open函数中,初始化messagequeue,构造参数split对应的flinkfuncdag并启动flinkfuncdag异步运行;所述flinkfuncdag由一个数据读取组件、messagecollector组成;数据读取组件与数据流sourcefunction中的处理方式一致,完全重用etl读取组件代码;所述messagecollector接收到读取组件数据后,向消息队列messagequeue中推送数据消息message,供customsoureinputformat的reachedend()从messagequeue中获取message;flink框架调用customsoureinputformat的nextrecord获取message,发送到后续算子。[0153]通过数据源分片或分区方式,flinksourcefunction设置parallelism并行度,多任务并发读取数据源,可以极大提高etl流程并发处理能力;有界可分片数据源的每个任务并发从inputformat的createinputsplits得到的分片中获取split进行读取。无界流数据源比如kafka,多分区并发读取提高数据读取效率。[0154]实施例3:[0155]本发明实施例3提供了一种flink框架运行etl的流程方法,本实施例3相比实施例1在更加实际场景下来展现本方案的实施流程。[0156]如图5所示,本发明实施例是在只有一个数据源节点、无flink_reduce_node节点、无flink_connector_node节点的情况下的etl流程分解,由于本流程中无缩减节点与连接节点,因此无flink_message_shared_nod节点。[0157]source算子执行该source的sourcefunction,读取数据以数据流的形式发送到后续算子。[0158]transform1接收到对应数据后,transform1的processfunction执行数据转换,生成新的数据流发送给后续节点;[0159]transform1生成的数据流发送到后续的sink算子,装载写入相应的目的。[0160]生成算子语句如下:[0161]streamexecutionenvironmentenv=[0162]streamexecutionenvironment.getexecutionenvironment();[0163]env.addsource(sourcefunction).process(processfunction);[0164]数据源独立在sourcefunction中运行,数据源后续所有的节点都在processfunction运行,其中算子api不存在sink。[0165]实施例4:[0166]本发明实施例4提供了一种flink框架运行etl的流程方法,本实施例4相比实施例1在更加实际的场景下来展现本方案的实施流程。[0167]如图6所示,本发明实施例是在同时存在flink_reduce_node节点、flink_message_shared_node节点的情况下的etl流程分解。[0168]其中,sort1与sort2节点为flink_reduce_node节点;transform1为flink_message_shared_node节点。[0169]其中,transform2为flink_message_shared_nod节点;sort1与排sort2组件为flink_reduce_node节点。[0170]source算子执行该source的sourcefunction,读取数据以数据流的形式发送到后续算子。[0171]transform1与transform2各自接收到对应数据后,transform1与transform2的processfunction执行各自的数据转换,生成新的数据流发送到后续节点;[0172]sort1与sort2各自接收到对应数据后,sort1与sort2的sortfunction执行各自的数据转换,生成新的数据流发送到后续节点;[0173]sort1与sort2生成的数据流发送到后续的sink1与sink2的算子,装载写入相应的目的。[0174]实施例5:[0175]本发明实施例5提供了一种flink框架运行etl的流程方法,本实施例5相比实施例1在更加实际的场景下来展现本方案的实施流程。[0176]如图7所示,本发明实施例是在同时存在flink_connector_node节点、flink_message_shared_node节点的情况下的etl流程分解。[0177]其中kafkasink1、kafkasink2、tablesink3为flink_connector_node;transform1是flink_message_shared_node节点。[0178]source算子执行该source的sourcefunction,读取数据以数据流的形式发送到后续算子。[0179]transform1、transform2、transform3与transform4各自接收到对应数据后,transform1、transform2、transform3与transform4的processfunction执行各自的数据转换,生成新的数据流发送到后续节点;[0180]其中,transform1生成的数据流作为transform2、transform3与transform4数据流源头共享使用。[0181]transform2、transform3与transform4生成的数据流发送到后续的sink算子,装载写入相应的目的。[0182]生成算子语句如下:[0183]streamexecutionenvironmentenv=[0184]streamexecutionenvironment.getexecutionenvironment();[0185]datastreamtransform1datastream=[0186]env.addsource(kafkasourcefunction).process(processfunction1);[0187]transform1datastream.process(processfunction2).addsink(kafkasink1);[0188]transform1datastream.process(processfunction3).addsink(kafkasink2);[0189]其中,processfunction1、processfunction2与processfunction3具体如下:[0190]processfunction1由transform1构造dag来运行;[0191]processfunction2由transform2构造dag来运行;[0192]processfunction3由transform3、transform4、tablesink2以及它们的路由线构造dag来运行;[0193]实施例6:[0194]本发明实施例6提供了一种flink框架运行etl的流程方法,本实施例6相比实施例1为在flink算子输出的是数据集具体的情景来展现本方案的实施流程。[0195]如图8所示,其中,tablesource为数据源节点;transform3为flink_message_shared_node节点;fliesink1与fliesink2为flink_connector_node节点。[0196]tablesource算子执行所述source的sourcefunction,读取数据以数据流的形式发送到后续算子。[0197]transform1、transform2、transform3、transform4、transform5、transform6与transform7各自接收到对应数据后,transform1、transform2、transform3、transform4、transform5、transform6与transform7的processfunction执行各自的数据转换,生成新的数据流发送到后续节点;[0198]其中,transform3生成的数据流作为transform4与transform6数据流源头共享使用。[0199]sort1与sort2生成的数据流发送到后续的fliesink1与fliesink2的sink算子,装载写入相应的目的。[0200]tablesource与transform3之间的组件子集为transform1、transform2、transform3以及它们之间的路由线;所述子集运行的etl子流程必须从tablesource算子的输出数据集接收数据,经过transform3转换后,输出数据集供后续算子使用;所述子集构造一个数据集对象type_flink_process_source接收上一个算子的输出数据集,以及一个数据集对象type_flink_process_sink发送数据到下一个算子;所述子集在flink的flatmap算子的richflatmapfunction代码使用,定义为transformcollection1-2-3,完成tablesource与transform3之间的组件翻译转化。[0201]transform3与sort1之间的组件集合为transform4、transform5以及transform3与sort1之间的组件的路由线;所述子集运行的etl子流程从上一个算子接收数据,经过transform5转换后,输出数据集供后续算子sort1使用。所述子集构造一个数据集对象type_flink_process_source接收上一个算子的输出数据集,以及一个数据集对象type_flink_process_sink发送数据集到下一个算子;所述子集在flink的flatmap算子的richflatmapfunction代码使用,定义为transformcollection4-5,所述flatmap算子后续跟上sort算子,transform3与sort1之间的组件翻译转化完成。[0202]sort1节点后续无splittingnode,后续所有节点以及节点之间的路由线构成的一个组件子集,定义为transformfilesinkcollection1;由于无后续splittingnode,不用输出数据集供后续算子使用,因此所述子集只构造一个数据源节点type_flink_process_source接收上一个算子的输出数据集,无需构建发送节点type_flink_process_sink,所述子集在flink的flatmap算子的richflatmapfunction代码使用。[0203]transform3与sort2之间的组件集合由transform6、transform7以及transform3与sort2之间的组件的路由线构成;所述子集运行的etl子流程从上一个算子的输出数据集接收数据,经过transform7转换后,输出数据集供后续算子sort使用;因此所述子集还必须构造一个数据源节点type_flink_process_source接收上一个算子的输出数据集,以及一个数据集发送节点type_flink_process_sink发送数据到下一个算子;所述子集在flink的flatmap算子的richflatmapfunction代码使用,定义为transformcollection6-7,完成transform3与sort2之间的组件翻译转化。[0204]所述sort2节点后续无splittingnode,后续所有节点以及节点之间的路由线构成的一个组件子集;定义为transformfilesinkcollection2;由于无后续splittingnode,不用输出数据集供后续算子使用,因此所述子集只需构造一个数据源节点type_flink_process_source接收上一个算子的输出数据集,无需构建发送节点type_flink_process_sink;所述子集在flink的flatmap算子的richflatmapfunction代码使用。[0205]具体如下:[0206]executionenvironmentenv=[0207]executionenvironment.getexecutionenvironment();[0208]datasetsourcedataset=env.createinput(newtablesourceinputformat(tablesource));[0209]etldatasetprocessfunctionfunction=newetldatasetprocessfunction(transformcollection1-2-3);[0210]datastreant3dataset=sourcedataset.flatmap(function).returns(messagetypeinfo);[0211]etldatasetprocessfunctionfunction4-5=newetldatasetprocessfunction(transformcollection4-5);[0212]datasett5dataset=t3dataset.flatmap(function4-5).returns(messagetypeinfo).;[0213]datasetsor1dataset=newsortpartitionoperator(t5dataset,newselectorfunctionkeys(sort1));[0214]etldatasetprocessfunctionfunctionfilesink1=newetldatasetprocessfunction(transformfilesinkcollection1);[0215]sor1dataset.flatmap(functionfilesink1).returns(messagetypeinfo).;[0216]etldatasetprocessfunctionfunction6-7=newetldatasetprocessfunction(transformcollection6-7);[0217]datasett7dataset=t3dataset.flatmap(function6-7).returns(messagetypeinfo).;[0218]datasetsor2dataset=newsortpartitionoperator(t7dataset,newselectorfunctionkeys(sort2));[0219]etldatasetprocessfunctionfunctionfilesink2=newetldatasetprocessfunction(transformfilesinkcollection2);[0220]sor2dataset.[0221]flatmap(functionfilesink2).returns(messagetypeinfo).;[0222]所述flatmap算子的etldatasetprocessfunction实现flink的richflatmapfunction接口,具体如下[0223][0224]并发度设置具体如下:[0225]操作算子通过设置并行度parallelism,操作算子任务可并发运行同一个或不同的nodemanager,极大提高并发计算处理能力;flink根据具体的操作算子以及操作算子的并行度,把多个操作算子组成一个链chain在一个子任务中运行,避开算子之间子任务传递数据消息的序列化和反序列化;上述api语句得到的dataset设置相同的并行度,sourcedataset、t3dataset以及t5dataset、t7dataset操作设置相同的并行度parallelism,数据源以及数据源的后续算子运行在一个子任务,算子之间数据传递无需消息的序列化和反序列化;排序算子设置parallelism为1。[0226]数据集数据源的读取自定义inputformat实现richinputformat;实现createinputsplits实现数据源的分片;open函数中启动分片数据源的读取流程,读取数据发送给用作缓冲的消息队列;实现reachend()函数、nextrecord()函数,从消息队列接收数据;flink框架在调用reachend()以及nextrecord()函数后,如果未读完,读取数据发送给后续算子处理;数据集api读取数据源的方式与数据流api存在很大的差别,数据集api需要自定义实现flink的sourcefunction。[0227]上述flatmap算子的etldatasetprocessfunction实现flink的richflatmapfunction接口,具体如下:[0228][0229][0230]原本flink提供的richflatmapfunction是通过flatmap接受一个消息数据message,经过计算处理,通过参数collector发送给下一个算子;[0231]本发明专利实现的flatmap函数仅接收一条数据消息message,然后推送到消息队列messagequeue,不做转换计算处理;在open函数内部构造组件集合transformcollection的dag有向无环图flinkfuncdag,并异步启动flinkfuncdag运行;流程中数据源节点类型为type_flink_process_source的processsource组件从消息队列messagequeue接收数据message,然后发送给下游组件,etl子流程内部进行一系列的转换计算处理;如果flinkfuncdag存在类型为type_flink_process_sink的messagecollector组件,该组件从上游组件接收数据,然后调用collector发送消息message给下一个算子。[0232]实施例7:[0233]本发明实施例7提供了一种flink框架运行etl的流程方法,本实施例7相比实施例1为在flink算子输出的是数据流具体的情景来展现本方案的实施流程。[0234]如图9所示,其中:kafkasource为数据源节点;transform3为flink_message_shared_node节点;kafkasink1、kafkasink2、tablesink为flink_connector_node节点。[0235]source算子执行所述source的sourcefunction,读取数据以数据流的形式发送到后续算子。[0236]transform1、transform2、transform3、transform4、transform5、transform6、transform7、transform8与transform9各自接收到对应数据后,transform1、transform2、transform3、transform4、transform5、transform6、transform7、transform8与transform9的processfunction执行各自的数据转换,生成新的数据流发送到后续节点;[0237]其中,transform3生成的数据流作为transform4、transform6与transform8数据流源头共享使用。[0238]transform5、transform7与transform9生成的数据流发送到后续的sink算子,装载写入相应的目的。[0239]具体的,kafkasource节点、transform3节点、kafkasink1节点与kafkasink2节点为splitting属性的节点;两个splitting属性的节点之间的一个或者多个etl节点以及节点之间的路由线构成的流程组件子集,所述集合在一个flink算子processfunction中运行,然后作为splittingnode算子的输入。[0240]其中,kafkasource节点与transform3节点之间的子集为transform1节点、transform2节点、transform3节点以及它们之间的路由线;所述子集运行etl子流程接收从kafkasource算子输出的数据流,经过作为splitting属性的节点的transform3节点的转换后,transform3节点将数据流输出给下一个子集的算子;因此为了所述transform3节点所在的子集能够接收所述数据流,所述子集构造一个数据集对象type_flink_process_source用于接收上一个算子的数据流,以及所述数据集对象type_flink_process_sink将接收到的数据流发送给下一个子集的算子;所述子集transform1节点、transform2节点与transform3节点在flink的transform算子的processfunction代码使用,定义为transformcollection1-2-3,完成kafkasource与transform3之间的节点翻译转化。[0241]transform3节点与kafkasink1节点之间的子集为transform4节点、transform5节点以及transform3节点与kafkasink1节点之间的各个节点间的路由线;所述子集运行的etl子流程接收从上一个算子输出的数据流,经过作为splitting属性的节点的transform5节点的转换后,transform5节点将数据流输出给下一个子集的算子;因此为了所述transform5节点所在的子集能够接收所述数据流,所述子集构造一个数据集对象type_flink_process_source用于接收上一个算子的数据流,以及所述数据集对象type_flink_process_source将接收到的数据流发送给下一个子集的算子;所述子集transform4节点与transform5节点在flink的transform算子的processfunction代码使用,定义为transformcollection4-5,完成kafkasink1与transform3之间的节点翻译转化。[0242]tablesink节点为表数据装载,所述tablesink节点不使用flink的sink算子,在transform3节点与kafkasink2节点之间的节点集合中使用;这个集合由transform6节点、transform7节点、transform8节点、transform9节点、tablesink节点以及transform3节点与kafkasink2节点之间的组件的路由线构成;所述子集运行的etl子流程接收从上一个子集的算子输出的数据流,经过作为splitting属性的节点的transform7节点的转换后,transform7节点将数据流输出给下一个子集的算子;因此为了所述transform7节点所在的子集能够接收所述数据流,所述子集构造一个数据集对象type_flink_process_source用于接收上一个算子的数据流,以及所述数据集对象type_flink_process_sink将接收到的数据流发送给下一个子集的算子;所述子集transform6节点、transform7节点、transform8节点、transform9节点与tablesink节点在flink的transform算子的processfunction代码使用,定义为transformcollection6-9,完成kafkasink2与transform3之间的节点翻译转化。[0243]其中transform算子的etlprocessfunction具体如下:[0244]streamexecutionenvironmentenv=[0245]streamexecutionenvironment.getexecutionenvironment();[0246]datastreamsourcestream=env.addsource(newflinkkafkaconsumer(kafkasource));[0247]etlprocessfunctionfunction=newetlprocessfunction(transformcollection1-2-3);[0248]processoperatoroperator=newprocessoperator(function);[0249]datastreant3stream=sourcestream.transform(“process”,messagetypeinfo,operator);[0250]etlprocessfunctionfunction4-5=newetlprocessfunction(transformcollection4-5);[0251]processoperatoroperator4-5=newprocessoperator(function4-5);[0252]t3stream.transform(“process”,messagetypeinfo,operator4-5).addsink(newflinkkafkaproducer(kafkasink1));[0253]etlprocessfunctionfunction6-9=newetlprocessfunction(transformcollection6-9);[0254]processoperatoroperator6-9=newprocessoperator(function6-9);[0255]t3stream.transform(“process”,messagetypeinfo,operator6-9).addsink(newflinkkafkaproducer(kafkasink2));[0256]上述transform算子的etlprocessfunction实现flinkprocessfunction接口,具体如下:[0257][0258][0259]并发度设置具体如下:[0260]操作算子通过设置并行度parallelism,操作算子任务可并发运行同一个或不同的nodemanager,极大提高并发计算处理能力;flink根据具体的操作算子以及操作算子的并行度,把多个操作算子组成一个链chain在一个子任务中运行,避开算子之间子任务传递数据消息的序列化和反序列化;上述api语句得到的datastream设置相同的并行度,sourcestream、t3stream以及最后的addsink操作设置相同的并行度parallism,数据源以及数据源的后续算子运行在一个子任务,算子之间数据传递无需消息的序列化和反序列化。[0261]上述transform算子的etlprocessfunction实现flinkprocessfunction接口,具体如下:[0262][0263]所述flink的processfunction通过processelement接受一个消息数据message,经过计算处理,通过参数collector发送给下一个算子;[0264]本发明专利实现flink框架processfunction的processelement函数中,仅接收一条数据消息message,推送到消息队列messagequeue。etlprocessfunction在open函数内部构造组件集合transformcollection的dag有向无环图flinkfuncdag,并异步启动flinkfuncdag运行;流程中数据源节点类型为type_flink_process_source的processsource组件从消息队列messagequeue接收数据message,发送给下游组件,etl子流程内部进行转换计算处理;如果flinkfuncdag存在类型为type_flink_process_sink的messagecollector组件,所述组件从上游组件接收数据,然后调用collector发送消息message给下一个算子。[0265]实施例8:[0266]如图10所示,是本发明实施例的一种flink框架运行etl的流程装置的架构示意图。本实施例的flink框架运行etl的流程装置包括一个或多个处理器21以及存储器22。其中,图10中以一个处理器21为例。[0267]处理器21和存储器22可以通过总线或者其他方式连接,图9中以通过总线连接为例。[0268]存储器22作为一种非易失性计算机可读存储介质,可用于存储非易失性软件程序和非易失性计算机可执行程序,如实施例1中的flink框架运行etl的流程方法。处理器21通过运行存储在存储器22中的非易失性软件程序和指令,从而执行flink框架运行etl的流程方法。[0269]存储器22可以包括高速随机存取存储器,还可以包括非易失性存储器,例如至少一个磁盘存储器件、闪存器件、或其他非易失性固态存储器件。在一些实施例中,存储器22可选包括相对于处理器21远程设置的存储器,这些远程存储器可以通过网络连接至处理器21。上述网络的实例包括但不限于互联网、企业内部网、局域网、移动通信网及其组合。[0270]所述程序指令/模块存储在所述存储器22中,当被所述一个或者多个处理器21执行时,执行上述实施例1中的一种flink框架运行etl的流程方法,例如,执行以上描述的图1-图9所示的各个步骤。[0271]以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。当前第1页12当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1