빅데이터분석

결함을 허용하는 의존성 있는 태스크의 관리

hongiiv 2015. 10. 13. 18:58
반응형

그래프를 이용한 태스크 표현

흔히 바이오인포매틱스 분석이라고 하는 경우 스크립트나 모듈을 작성하여 일련의 분석을 수행하곤 한다. 그러나 단순한 형태의 일이 아니라 더욱 고난이도의 일을 처리하다가 보면 (물론 대부분이 그렇지만) 태스크의 의존성을 고려해야 하는 경우가 많다. 그래프를 이용하여 이를 표현해 보면서 어떻게 의존성과 결함을 고려한 스케줄러를 만들 수 있는지 생각해 보도록 하자.



총 4개의 노드 (Task1, Task2, Task3, Task4)와 엣지로 구성된 그래프로 각각의 엣지는 다음과 같은 의존성을 가진다.


Task1=>[Task2, Task3]

Task2=>[Task4]

Task3=>[Task4]

Task4=>[]


즉, Task1이 끝나야 Task2,3이 수행되고 Task4는 Task2,3가 끝나야 수행된다. 이렇게 각각의 노드(태스크)는 의존성(엣지)을 가지고 최종적으로 위의 그래프는 Task1-Task2, Task1-Task3, Task2-Task4, Task3-Task4로 표현될 수 있다.

워크플로우 상호 의존 태스크 관리

SGE를 비롯한 대부분의 스케줄러는 workflow interdependence (워크플로우 상호의존) 개념을 가지고 있으며 다음과 같이 표현될 수 있다.

qsub -N Task1
qsub -N Task2 -hold_jid Task1
qsub -N Task3 -hold_jid Task1
qsub -N Task4 -hold_jid Task2, Task3


어때유 간단하쥬,

결함을 허용하는 워크플로우 만들기

그런데 문제는 어떻게 결함을 허용하게 하느냐는 것이다. 여러가지 방법이 있겠지만, 필자는 각 Task의 결과 파일과 결과 파일의 MD5 체크섬을 이용하는 방안에 대해서 이야기 해 볼 것이다.


각 Task는 Task의 결과로 생성되(어야하)는 ouput file이 존재한다. 따라서 Task의 실행전에 해당 output file이 존재하는 또한 저장된 ouput file의 MD5 값이 outputfile을 실제 MD5를 실행해서 얻은 값과 동일한지(결과값이 변경되었는지를 확인하기 위해) 를 확인한다. 만약 두 조건을 만족한다면 해당 Task는 이미 정상적으로 실행되었던 것이기에  skip하고 그렇지 않은 경우에는 해당 Task가 처음 수행되거나 또는 비정상적으로 종료된 것이기 때문에 Task 고유의 action을 수행한다.


if [[ -f $OUTFILE && -f $MD5FILE && `md5sum ${OUTFILE} | cut -f1 -d" "` = `cat ${MD5FILE} | cut -f1 -d" "` ]]; then

   skip

else

   do task action

   task_md5=`md5sum $OUTPUTFILE > $MD5FILE

fi


위 그림과 같이 Task3이 어떤 이유에서든 실패했다면, 실패의 원인을 찾아 해결한 후 다시 모든 Task job을 resubmit하면 Task1은 skip이 되고 (이미 정상적으로 수행되었기때문) Task3부터는 재실행하게 되어 결국 자원낭비 없이 모든 Task들이 수행된다.

Job Array를 이용한 반복 태스크 관리

한가지 더 이쪽 분야의 일을 하다가 보면 특정한 일을 여러번 반복해야하는 경우가 생긴다. 가령 염색체별로 23번을 반복해야한다거나 샘플별로 동일한 작업을 여러번 해야 한다거나 말이다. Task2, Task3...TaskN의 작업은 변수1개만 다를뿐 동일한 경우에는 Job Array를 이용한다.


qsub -N Task2toN -t 1-100 


-t 옵션을 주어 1부터 100까지 100번의 job을 차례로 submit한다. 그럼 나는  job 스크립트에 다음과 같이 array별로 변수를 바꾸어 할당하여 job을 수행하도록 하면 된다.


sample=awk "NR==${SGE_TASK_ID}" samplelist.txt

java -jar GATK.jar -T GenotypeGvcf -I ${sample}.bam -O ${sample}.vcf


samplelist.txt에는 sample 이름 100개가 담겨져 있고 스크립트는 samplelist.txt 파일을 한줄한줄 읽어 두번째  모든 샘플에 대해 GATK 작업을 100번 수행한다. 100번을 job을 submit하지 않고도 100번을 job을 수행할 수 있는 것이다. 이렇게 간단하게 embarrassingly parallel를 손쉽게 구현이 가능하다.


간단하게 바이오인포매틱스 워크플로우에서 SGE 스케줄러를 이용하여 의존성 있는 Task들에 대해서 결함을 허용하는 한편 간단히 array job을 수행하는 방법에 대해서 알아보았다.


실제로는 NoFlo 등을 이용하여 프론트엔드단을 구현하고 그안에 SGE 스케줄러와 위에 설명한 방법들을 결합하여 워크플로우를 작성하여 실행하도록 하면 끝.

Job 모니터링과 fail job 복구

마지막으로 스케줄러를 사용하다보면 간혹 shared storage가 네트워크의 과부하 등으로 제대로 작동되지 않는 경우 SGE는 job의 상태를 Eqw로 빠드리고 에러를 확인해 보면 "can't chdir to directory: No such file or directory"라고 shared storage에 접근하지 못한다는 에러를 확인 할 수 있다. 이때는 아까도 말했듯이 간헐적인 네트워크 과부하 등의 원인으로 shared staroge 접근에 임시적으로 문제가 생길 수 있으니 이때는 job을 다시 실행하도록 하는데 qmod의 -cj 옵션으로 에러를 해결(clear)했으니 다시 시도하라는 것이다.


간단히 다음의 bash 스크립트로 job 상태를 xml 형태로 받아 파싱하여 queue의 상태를 모니터링하도록 하자.


로그 관리

분석을 수행하면서 생기는 로그는 다음의 3가지로 나누어 볼 수 있다. 스케줄러에서 생성되는 Job별 STDOUT, STDERR과 전체 워크플로우에 사용자가 넣은 로그로 각 로그는 웹 상에서 자동으로 갱신되어 보여지도록 한다. 이때는 js-logtail 등을 이용하면 쉽게 로그 파일을 처리할 수 있다.





반응형