머신러닝 분석 과정 자동화를 위한 데이터 파이프라인 구축하기마이뮤직테이스트

이승진
MyMusicTaste
Published in
10 min readMay 6, 2020

--

이 글은 MyMusicTaste(mymusictaste.com, 이하 ‘마이뮤직테이스트’)의 Growth Team(이하 ‘그로스팀’)이 지난 한 달간 그로스팀 데이터 엔지니어 셀 (이하 ‘S-HD’)의 ‘분석 자동화 파이프라인’을 구성한 과정을 다룹니다. 마이뮤직테이스트 그로스팀은 ‘회사의 성장 견인’을 목표로 2018년 10월 신설된 팀인 동시에 마이뮤직테이스트의 데이터와 연관된 모든 업무를 수행하는 조직입니다. 글 속에 내용은 ‘S-HD’ 팀원이 모두 함께 수행한 것을 제가 정리하여 쓴 것으로, 실질적인 업무는 팀원들과 모두 함께 수행했음을 미리 밝힙니다.

0. 들어가며

안녕하세요, 마이뮤직테이스트의 S-HD 셀에서 산업기능요원으로, 데이터 엔지니어 업무를 맡고 있는 Jamie 입니다. 최근에 그로스팀 데이터 분석 셀의 요청 사항 이였던 ‘데이터 분석 자동화 파이프라인 구축’ 작업을 진행했습니다. 이 과정에서 알게 된 ‘데이터 분석 파이프라인’에 대한 개념과 어떻게 파이프라인을 구축 했는가, 과정 중에 어떤 허들이 있었는가에 관해 정리해 봤습니다.

1. ‘데이터 분석 파이프라인’이 도대체 뭐야?

데이터 사이언스 영역에서의 ‘파이프라인’ 이란, 한 데이터 처리 단계의 출력이 다음 단계의 입력으로 이어지는 형태를 말합니다. 즉, 데이터 분석을 위해 필요한 여러 개별 작업 (데이터 수집, 저장, 처리, 분석, 결과 저장 등)이 이후 작업을 실행하기 위한 입력으로 이어진다는 의미입니다.

저희 마이뮤직테이스트 그로스 팀의 분석 과정을 예시로 말씀드리면, 다음과 같습니다.

  1. 마이뮤직테이스트에서 유저가 특정 아티스트의 공연을 ‘MAKE’ 하는 등의 유저 데이터를 수집, 저장
  2. 수집 및 저장된 데이터를 분석에 알맞은 형태로 전처리
  3. 전처리된 데이터를 바탕으로 머신러닝 모델을 작동
  4. 분석 결과를 도출
  5. 1~4의 과정을 자동화

이처럼 데이터 분석에 필요한 여러 작업들은 꼬리에 꼬리를 물며 하나의 연속된 과정으로 이어집니다. 이를 일련의 연속과정으로 이해하여 하나의 프레임으로 조망하는 개념이 바로 ‘데이터 분석 파이프라인’ 이라고 할 수 있습니다.

2. 그로스팀의 파이프라인

2–1. 우리는 왜 파이프라인 구축을 시작했는가

우리 그로스팀, 데이터 분석 셀 (이하 ‘TSE’)의 현재 분석 프로세스는 다음과 같습니다.

마이뮤직테이스트의 사업부에서는 공연의 사업성 여부 판단 및 아티스트와 컨텍하기 위한 자료로 사용할 ‘특정 국가에서의 티켓 판매량 예측 데이터’를 TSE에 요청합니다. TSE는 이러한 분석 요청이 들어오면, 데이터 분석가가 로컬 환경에서 티켓 판매량 예측 분석을 진행하고, 이 결과 값들을 구글 스프레드 시트에 일일이 저장하고 있습니다.

하지만, 마이뮤직테이스트가 진행하는 공연의 수는 꾸준히 증가하고 있고, 다양한 아티스트들의 공연 요청을 받는 상황에서 분석 해야하는 공연의 수가 크게 증가하고 있습니다.

이러한 상황에서 TSE의 데이터 분석가들은 더 좋은 모델을 구축하기 위한 연구 개발 시간이 줄어들었고, 사업부는 필요한 시간에 분석 결과 값을 확인하지 못하는 결과를 초래했습니다.

위와 같은 문제를 해결해 보고자 S-HD는 TSE의 분석가들이 좀 더 효율적으로 시간을 활용하여 모델 연구 개발에 매진할 수 있고, 사업부에서 TSE에 굳이 분석을 요청하지 않더라도 Real-time으로 판매량 예측 데이터를 쉽고, 편리하게 확인할 수 있는 환경을 조성하기 위해 데이터 분석 파이프라인 구축을 시작하게 되었습니다.

