일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 데이터레이크
- 회고
- 박종천
- spray
- wait region split
- 개발7년차매니저1일차
- 코딩인터뷰
- 데이터유통
- hackercup2017
- 함수형 사고
- 해커컵
- functional thinking
- 동시성
- Raw-Request-URI
- 개발자
- datalake
- kafka
- 단위테스트
- coursera
- 실전사례
- 2017회고
- clean code
- 데이터야놀자
- 켄트백
- 클린코드
- 2016년회고
- 테스트주도개발
- 개발자로살아남기
- 알고스팟
- 데이터플랫폼
- Today
- Total
Software Engineering Note
shell script 부분 병렬화 사례 본문
파일 다운로드 > 압축 해제 > hdfs 업로드 > hdfs to storage 업로드
이런 플로우로 데이터를 처리할 일이 있었다. (n = 0 ... ?)
shell script로 구현을 하고 돌려보는데 속도가 너무 느렸다.
어디가 병목일까? 보니 압축 해제하는 부분이 특히 느렸다.
그래서 그 부분부터 병렬화 하기로 했다.
병렬화는 script 파일을 나누고 백그라운드(&) 로 돌리면 된다.
ex) hdfs_uploader.sh ... &
여기서 다시 아래와 같은 문제가 발생했다.
1) unzip 하는 작업이 많아지면 cpu를 너무 많이 차지한다.
2) storage upload 작업이 너무 빈번해지면 문제가 된다.
이제 다시 한 번 정리를 해보자.
1) 파일 다운로드는 빠르다. 문제없는 부분
2) unzip & hdfs upload 부분은 느리다. 병렬화가 필요하다. 하지만 너무 많은 병렬화는 cpu 를 무리하게 사용한다.
- 병렬화는 그대로 간다. 여전히 백그라운드로 실행 시키면 된다.
- 단, 일정 갯수만 실행되도록 컨트롤한다. pgrep -f /path/to/hdfs_uploader.sh | wc -l 와 같은 커맨드로 실행되는 수를 확인할 수 있다.
3) storage upload 부분은 병렬화 시키기 부담스럽다. 몇 개씩 묶어서 한 번에 처리하면 좋겠다.
- storage uploader 는 하나만 띄운다. 스크립트 시작 부분에 storage uplader 를 실행시키고 PID를 받아놓는다. (pid=$($!))
나중에 kill 해야 하므로 필요하다.
- 그룹 단위로 처리하기 위해 hdfs upload 시 그룹 아이디를 부여한다. 이제 "그룹" 이라는 개념이 들어가야 한다.
각 그룹에 속한 task 는 동일한 hdfs path 에 upload 한다.
- storage uploader 는 하나의 그룹에 속한 task 들이 모두 끝나길 기다렸다가 upload 를 수행한다.
- 하나의 그룹이 끝났다는 것을 알기 위해서 hdfs uploader 는 파일을 남기도록 만든다.
- 각각의 hdfs uploader task 는 running_${groupId}_${taskId} 파일을 만들어 실행중임을 알리고, 작업이 완료되면
done_${groupId}_${taskId} 파일을 만든다.
- 그룹의 마지막 녀석은 작업이 끝나면 success_${groupId} 파일을 만든다.
- storage uploader 는 running 파일이 없고, success 파일이 존재하면 하나의 그룹이 작업을 완료했다고 판단하고
storage upload 를 실행한다. 그리고 다음 그룹을 기다린다.
정리하면 이렇게 된다.
문제를 하나씩 해결하다보니 고려해야 할 것들이 많아졌다.
특히 두 번째 개선은 많이 복잡해졌다. 제한 사항이 많으면 시스템이 복잡해지기 마련이다.
이렇게 구현을 하고 문제점을 찾고 다시 개선을 하는 것은 개발자들이 항상 겪는 일이다.
난관에 부딪칠 때마다 머리가 아프지만 그 속에 또 즐거움이 있다.
특히 번뜩이는 아이디어가 떠오를 때는 궁극의 즐거움을 맛볼 수 있다.
이 사례에서는 병렬화 후 특정 그룹으로 묶어서 처리해야하는 부분이 난관이었고,
진행 상태를 파일로 남기는 방법이 해결책이 되었다. 초기 구현에 비해 코드는 꽤 복잡해졌다.
문제)
다운로드 받는 파일의 수가 각 그룹에 할당되는 task 개수에 딱 맞지 않기 때문에 이런 경우도 별도로 처리해줘야 한다.
- ex) 각 그룹이 처리하는 파일의 개수: 10, 실제 업로드해야 하는 파일의 수: 93
너무 복잡해져서 여기에는 적지 않았는데 어떻게 하면 될지 각자 생각해보자 : )
'일하며 개발하며' 카테고리의 다른 글
개발자 준비생들을 위한 조언 (0) | 2021.02.20 |
---|---|
시간 복잡도는 왜 따져봐야 할까? (0) | 2020.03.18 |
클래스는 언제 나눠야 할까? (0) | 2018.02.27 |
FDD(Feeling-Driven Development) (0) | 2018.02.27 |
테스트 코드를 먼저 작성해야 하는 이유 (0) | 2017.06.23 |