我正在使用ooziesqoop操作在datalake中导入数据。我需要一个hdfs文件夹为每个表的数据库源。我有300多张table。
我可以将所有300 sqoop操作硬编码到一个工作流中,但是工作流对于oozie配置来说太大了。
Error submitting job /user/me/workflow.xml
E0736: Workflow definition length [107,123] exceeded maximum allowed length [100,000]
拥有这样的大文件不是一个好主意,因为它会减慢系统的速度(它保存在数据库中),而且很难维护。
问题是,如何为每个表名调用子工作流?
等效的shell脚本类似于:
while read TABLE; do
sqoop import --connect ${CONNECT} --username ${USERNAME} --password ${PASSWORD} --table ${TABLE} --target-dir ${HDFS_LOCATION}/${TABLE} --num-mappers ${NUM-MAPPERS}
done < tables.data
其中tables.data包含一个表名列表,该列表是数据库源表名的子集。例如:
TABLE_ONE
TABLE_TWO
TABLE_SIX
TABLE_TEN
下面是我要为每个表调用的子工作流:
<workflow-app name="sub-workflow-import-table" xmlns="uri:oozie:workflow:0.5">
<start to="sqoop-import"/>
<action name="sqoop-import">
<sqoop xmlns="uri:oozie:sqoop-action:0.2">
<job-tracker>${jobTracker}</job-tracker>
<name-node>${nameNode}</name-node>
<command>sqoop import --connect ${CONNECT} --username ${USERNAME} --password ${PASSWORD} --table ${TABLE} --target-dir ${HDFS_LOCATION}/${TABLE} --num-mappers ${NUM-MAPPERS}</command>
</sqoop>
<ok to="end"/>
<error to="log-and-kill"/>
</action>
<end name="end"/>
<kill name="log-and-kill">
<message>Workflow failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
</kill>
</workflow-app>
如果你需要更精确的信息,请告诉我。谢谢!大卫
2条答案
按热度按时间lnlaulya1#
我的建议是为每个表导入创建工作流。你有6个这样的。将所有6个工作流作为主工作流或父工作流的子工作流调用。通过这种方式,我们可以在一个控制点,它将很容易安排一个单一的工作流。
6ojccjat2#
遗憾的是,在oozie中没有办法很好地做到这一点——您需要将所有300个sqoop操作硬编码到oozie xml中。这是因为oozie处理有向无环图,这意味着循环(比如shell脚本)没有oozie等价物。
但是我不认为oozie是合适的工具。oozie要求每个操作使用一个容器作为启动程序,这意味着您的集群需要在一次运行的空间上分配300个额外的容器。这可以有效地使集群死锁,因为您最终会遇到启动器阻止实际作业运行的情况!我曾经在一个有超过1000个表的大型集群上工作过,我们在那里使用bash来避免这个问题。
如果您确实想在oozie中继续这样做,那么就不可避免地生成一个包含300个操作的工作流。我会做300个动作,而不是300个调用子工作流,每个调用一个动作,否则你会产生更多的开销。您可以手动创建此文件,或者最好编写一些代码来生成给定表列表的oozie工作流xml文件。后者更灵活,因为它允许在每次运行的基础上包含或排除表。
但正如我最初所说的,除非你有很好的理由,否则我会坚持使用bash。