2–2. 어떻게 파이프라인 구축 작업을 진행했는가

S-HD 셀은 소프트웨어 개발 경력이 있고, MMT에서 데이터 엔지니어링 셀 리딩을 담당하고 계시는 DK님이 리더가 되어 전체적인 작업을 계획하고, 진행하고 있습니다. DK님이 구글 엔지니어 분들과 미팅을 진행하시면서 효율적인 아키텍쳐 설계 (아래 사진 참고) 에 매진하셨고, 설계에 따른 R&R (Role and Responsibility)을 셀 원에게 설정했습니다.

[초기 Pipeline]
[최종 Pipeline]
  1. 하루에 한 번 설정한 시간에 ‘Cloud Scheduler’ 실행 → ‘Pub/Sub’에 메세지 전송
  2. ‘Pub/Sub’에 설정된 값을 기반으로 ‘Cloud Functions’ 실행
  3. ‘Cloud Functions’에 설정된 값을 기반으로 ‘Compute Engine’(Analysis Server) 실행
  4. ‘Compute Engine’(Analysis Server)에서 ‘BigQuery’(Data Source)와 ‘Github(Source Code)’를 기반으로 분석 실행
  5. 분석이 완료되면 분석 결과 값은 ‘BigQuery’(Analysis Result)로 보내고, ‘Pub/Sub’에 ‘Compute Engine’(Analysis Server)의 정보를 메세지로 보냄
  6. ‘Pub/Sub’ 설정된 값을 기반으로 ‘Cloud Function’ 실행, ‘Compute Engine’ 종료

2–3. 아키텍쳐 수정

최종 아키텍쳐는 초기 아키텍쳐와 비교할 때 크게 3가지의 변경사항이 있었습니다.

첫 번째, Composer를 Scheduler로 변경하였습니다.

초기 아키텍쳐에서는 Composer를 이용해 전체적인 Schedule Job을 관리하려 했습니다. Composer의 경우 Job 사이의 interdependency (상호 의존성)이 존재할 때 비로소 효과적일 수 있는데, 저희의 파이프라인의 경우 단일 Job (Python Script 실행) 만 작동되는 구조이므로 굳이 Composer를 사용해야 할까? 라는 의문이 들었습니다. 이후 많은 리서치를 통해 End Point만 지정해주면 정해진 시간에 쉽게 Job을 실행시킬 수 있는 Scheduler를 사용하는 것으로 수정했고, 이와 동시에 비용을 절감할 수 있었습니다.

  • Scheduler의 경우 3개의 Cron Job 까지 무료.

두 번째, Pub/Sub을 추가하였습니다.

Cloud Scheduler를 사용하면서 End Point로서 단일 HTTP 호출, Pub/Sub 중 한 가지를 선택해야 했습니다. HTTP 호출의 경우 보안에 취약하다는 단점을 가지고 있으므로, 상세한 로그 기록이 가능한 Pub/Sub을 아키텍쳐에 추가하였습니다.

세 번째, 분석 로그를 Cloud Storage가 아닌 Stackdriver를 활용해 기록하는 것으로 변경했습니다.

Cloud Storage의 경우 GCE를 비롯한 클라우드 서비스의 로깅을 위해선 별도의 소스코드를 이용하여 많은 로그들을 저장해 주어야 하는데, Stackdriver의 경우 별도의 소스 코드 없이 모니터링 탭을 통해 편리하게 VM 이상 작동 탐지가 가능합니다. 적은 수의 인원이 쉽고, 간편하게 유지보수를 하기 위해서는 복잡도가 낮은 인프라 구축이 필요했고, 이에 따라 Stackdriver를 활용하는 것으로 변경하였습니다.

2–4. 허들을 뛰어넘자

