DevOps

[AWS/나만의 무기 프로젝트]서비스 파이프라인 클라우드 배포 현황(EC2 서버 배포 + S3 스토리지 mounting)

Woonys 2022. 2. 22. 21:52
반응형

이전까지 로컬에서 구축했던 프로젝트의 파이프라인은 아래와 같은 형태였다.

이를 클라우드 상에서 배포해 안정적으로 운영하기 위해 지금까지 EC2 서버 구축 및 S3 스토리지 mounting 작업을 진행했다. 현재 서버는 클라우드 상에서 안정적으로 동작하며 S3 스토리지에 스트리머 영상을 실시간으로 저장하고 있음을 확인했다. 따라서 바뀐 파이프라인은 아래와 같다.

 

 

1. 클라이언트 

클라이언트인 스트리머와 시청자는 RTMP(스트리머->미디어 서버)/HLS(미디어 서버->시청자) 프로토콜을 이용해 서버로 각각 영상을 송출하고 받는다. 

 

2. 서버

전체 서버는 익스프레스로 구성되어 있으며, 내부에는 미디어 서버와 커뮤니케이션 서버로 나뉘어져 있다. 이전까지는 로컬에 구축해놨으나 현재는 EC2에 원격으로 배포한 상태이다.

 

1. 미디어 서버: node-media-server

 

미디어 서버는 오픈 소스인 Node Media Server로 구성되어 있다. RTMP 프로토콜을 통해 스트리머로부터 받은 영상을 ffmpeg로 인코딩/디코딩해 HLS 프로토콜로 시청자에게 전송하는 역할을 담당한다. 왜 RTMP/HLS 프로토콜을 사용했는지에 대해서는 따로 글을 쓸 계획이나, 이 글을 참조하면 쉽게 이해할 수 있다.

 

2. 커뮤니케이션 서버: socket.io 모듈

 

클라이언트 간 통신을 위한 커뮤니케이션 서버로는 웹소켓 기반 모듈인 socket.io를 이용한다. socket.io는 미디어 송출을 제외한 스트리밍 룸과 관련한 CRUD 역할 및 채팅 전송을 담당한다. 여기(링크)에 가면 어떻게 socket.io를 이용해 채팅 서버를 구축하는지에 대한 상세한 내용이 나와있다.

 

3. 스토리지: 로컬 드라이브 -> EC2 인스턴스 스토리지(EBS) -> AWS S3

 

미디어 서버에서는 실시간으로 방송 중인 스트리머의 영상을 시청자에게 송출해주는 한편, 이를 스토리지에 MP4 형태로 실시간으로 저장한다. 방송이 끝나고 나면 해당 스토리지에 저장된 방송이 '지나간 라이브' 목록에 추가되어 시청자들은 해당 탭에 들어가 지나간 방송을 볼 수 있다. 즉, 여기서 스토리지 역할은 온디맨드 스트리밍이다(원래는 현재 라이브 중인 방송의 지난 구간 시청 기능을 지원하려 했으나 이는 리소스가 많이 들 것으로 판단해 기능을 제거하고 방송 입장 시점 이후로 영상을 캐싱해 30초/1분 전으로 돌아가기 기능은 제공할 계획).

 

처음에 로컬 환경에서 구축했을 때는 로컬 드라이브에 영상을 저장하는 형태였으나, 이를 클라우드에 올리면서 EC2 인스턴스 스토리지를 쓰는 방식으로 바뀌었다. 하지만 EC2 스토리지를 그대로 사용하게 될 경우, 여러 문제가 발생하기에 최종적으로는 S3를 사용하기로 확정했다. 그러면 어떤 문제가 있는지 EC2 인스턴스 스토리지와 S3를 간단히 비교해보자. (여기서 우리의 목적은 방송이 종료된 라이브를 저장해 다시 보기 기능을 제공하기 위한 온디맨드 스트리밍용임을 상기하자.)

 

1. 용량 -> 프리 티어 기준으로 EC2 스토리지 용량이 더 크지만 용량의 확장성은 S3가 좋다.

 

