Big Data/Apache Oozie

Oozie workflow pattern - 2

Data Engineer 2017. 9. 28. 17:20

해당 포스트는 이전한 블로그에서도 확인할 수 있습니다.

Oozie workflow pattern - 2

이전 포스트에는 Oozie의 워크플로우 패턴중 하나인 Point-to-Point 패턴에 관해서 알아보았습니다. 이번 시간에는 fork-and-join 패턴에 대해 알아보도록 하겠습니다.

fork-and-join pattern

fork-and-join 패턴은 Fan-out 패턴이라고도 합니다. 이와 같은 형태의 워크플로우는 여러 액션들이 나누어 실행한 후 해당 액션들이 다 정상적으로 완료된 후 다음 액션을 수행해야하는 경우 많이 사용합니다. 즉, 다음 액션이 실행되기 전에 모든 선행 액션이 완료되는 것을 전제로 하겠다는 것입니다. 말로 하니까 약간 이해하기 어렵네요. 예제를 통해 알아보도록 하겠습니다.

워크 플로우 형태는 위와 같습니다. fork를 통해서 여러 액션을 수행하면 fork 된 액션들이 완료될 때까지 join에서 기다립니다. join은 앞서 fork에서 수행되는 액션이 다 종료가 되어야지 다음 액션을 수행합니다. 만일 하나의 액션이라도 실패하게 되면 워크플로우 전체가 종료(kill)됩니다.

그럼 실제로 위에서 실행되고 있는 것을 workflw.xml로 만든 예제를 살펴봅시다. 하이브 액션이 각각 무엇을 하는지는 중요하지 않고 fork-and-join을 어떤식으로 정의하는지를 중점적으로 보시면 좋을 것 같습니다.

<workflow-app name="build_reports" xmlns="uri:oozie:workflow:0.4">

   <global>
         <job-tracker>${jobTracker}</job-tracker>
         <name-node>${nameNode}</name-node>
         <job-xml>${hiveSiteXML}</job-xml>
   </global>

   <start to="preliminary_statistics" />

   <action name="preliminary_statistics">
      <hive xmlns="uri:oozie:hive-action:0.5">
         <script>${scripts}/stats.hql</script>
      </hive>
      <ok to="fork_aggregates" />
      <error to="kill" />
   </action>

   <!-- 여기서 fork가 시작됩니다. -->
   <fork name="fork_aggregates">
      <path start="prescriptions_and_refills" />
      <path start="office_visits" />
      <path start="lab_results" />
   </fork>

   <action name="prescriptions_and_refills">
      <hive xmlns="uri:oozie:hive-action:0.5">
         <script>${scripts}/refills.hql</script>
      </hive>
      <ok to="join_reports" />
      <error to="kill" />
   </action>

   <action name="office_visits">
      <hive xmlns="uri:oozie:hive-action:0.5">
         <script>${scripts}/visits.hql</script>
      </hive>
      <ok to="join_reports" />
      <error to="kill" />
   </action>

   <action name="lab_results">
      <hive xmlns="uri:oozie:hive-action:0.5">
         <script>${scripts}/labs.hql</script>
      </hive>
      <ok to="join_reports" />
      <error to="kill" />
   </action>

   <!-- 여기서 join을 하게 되는거죠. -->
   <join name="join_reports" to="summary_report" />

   <action name="summary_report">
      <hive xmlns="uri:oozie:hive-action:0.5">
         <script>${scripts}/summary_report.hql</script>
      </hive>
      <ok to="end" />
      <error to="kill" />
   </action>

   <kill name="kill">
      <message> Workflow failed. Error message
                [${wf:errorMessage(wf:lastErrorNode())}]</message>
   </kill>
   <end name="end" />
</workflow-app>

위의 workflow.xml 파일에서 보듯이 fork를 하는 부분이 생기고, 이후에 fork 안에 액션들이 수행된 후 합쳐지는 join 컨트롤 노드가 존재합니다.

...

<fork name="fork_aggregates">
   <path start="prescriptions_and_refills" />
   <path start="office_visits" />
   <path start="lab_results" />
</fork>

...
<join name="join_reports" to="summary_report" />

위의 구문처럼 액션의 흐름을 제어할 수 있게 됩니다. fork 내에 있는 액션들을 나누어서 수행을 하고 join에서는 fork 내의 액션이 끝났는지 기다려줍니다. fork 내에 액션중 하나라도 실패하면 워크플로우는 실패하게 됩니다.

다음 포스트에서는 이어서 capture-and-decide(aka switch-case) 패턴에 대해 알아보도록 하겠습니다.

references

  • Apache Oozie
  • Mark Grover,Ted Malaska,Jonathan Seidman,Gwen Shapira. (2015). Hadoop Application Architectures: Designing Real-World Big Data Applications, O'Reilly Media, Inc.