2. Workflow?
• Oozie를 통해 실행할 action들과 action 관련 속성들을 정의
• action?
– Map-Reduce java
– Map-Reduce Streaming, Pipe
– Pig
– Hive
– Java application
– Shell script
– User defined action
• 상세 설명
– http://oozie.apache.org/docs/4.0.1/WorkflowFunctionalSpec.html
• 작성법은 뒤에서 더 설명…
3. Job properties
• Workflow가 위치한 디렉토리 경로 정의
• Workflow에서 사용할 속성들의 값을 정의
• 단순 text 파일, 변수는 ${variable_name}로 표기
• 예제 # hadoop configuration
nameNode=hdfs://your.namenode
jobTracker=your.jobtracker.address.com:8032
queueName=default
serviceDir=/user/alex/hello
# oozie configuration
oozie.wf.application.path=${nameNode}${serviceDir}/workflow
# job directory information
inputDir=${serviceDir}/input
outputDir=${serviceDir}/output
# user information
user.name=alex
group.name=hadoop
# job configuration
reduceNum=2
4. Workflow 배포
• 배포된 상태에서의 hdfs 경로 구조
• hello/workflow/workflow.xml
– Action이 정의된 Workflow 파일
– Properties 파일에서는 디렉토리까지만 지정
• hello/workflow/lib/
– 사용할 java application, library (only jar)
– 실행할 Map-reduce application jar도 이곳에 배포
– Streaming 작업이라면 이곳에 hadoop-streaming.jar 넣어줘야 함
5. Workflow 실행
• Oozie client 를 이용해 실행
• 실행 예
– bash$ oozie job –oozie http://your.oozie.address.com:11000/oozie -config ./hello.properties –run
• hello.properties
– 앞서 살펴 본 job properties 파일
– Oozie를 통해 실행할 workflow의 위치와 관련 값들을 정의
6. Workflow again
• Workflow
– 실행할 작업(Task)들을 나열
– Xml 로 표기
– Control flow nods
• Workflow의 시작, 종료 등을 정의하는 node – start, end, kill
• Workflow의 흐름을 제어하는 node – decision, fork, join
– Action nodes
• 실행할 작업(task)을 정의
• action node의 작업은 oozie 밖에서 실행 – MR, Streaming, Pig, Hive, …
• 2가지 전이 단계를 가짐 – ok, error
• 변수 사용
– 표기 : ${param-name}
– 변수의 값은 Job properties 파일에서 정의
– 추후에 살펴 볼 coordinator 에서도 정의
7. Workflow 작성 – start/end
• Node마다 이름을 명시 – “내가 그의 이름을 불러 주기 전에는…”
– 빨간색 영역은 사용자가 마음대로 넣을 수 있는 값
• Start node에서 시작할 node의 이름을 명시
• End node는 workflow job을 종료시킴. 성공적인 종료.
• Kill node는 workflow job을 스스로 죽임. Error 종료.
<workflow-app name=“hello_workflow” xmlns=“uri:oozie:workflow:0.4>
<start to=“start_node”/>
<action name=“start_node”>
…
<ok to=“next_node”>
<error to=“error_node”>
</action>
…
<kill name=“error_node”>
…
</kill>
<end name=“end_node”/>
</workflow-app>
8. Workflow 작성 – Map-Reduce
• Map-Reduce Acition 정의
<action name=“start_node”>
<map-reduce>
<job-tracker>jobtracker.address:port</job-tracker>
<name-node>namenode.address:port</name-node>
<!-- task 시작 전에 실행 -->
<prepare>
<delete path=“/where/is/my/output”/>
</prepare>
<!-- jobConf 정의 -->
<configuration>
<!-- new-api (hadoop2 설정) 사용하려면 미리 new-api를 true로 설정 -->
<property>
<name>mapred.mapper.new-api</name>
<value>true</value>
</property>
<property>
<name>mapred.reducer.new-api</name>
<value>true</value>
</property>
…
</configuration>
</map-reduce>
<ok to=“next_node”>
<error to=“error_node”>
</action>
11. Workflow 작성 – file/archive
• File/archive 방법
<action name=“start_node”>
<map-reduce>
…
<configuration>
…
</configuration>
<!-- 상대 경로일 경우 work dir(properties에서 설정한 거)을 기준으로 한다. -->
<file>/your/file/path1</file>
<!-- # 뒤에 alias 붙일 수 있다. -->
<file>/your/file/path2#file_alias2</file>
<archive>/your/archive/path1</archive>
<archive>/your/archive/path2#archive_aliash2</archive>
</map-reduce>
<ok to=“next_node”>
<error to=“error_node”>
</action>
13. Workflow 작성 – job-xml
• Configuration의 jobConf를 별도 파일로 작성 – job-xml
– <job-xml>your.jobConf.path.xml</job-xml>
• 로딩 순서
– streaming(streaming job일 경우) -> Job-conf -> configuraton
– Configuration에 중복된 설정 있을 경우 configuration 내용대로
• 여러 job.xml 파일 입력 가능
14. Workflow 작성 - Shell
• Shell action
<action name=“shell_node”>
<shell xmlns=“uri:oozie:shell-action:0.1”>
<job-tracker>jobtracker.address:port</job-tracker>
<name-node>namenode.address:port</name-node>
<!-- task 시작 전에 실행 -->
<prepare>
<delete path=“/do/u/wanna/delete/something”/>
</prepare>
<exec>bash</exec>
<argument>your.script</argument>
<argument>your.arg1</argument>
<argument>your.arg2</argument>
…
<argument>your.arg#</argument>
<file>/your/script/path</file>
<!-- capture-output이 있으면 stdout으로 출력된 param_name=value 를
oozie workflow에서 아래처럼 사용 가능
${wf:actionData(‘node_name’)[‘param_name’]} -->
<capture-output/>
</shell>
<ok to=“next_node”>
<error to=“error_node”>
</action>
15. Workflow 작성 - Java
• Java action
– map-reduce job으로 작동하므로 queue를 꼭 지정
<action name=“java_node”>
<java>
<job-tracker>jobtracker.address:port</job-tracker>
<name-node>namenode.address:port</name-node>
<prepare>
<delete path=“/where/is/my/output”/>
</prepare>
<configuration>
<property>
<name>mapred.queue.name</name>
<value>default</value>
</property>
</configuration>
<main-class>your.main.class</main-class>
<!-- configuraton에서 mapred.child.java.opts 로 지정해도 동일한 효과 -->
<java-opts>-Dblah</java-opts>
<arg>arg1</arg>
<arg>arg2</arg>
</java>
<ok to=“next_node”>
<error to=“error_node”>
</action>
16. Coordinator?
• Crontab처럼 반복적으로 workflow를 실행
• Properties
– oozie.coord.application.path 정의
• oozie.wf.application.path 는 정의하지 않음
• 정의된 위치 내 coordinator.xml 사용
• workflow path는 coordinator.xml 에서 지정
• 실행
– $ oozie job -oozie http://your.oozie.host:11000/oozie -config ./coord.properties –run
• 상세 설명
– http://oozie.apache.org/docs/4.0.1/CoordinatorFunctionalSpec.html
17. coordinator – 시각 표시
• Datetime
– 분(minute) 단위까지 지정 가능
– UTC
• YYYY-MM-DDTHH:MMZ
• 2014-07-01T00:10Z
– GMT offset
• YYYY-MM-DDTHH:MM+0900 (한국)
• 2014-07-01T09:10+0900
– 한국 시각으로 14년 7월 1일 오전 9시 10분
– 위의 UTC로 표기된 시각과 동일
• timezone 표시
– NON-DST : GMT[+/-]HH:MM
– DST support(by JAVA jdk) : America/Los_Angeles
18. coordinator – 시각 함수들
• ${coord:minutes(int n)} = n
• ${coord:hours(int n)} = n*60
• ${coord:days(int n)} = 현재 날짜로부터 n일이 전부 지날 때까지 분
• ${coord:months(int n)} = 현재 날짜로부터 n달이 지날 때까지 분
– DST(daylight saving time) 때문에 timezone에 따라 변동
19. coordinator 구성
• controls
– timeout, concurrency, execution, throttle 등등 지정
– timeout – 실현된 action 이 다른 조건을 기다릴 때까지의 최대 시간(분). Default -1 (no timeout)
– concurrency – 최대 동시 실행 action 개수 (default 1)
– execution – 동시에 여러 개가 실행될 때 실행 순서 ( FIFO, LIFO, LAST_ONLY, default FIFO )
– throttle – waiting 단계에서 기다릴 최대 action 개수(default 12)
• dataset
– 논리적 이름을 갖는 데이터(URI) 집합
– dataset instance – dataset의 특정한 발현으로, 중복 없는 URI들의 집합
– name – dataset의 이름
– frequency – 생성 주기
– initial-instance – 초기 data의 생성 시각
– Uri-template – dataset을 명시하고, dataset instance로 구체화될 상수/변수로 이루어진 uri template
– done-flag – data set을 위한 done file명. 기본은 _SUCCESS. 빈 칸으로 설정할 경우 directory의 유무를 이용.
• input-events
– coordinator action을 실행하기 위한 input 조건. 생성된 모든 dataset instance가 준비되어야 함
• output-events
– 결과를 위한 dataset instance
• action
– workflow와 property 설정
20. coordinator – action
• 하루 주기로 7월 2일 00:00에 시작, 7/8 00:00에 종료
• app-path로 workflow.xml이 있는 경로 설정
<coordinator-app name=“hello-coord” frequency=“${coord:days(1)}” start=“2014-07-02T00:00+0900” end=“2014-07-
08T00:00+0900” timezone=“UTC” xmlns=“uri:oozie:coordinator:0.4”>
<action>
<workflow>
<app-path>hdfs://bar:8020/usr/joe/logprocessor</app-path>
</workflow>
</action>
</coordinator-app>
21. coordinator - dataset
• 1시간 주기의 searchlogs, clicklogs와 하루 주기의 joinlogs 라는 dataset
• uri-template
– ${YEAR}, ${MONTH}, ${DAY}, ${HOUR}, ${MINUTE} 같은 상수(EL Time Constants) 사용 가능
– job properties에 정의된 변수도 ${variable_name} 처럼 사용 가능
<coordinator-app name=“hello-coord” frequency=“${coord:days(1)}” start=“2014-07-02T00:00+0900” end=“2014-07-
08T00:00+0900” timezone=“UTC” xmlns=“uri:oozie:coordinator:0.4”>
<datasets>
<dataset name=“searchlogs” frequency=“${coord:hours(1)}” initial-time=“2014-06-20T00:00+0900” timezone=“GMT+09:00”>
<uri-template>hdfs://bar:8020/data/srchlogs/${YEAR}${MONTH}/${DAY}/${HOUR}/data</uri-template>
</dataset>
<dataset name=“clicklogs” frequency=“${coord:hours(1)}” initial-time=“2014-06-20T00:00+0900” timezone=“GMT+09:00”>
<uri-template>hdfs://bar:8020/data/clcklogs/${YEAR}${MONTH}/${DAY}/${HOUR}/data</uri-template>
</dataset>
<dataset name=“joinlogs” frequency=“${coord:days(1)}” initial-time=“2014-07-01T05:00+0900” timezone=“GMT+09:00”>
<uri-template>hdfs://bar:8020/data/joinlogs/${YEAR}{$MONTH}/${DAY}/data</uri-template>
</dataset>
</datasets>
…
</coordinator-app>
22. coordinator – input/output events
• dataset으로부터 dataset-instance를 생성
• start-instance와 end-instance를 이용해 최근 24시간에 해당하는 24개 instance 생성
– Data가 준비될 때까지 기다림. 단, initial-time보다 앞선 data가 필요할 경우엔 해당 data 무시
• output은 1개 instance 생성 (참고로, coord:current는 dataset의 frequency와 간격이 일치)
<coordinator-app name=“hello-coord” frequency=“${coord:days(1)}” start=“2014-07-02T00:00+0900” end=“2014-07-
08T00:00+0900” timezone=“UTC” xmlns=“uri:oozie:coordinator:0.4”>
<datasets>
…
</datasets>
<input-events>
<data-in name=“in_srch” dataset=“searchlogs”>
<start-instance>${coord:current(-24)}</start-instance>
<end-instance>${coord:current(-1)}</end-instance>
</data-in>
<data-in name=“in_clck” dataset=“clicklogs”>
<start-instance>${coord:current(-24)}</start-instance>
<end-instance>${coord:current(-1)}</end-instance>
</data-in>
</input-events>
<output-events>
<data-out name=“out_join” dataset=“joinlogs”>
<instance>${coord:current(0)}</instatnce>
</data-out>
</output-events>
</coordinator-app>
23. coordinator – action again
• app-path로 workflow.xml이 있는 경로 설정
• data-in, data-out에서 정의한 이름을 이용해 필요한 data 설정
– workflow.xml 에서 ${srchlogs}, ${clcklogs}, ${outdir} 로 사용 가능
…
</output-events>
<action>
<workflow>
<app-path>hdfs://bar:8020/usr/joe/logprocessor</app-path>
<configuration>
<property>
<name>srchlogs</name>
<value>${coord:dataIn(‘in_srch’)}</value>
</property>
<property>
<name>clcklogs</name>
<value>${coord:dataIn(‘in_clck’)}</value>
</property>
<property>
<name>outdir</name>
<value>${coord:dataOut(‘out_join’)}</value>
</property>
</configuration>
</workflow>
</action>
</coordinator-app>
24. Coordinator - Materialization
• Coordinator의 Job Frequency에 따라 action이 생성되어 실행됨
• dataset instance가 구체화됨
• 앞 예에서 7/1 24:00에 실행될 job에서 property들 값
– srchlogs =
hdfs://bar:8020/data/srchlogs/201407/01/23/data,hdfs://bar:8020/data/srchlogs/20140
7/01/22/data,...,hdfs://bar:8020/data/srchlogs/201407/01/00/data
– clcklogs =
hdfs://bar:8020/data/clcklogs/201407/01/23/data,hdfs://bar:8020/data/clcklogs/201407/
01/22/data,...,hdfs://bar:8020/data/clcklogs/201407/01/00/data
– outdir = hdfs://bar:8020/data/joinlogs/201407/01/data
• initial-time + frequency(24시간) 가 안 지났기 때문에 07/01이 current(0)
25. End
• 더 자세한 내용은 http://oozie.apache.org/ 에서!!!
• Yahoo!에서 작성한 use cases
– https://github.com/yahoo/oozie/wiki/Oozie-WF-use-cases
– https://github.com/yahoo/oozie/wiki/Oozie-Coord-Use-Cases