[개인 R&R (일부 수정사항이 있습니다.]

제 개인 R&R을 달성하는 과정에 있어서, 셀 전체의 R&R을 달성하는 과정에 있어서 매우 다양한 이슈들이 발생하였습니다. 그 중 대표적인 2가지 이슈를 소개해보고자 합니다.

첫 번째, GCP 접속을 위한 Key File 관리 문제 (보안)가 발생했습니다.

이 문제를 해결해보고자 셀원들과 함께 많은 방법을 생각해 보았습니다.

  1. GCS Bucket에 Key File을 저장한 뒤 gsutil 명령어를 사용해 가져오는 방법
  2. 사용할 VM 내부에 Key File을 넣어놓는 방법 → Scale Out에 적절치 않은 방법
  3. GitHub 저장소에 Key File 저장 → 보안에 제일 취약한 방법

하지만, 추후 늘어날 데이터 양에 따라 Batch Job을 원활히 수행하기 위해선 Scale Out이 가능한 방법으로 개발을 진행해야 한다고 판단하였습니다. 따라서 1의 방법으로 문제를 해결하는 것으로 의견을 모았고, 이에 알맞은 Shell File을 작성하여 문제를 해결할 수 있었습니다.

두 번째, 일정한 시간마다 VM이 중단되는 문제가 발생했습니다. Cloud StackDriver를 통해 VM의 실행, 종료 과정을 모니터링 하는 과정에 일정 시간마다 VM에서 실행했던 컨테이너가 정지되어 파이프라인이 정상적으로 작동하지 않는다는 것을 발견했습니다.

문제 요인을 찾기 위해 VM에 접속한 뒤, System Log들을 살펴보며 VM을 지속적으로 모니터링 해본 결과 다음과 같은 문제를 발견했습니다.

  • 도커를 이용해 띄운 GCE는 살아 있었지만, 컨테이너 안의 파이썬이 실행되지 못하고, 죽어버림.

Docker 컨테이너는 프로세스를 감싸는 하나의 공간이며, 프로세스가 가질 수 있는 메모리, CPU를 제한할 수 있기 때문에 이러한 문제가 발생한 것이라고 추측할 수 있었습니다. 따라서, 이 문제를 해결하기 위해 도커 컨테이너의 메모리 용량을 증가 시켰고, VM의 metadata에 기록한 startup-script에 VM 시작 시 기존의 RAM Memory Cache를 삭제하는 sudo sync && echo 3 > /proc/sys/vm/drop_caches 코드를 삽입했습니다. 이후, 장시간 반복적으로 VM을 작동 시키더라도 문제가 발생하지 않았습니다.

c.f.) 추가적으로, 캐시를 굳이 초기화하지 않더라도, 캐시 부하없이 코드가 정상적으로 작동할 수 있도록 도커 파일을 다이어트 시키는 작업을 추후 진행해보고자 합니다. (참고 링크 : https://yeomko.tistory.com/10)

2–5. Auto Scaling

그로스팀의 TSE 셀에서는 주기적으로 모델의 성능을 향상시키고 있습니다. 모델이 향상 됨에 따라 이전에 학습시킨 데이터들을 불러와 재학습 시켜야 하는 경우가 종종 생기곤 합니다. 재학습시킬 데이터가 많다보니, 단일 VM으로 학습시키면 몇 일이 소요됩니다. 이에 따라 다수의 VM을 사용해 병렬 처리가 가능하도록 코드를 개발할 필요가 있었습니다 (날짜를 기준으로 데이터를 분할하여 병렬 처리). 소스 코드에는 다음과 같은 기능을 구현했습니다. 민감한 정보를 제외한 일부 소스코드를 공개하였습니다.

  1. GCE API를 이용해 원하는 개수만큼 인스턴스 생성 및 startup-script에 날짜를 Argument로 전송
  2. 분석이 종료되는 즉시 GCE API를 이용해 인스턴스 삭제
  3. 추가적으로, 정상 작동을 위한 Shell File 및 Dockerfile 수정
[Dockerfile 수정]
[Instance 생성 자동화 API 활용 코드]
[출처 : https://nirsa.tistory.com/69]

3. 파이프라인 Testing 결과

CPU 및 네트워크 사용량 모니터링 및 빅쿼리 Destination Table 확인 결과 모든 데이터가 문제 없이 저장되고 있음을 확인할 수 있었습니다. 또한, 이 과정을 통해 TSE의 분석 내용을 Tableau에 조직화하여 정리 할 수 있었고, 디테일한 내용 및 다양한 특이 사항들을 지속적으로, 손쉽게 모니터링할 수 있게 되었습니다.

[Monitoring 현황]
[Delphi Project In Tableau]

4. 마치며

이번 파이프라인 구축 작업은, 그로스팀이 처음으로 자동화의 매력을 맛보게 된 하나의 프로젝트가 되었습니다. 이후에도 지속적으로 자동화를 시도해볼 수 있는 일들을 찾아 우리 팀이 각자 맡은 일에 좀 더 집중할 수 있는 환경을 만들어 나갈 것입니다. 추후 새로운 개발 내용으로 찾아 뵙겠습니다.

--

--