프리 티어를 기준으로 각 스토리지가 제공하는 최대 용량을 살펴보자.

  • EC2 인스턴스 프리 티어 제공 최대 용량: 30GB
  • S3 프리 티어 제공 용량: 5GB

엥? EC2가 무료 제공 용량이 훨씬 큰데?? 이렇게만 보면 EC2가 더 좋아보이긴 한다..?

 

하지만 아래 비용과도 커플링되는 문제인데, S3는 기본적으로 무제한 용량이 제공되고 거기서 쓰고 있는 용량만큼만 가격을 매기는 반면, EC2 스토리지(이때의 스토리지는 정확히 EBS에 해당 - 인스턴스 스토어와 EBS 차이 참조)는 EC2 생성 전에 용량 크기를 정해야 하고 그 용량만큼 가격을 낸다. 이렇게 되면 두 가지 문제가 발생한다.

 

1) 신청한 용량 중 사용하고 있지 않는 유휴 용량에 대해서도 불필요한 비용을 지불해야 한다.

2) 만약 스토리지에 저장된 데이터가 신청한 용량을 넘어서게 되면 여기서 용량을 확장하는 게 아니라 새로운 볼륨을 신청하고 거기에 옮긴 뒤, 기존 스토리지를 반납하는 식으로 진행해야 한다. 즉, 용량의 확장성이 떨어진다.

 

S3는 주어진 프리티어 5기가를 넘어섰다고 해서 새로운 스토리지로 옮기는 게 아니라 추가된 용량에 비례해 돈만 내면 그만이며 최대 5TB까지 한 객체에 대한 용량을 확장할 수 있다는 장점이 있다.

 

2. 비용 -> S3가 대체로 저렴한 편이나 I/O 요청이 많아질 경우 더 비쌀 것(해당 프로젝트에서는 프리 티어 한도를 넘기지 않을 것이기에 고려 X)

 

이 글을 쓰기 전에 막연히 리서치했을 때는 S3의 비용이 인스턴스 스토리지보다 쌀 것이라 생각했다. 물론 S3가 효율적으로 스토리지를 쓸 수 있어 대체로 더 저렴할 것으로 보이지만 특정 상황에서는 S3가 비쌀 수도 있다. 이 중에서 가장 크게 고려해야 할 요소는 I/O 횟수. S3의 요금 정책 특징 중 하나는 단순히 사용하는 용량 이외에도 I/O 횟수를 고려한다. 쉽게 말해, '몇 번 GET/PUT 요청을 받았는가?'이다. 만약 I/O가 매우 빈번한 환경이라면 S3가 비용 면에서 더 비쌀 수 있다는 것.

 

물론 우리는 프리 티어 한도 내에서 쓸 것이기에 현재 수준에서는 둘 다 비용 자체가 그렇게 문제되지는 않을 것으로 판단했다.

 

3. 클라이언트 동시 접근 문제: S3의 압승. 스트리밍 서비스에서 S3를 써야 하는 이유

 

EC2 인스턴스 스토리지는 EC2 가상 머신에 마운트해서 사용하기에 반드시 EC2 서버에서만 접근이 가능하며, 단일 EC2에 한해서만 접근이 가능하다. 이를 위해 EFS라고 해서 복수의 EC2가 접근 가능한 스토리지를 제공하나 우리의 핵심은 여러 EC2를 쓰는 게 아니기에 이 부분은 중요하지 않다.

 

하지만 S3는 꼭 EC2 서버를 거치지 않고도 복수의 클라이언트가 접근 가능하다. 서버리스에서 AWS Lambda와 함께 S3를 쓰는 이유가 바로 여기에 있다. 우리 서비스 역시 복수의 시청자가 각각 지나간 영상에 대해 시청을 요청할 것이기에 이 문제를 해결하기 위해서는 S3를 스토리지로 쓰는 것이 적합하다고 판단했다.

 

