权声明:本文为博主原创文章,未经博主允许不得转载。
一、使用CM添加服务的方式安装Oozie
如果在创建Oozie数据库时失败,且提示数据库已存在,如下图,则可能是之前已经安装过Oozie,没有卸载干净,需要手动将Oozie服务器数据目录删掉(oozie/data部分),见图二
(图一)
(图二)
二、安装成功后,可以通过web方式访问Oozie(http://hadoop1:11000.oozie/),但此时出现如下页面,提示需要Ext JS,查看官方文档可知,只能使用Ext js 2.2版本(版权问题)
将ext-2.2.zip放到libext目录下:/opt/cloudera/parcels/CDH/lib /oozie/libext,并解压,unzip ext-2.2.zip,将解压后的ext-2.2权限改为777:chmod -R 777 ext-2.2
此时不需要重启Oozie,只要刷新浏览器,即可看到oozie的web页面
三、修改Oozie的元数据库为mysql,默认为derby,不适合生产环境使用
1、CM配置见下图:
2、在对应的mysql服务器创建oozie数据库:create database oozie;
3、在安装Oozie的节点libserver目录下(/opt/cloudera/parcels/CDH/lib/oozie/libserver)添加mysql的驱动jar包,然后重启Oozie
此时会报如下错误,说数据库不存在:
4、此时可以在CM的Oozie-->实例-->右上角的操作处点击创建数据库
此时报错如下图,提示找不到mysql驱动
将mysql驱动拷贝到libtools目录下(/opt/cloudera/parcels/CDH/lib/oozie /libtools),并重命名驱动包,去掉版本号,如原名为:mysql-connector-java-5.1.25-bin.jar,重命名为:mysql-connector-java-bin.jar,此时再次执行上面的创建数据库操作,提示创建成功。
也可以进行mysql数据库,查看oozie数据库下的表,此时会多出新建的12张表,此时代表Oozie已全部安装成功!
此时通过CM重新启动Oozie服务成功!
四、修改Oozie配置
将java的堆栈大小设为1到2G
五、运行demo
1、进入目录:/opt/cloudera/parcels/CDH/share/doc/oozie-4.0.0+cdh5.3.3+340,在root目录下建立example目录,并将上面目录中的oozie-examples.tar.gz拷贝到/root/example目录中并解压,得到examples目录,目录结构如下:
2、进入apps/map-reduce目录,可看到如下配置文件,主要关注job.properties和workflow.xml
3、修改job.properties
1)未修改前的内容
2)修改细节:
修改nameNode:nameNode=hdfs://xxx:8020
修改jobTracker:jobTracker=hadoop4:8032
注意:jobTracker的内容根据hadoop的版本,内容也不同。如为hadoop1,则直接使用jobTracker的地址即可。如为 hadoop2,即写resourceManager的地址,具体可参见:/etc/hadoop/conf/yarn-site.xml
queueName=default:指定提交作业时,运行的队列
examplesRoot=examples:指定运行作业的hdfs上的目录名称
4、可查看workflow.xml配置的内容,但暂不做修改
5、将examples整个目录上传到hdfs的/user/oozie下:hdfs dfs -put examples /user/oozie
6、运行作业:
oozie job -oozie http://hadoop1:11000/oozie/ -config /root/example/examples/apps/map-reduce/job.properties -run
重点:oozie作业流程解析
1)job.properties文件可以不上传到hdfs中,是在执行oozie job ...... -config时,批定的linux本地路径
2)workflow.xml文件,一定要上传到job.properties的oozie.wf.application.path对应的hdfs目录下
3)job.properties中的oozie.use.system.libpath=true指定oozie使用系统的共享目录
4)job.properties中的oozie.libpath=${nameNode}/user/${user.name}/apps/mymr,可以用来执行mr时,作业导出的jar包存放位置,否则可能报找不到类的错误
5)oozie调度作业时,本质也是启动一个mapreduce作业来调度,workflow.xml中设置的队列名称为调度作业mr的队列名称。所以如果想让作业运行在指定的队列时,需要在mr或hive中指定好
7、检测workflow.xml文件的正确性
oozie validate workflow.xml
8、编写workflow.xml文件
控制节点:
1)start节点
<start to="[nodename]" />
2)end节点
<end name="[nodename]" />
3)kill节点
<kill>
<message>"logmsg"</message>
</kill>
4)decision决策节点
<decision name="[nodename]">
<switch>
<case to="[nodename]">[PREDICATE]</case>
......
<default to="[nodename]" />
</switch>
</decision>
5)fork分支节点
<fork name="[fork-node-name]">
<path start="[nodename]"/>
......
<path start="[nodename]"/>
</fork>
6)join会签节点
<join name="[join-node-name]" to="[nodename]" />
动作节点:
1)map-reduce配置:
<workflow-app xmlns="uri:oozie:workflow:0.2" name="map-reduce-wf">
<start to="mr-node"/>
<action name="mr-node">
<map-reduce>
<job-tracker>${jobTracker}</job-tracker>
<name-node>${nameNode}</name-node>
<prepare>
<delete path="${nameNode}/user/${wf:user()}/${examplesRoot}/output-data/${outputDir}"/>
</prepare>
<configuration>
<property>
<name>mapred.job.queue.name</name>
<value>${queueName}</value>
</property>
<property>
<name>mapred.mapper.class</name>
<value>org.apache.oozie.example.SampleMapper</value>
</property>
<property>
<name>mapred.reducer.class</name>
<value>org.apache.oozie.example.SampleReducer</value>
</property>
<property>
<name>mapred.map.tasks</name>
<value>1</value>
</property>
<property>
<name>mapred.input.dir</name>
<value>/user/${wf:user()}/${examplesRoot}/input-data/text</value>
</property>
<property>
<name>mapred.output.dir</name>
<value>/user/${wf:user()}/${examplesRoot}/output-data/${outputDir}</value>
</property>
</configuration>
</map-reduce>
<ok to="end"/>
<error to="fail"/>
</action>
<kill name="fail">
<message>Map/Reduce failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
</kill>
<end name="end"/>
</workflow-app>
2)hive动作节点配置
<workflow-app xmlns="uri:oozie:workflow:0.2" name="hive-wf">
<start to="hive-node"/>
<action name="hive-node">
<hive xmlns="uri:oozie:hive-action:0.2">
<job-tracker>${jobTracker}</job-tracker>
<name-node>${nameNode}</name-node>
<prepare>
<delete path="${nameNode}/user/${wf:user()}/${examplesRoot}/output-data/hive"/>
<mkdir path="${nameNode}/user/${wf:user()}/${examplesRoot}/output-data"/>
</prepare>
<configuration>
<property>
<name>mapred.job.queue.name</name>
<value>${queueName}</value>
</property>
</configuration>
<script>script.q(存放hive脚本的文件)</script>
<param>INPUT=/user/${wf:user()}/${examplesRoot}/input-data/table</param>
<param>OUTPUT=/user/${wf:user()}/${examplesRoot}/output-data/hive</param>
</hive>
<ok to="end"/>
<error to="fail"/>
</action>
<kill name="fail">
<message>Hive failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
</kill>
<end name="end"/>
</workflow-app>
3)sqoop动作节点
<workflow-app xmlns="uri:oozie:workflow:0.2" name="sqoop-wf">
<start to="sqoop-node"/>
<action name="sqoop-node">
<sqoop xmlns="uri:oozie:sqoop-action:0.2">
<job-tracker>${jobTracker}</job-tracker>
<name-node>${nameNode}</name-node>
<prepare>
<delete path="${nameNode}/user/${wf:user()}/${examplesRoot}/output-data/sqoop"/>
<mkdir path="${nameNode}/user/${wf:user()}/${examplesRoot}/output-data"/>
</prepare>
<configuration>
<property>
<name>mapred.job.queue.name</name>
<value>${queueName}</value>
</property>
</configuration>
<command>import --connect jdbc:hsqldb:file:db.hsqldb --table TT --target-dir /user/${wf:user()}/${examplesRoot}/output-data/sqoop -m 1</command>
<file>db.hsqldb.properties#db.hsqldb.properties</file>
<file>db.hsqldb.script#db.hsqldb.script</file>
</sqoop>
<ok to="end"/>
<error to="fail"/>
</action>
<kill name="fail">
<message>Sqoop failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
</kill>
<end name="end"/>
</workflow-app>