[소프트웨어 마에스트로 활동] 서버 구축기 (1)

Parker cho·2022년 7월 7일
0

시작하며..

시간이 얼마 흐르지 않은 것 같은데 어느 덧 소프트웨어 마에스트로 13기 활동을 시작한지 3개월이라는 시간이 흘렀습니다. 이번 포스팅에서는 프로젝트에서 필요한 딥러닝 추론서버를 어떤 방법으로 구축했는지 소개하겠습니다.


프로젝트

현재 팀원들과 함께 진행하고 있는 프로젝트는 기존에 구하기 어려운 악보들을 인공지능 모델로 근음을 잡아줘서 사용자에게 제공하고 또 모델이 잡지 못하는 세부적인 악보를 직접 수정 & 공유를 가능하게 함으로써 양질의 악보를 제공해주는 프로젝트입니다.

디지털 악보 생성 로직

악보생성로직은 아래와 같이 크게 3단계로 이루어져있습니다.

  1. 음원 분리 (목소리, 악기의 집합)
  2. 분리된 음원을 기반으로 근음 생성
  3. 근음을 바탕으로 디지털 악보화

순서도

개발에 앞서 각 로직이 어떤 데이터가 필요한지 생각해봤고 순서도를 그려봤습니다.

악보 생성 로직은 서비스 단위로 구분하여 도커 컨테이너로 독립된 환경을 구축했습니다.

왜 도커를 사용했는가?

음원 분리와 근음 생성은 서로 다른 오픈소스 모델을 사용하고 있었습니다. 하나의 환경에 전부 묶어서 구축하면 파이썬 라이브러리 의존성과 독립 환경이 너무 무거워졌기에 도커라이징을 통해 분리했습니다.

컨테이너 종류

  1. 컨트롤러 컨테이너
    • 각 서비스 사이의 비즈니스 로직을 담고 있는 서버입니다.
  2. 음원 분리 컨테이너
    • 음원 분리를 하는 컨테이너입니다.
  3. 코드 생성 컨테이너
    • 분리된 음원으로 부터 코드를 생성하는 컨테이너입니다.
  4. 악보 생성 컨테이너
    • 코드(midi) 데이터 후처리를 통해 디지털 악보를 생성하는 서버입니다.

네트워크

각 컨테이너는 도커 컴포즈로 묶어서 일괄적으로 실행합니다. 도커 컴포즈는 Default로 네트워크 브릿지를 생성해서 각 컨테이너가 공유할 수 있도록 합니다.

따라서 컨트롤러 컨테이너는 도커 컴포즈에 정의된 서비스 네임으로 각 컨테이너에 HTTP 요청을 보낼 수 있습니다.

자원 공유

각 컨테이너는 도커 볼륨을 통해 자원을 공유합니다. 볼륨에 존재하는 모든 데이터는 악보 생성이 완료된 이후에 사용하지 않는 데이터였기 때문에 모두 삭제하였습니다.


디지털 악보 생성 클라우드 흐름도

추론서버를 구축하고 나서 사용자로부터 요청을 받고 악보를 제공하는 전체로직을 그려봤습니다.

흐름도

악보 생성 클라우드 로직

  1. 악보가 이미 존재하면 사용자에게 바로 악보를 제공한다.

  2. 악보가 존재하지 않을 경우에 api 서버는 message broker 에게 악보생성 요청 메세지를 전송한다
    진행 상황(state)는 아래와 같다

    state 0: 음원 분리 전
    state 1: 음원 분리 완료
    state 2: 코드 생성 완료
    state 3: 악보 생성 완료
    • 이후 long polling 을 통해 사용자에게 현재 진행 상황을 알려준다
    • 요청을 처음 받았을 때 redis의 생성 상태를 get 한다.
      - 이전 요청에서 response 하는 순간 redis의 상태가 변하고 서버는 이벤트를 캐치 못한 경우를 대비한다.
    • long polling 이 끝나는 시점에 한번더 redis 의 상태를 get 한다.
      - long polling 이 끝나는 순간 redis 의 상태가 변할 수 있기 때문이다.
  1. 악보 생성 요청 메세지를 받은 추론서버는 redis를 통해 api 서버에게 현재의 진행상황을 알려준다.
  1. 악보 생성이 완료되면 추론서버는 mongo db 에 악보 데이터를 저장한다.

왜 long polling 방식을 채택했는가?

사용자가 현재 상태를 체크하려고 계속 request를 서버에 보내는 방식은 비효율적이라고 생각했습니다. 그래서 좀더 greedy 한 접근인 long polling 방식을 채택했습니다.

왜 Redis 를 사용했는가?

기존에 클라이언트는 요청을 보내고 나서 악보 생성이 어느정도 진행되었는지 알 수 없다는 문제가 있었습니다.

위와 같은 문제를 해결하고자 Redis의 Pub Sub 을 사용해서 특정 Redis Channel 을 바라보고 있는 api server 들에게 일괄적으로 현재의 상태를 전달해줘서 결과적으로 클라이언트가 현재 진행상황을 알 수 있도록 구현하였습니다.

보안

Mongo Database 와 redis 는 특정 security group 에서만 접근 가능하도록 하였습니다.

또한 api 서버와 추론 서버를 각각 다른 가용영역(subnet)에 위치시켰습니다.


마치며..

2년동안 회사 생활을 하면서 앱 개발, 프론트엔드 개발 등 다양한 개발 업무를 맡아봤지만 백엔드 개발은 전무했기에 항상 팀원들과 우리가 현재 설계한 방식에서의 문제점은 없는지 있다면 어떻게 해결할 것인지에 대해 고민하고 있습니다.

다음 포스팅에서는 이후에 발생할 문제점을 어떻게 해결했는지 또 추가한 기능에 대한 내용을 소개하겠습니다 ㅎㅎㅎ

profile
true nobility is being superior to your former self

0개의 댓글