다각도로 고민한 끝에 S3를 스토리지로 사용하기로 결정했다. 이를 위해 EC2에 S3를 마운팅하여 실시간 영상을 송출하면서 동시에 영상을 S3 스토리지에 저장하는 파이프라인을 구현했다. (EC2에 S3를 마운팅하는 방법은 링크 영상을 참조 - 가장 설명을 잘함!)

 

4. DB

현재는 mongoDB를 사용해 유저 정보 및 스트리밍 room에 대한 스키마를 mongoose로 셋업해둔 상황이다. 이 역시 로컬에서 구축했으나 웹 서버를 EC2 위에 올리면서 함께 EC2 위에 올라간 상황.

 

 

추가로 고려해야 할 요소

자잘한 버그 해결, 2채널 동시 송출 로직 구현과 지나간 영상을 S3에서 클라이언트로 송출하는 로직을 구현하면 서비스를 배포할 수 있는 환경 셋업은 얼추 완료된다. 여기서 보다 안정적으로 서비스를 제공하고 싶다면 아래 두 가지를 생각해볼 만 하다.(지금 규모에서 필수는 아님)

 

1. 서버리스 migration(AWS Lambda + S3)

현재 구축한 파이프라인을 서버리스로 migration하는 것. 이렇게 작업하면 두 가지 이점이 생긴다.

 

1. 서버 운영 비용을 획기적으로 절감 가능

2. 새로운 feature 도입 시 드는 비용 절감

 

이와 관련해서는 <PlayOn! Sports>가 라이브 스트리밍 서비스를 제공하는 과정에서 서버리스로 migration한 내용을 AWS re:invent에서 발표한 내용을 참고하면 좋을듯(관련 medium 글). 간략하게 아래 세 장으로 설명 가능하다.

이들이 기존 아키텍쳐에서 서버리스를 도입해야겠다고 느낀 이유다. 이 중 우리 역시 공감하는 문제를 살펴보면

 

1. RTMP -> HLS 프로토콜 변경

2. 운영에 드는 오버헤드 최소화

3. Adaptive bitrate streaming 적용(dynamic한 네트워크 환경에 맞춰 영상 화질을 조정해 송출하는 방식)

4. 비용 최소화

5. 명확한 인코딩 워크 플로우

 

따라서 아래와 같이 AWS lambda와 S3를 이용해 아키텍쳐를 변경하였고, 잘 워킹하지만 다른 tradeoff가 있었다는 발표이다.

우리 역시 현재는 EC2 서버에서 동작하는 환경이며 이를 더욱 효율화하려면 서버리스를 도입해보는 것이 좋을 수 있겠지만 현재로서는 투머치인 감이 없잖아 있다.

 

하지만 라이브 스트리밍이 아닌 온디맨드에 한해서만 서버리스를 적용해보는 것도 나쁘지 않을 듯. 이에 관련해서는 이 글을 나중에 참고하자.

추가: 라이브 스트리밍 & 온디맨드 스트리밍 정리 글

 

2. CDN (AWS CloudFront): 미디어 캐시

 

위에 링크를 걸어둔 추가 글을 읽어보면 CDN의 중요성에 대해 깨달을 수 있을 것이다. CDN은 한마디로 미디어 서버에 캐시를 두는 것인데, CDN이 없다면 모든 클라이언트는 하나의 미디어 서버에 접근할 것이고 그로 인해 부하가 커질 것이다. 이를 방지하기 위해서는 CDN이 필요하다.

 

AWS에서 제공하는 CDN으로 cloudfront가 있다. 이 역시 프리 티어가 있어 적용해볼만 할듯. 아직 제대로 테스트해보지 않았지만 지금 EC2 서버에 여러 대의 클라이언트가 접근하면 터지지 않을까 싶다. 이를 위해서는 두 가지가 있을텐데, 서버의 메모리를 늘리거나(혹은 스왑 영역을 늘려 프리 티어 안에서 어떻게든 해결하든지) 아니면 서버와 클라이언트 사이에 CDN을 두거나. 오히려 1번 사항보다 안정적인 데모 시연 측면에서 2번 요소가 더 중요할 수 있겠다 싶다.

 

반응형