아프리카TV API 프로젝트 개발 회고

Dochis·2024년 4월 28일
4
post-custom-banner

이 글은 제가 제공하고 있는 아프리카TV API 서비스인 SSAPI 서비스 개발에 대한 회고글입니다
https://doc.ssapi.kr/

왜 API를 만들었나?

SSAPI는 제가 처음으로 만든 아프리카TV의 API 프로젝트가 아닙니다.

최초는 아프리카도우미의 룰렛 기능을 개선하기 위해 "룰렛 집계기"라는 프로그램을 개발했을 때 이를 위해 API를 만들었고, 많은 개발자분들의 요청으로 이를 개방했던것이 시초가 되었습니다.

API를 개방하자 많은 개발자분들께서 다양한 의견과 리포트를 주셨습니다.

  • 아프리카도우미 자체에 버그가 좀 있다.
  • API의 안정성이 아쉽다 (누락 등)
  • 설정이 복잡하다

초기에는 이러한 문제를 서버의 아키텍쳐 수정과 편리한 GUI를 제공해 해결하고자 관리자 데시보드를 제작하고 아키텍쳐를 서버리스 기반으로 수정하는 프로젝트를 진행했습니다.
당시 서비스의 화면

그렇게 탄생한 '헛삯 LAP' 프로젝트가 탄생하였으나 근본적인 안정성 문제와 설정의 복잡성 문제를 해결하지 못했습니다.
더욱이 트레픽이 늘면서 폭증한 서버리스 서비스 비용이 부담되기도 했기 때문에 이 프로젝트는 진행 중 폐기되었습니다.

비용과 안정성 그리고 사용 편의성에 대한 대안이 필요한 상황이 되었습니다.

당시 문의 주신 많은 피드백을 바탕으로 아래와 같은 개선 목표를 정했습니다.

  • 서버리스 포기, 고사양의 물리 서버를 넉넉히 사용하자
    (비용과 갑자기 증가하는 트레픽 증가 대응위해)
  • 아프리카도우미 기반을 과감히 포기! 아프리카TV의 채팅을 직접 파싱하자
  • BJ N : 클라이언트 소켓 1 구조로 다수의 BJ 데이터를 하나의 소켓으로 제공받는 기능을 제공하자

그렇게 탄생된것이 지금의 SSAPI 서비스가 되었습니다.

아프리카TV 채팅 파싱기

파싱하는 방식은 기본적으로 채수현 개발일지 - 아프리카TV 실시간채팅 크롤링를 방식을 사용했습니다.

다만, SSAPI는 태생 부터가 수백명의 BJ의 데이터를 파싱해 API로 제공하는 것을 목표로 개발되었기 때문에 위 글 만으로는 한계가 명확했습니다.

가장 큰 문제는 바로 아프리카TV는 broad_nochat_no 값이 존재 하는데 이 값은 매 방송마다, 방송의 시청자 수에 따라 계속 업데이트 된다는 점 입니다.

이를 확인하려면 BJ 한명당 2번의 API 호출이 필요했는데, 당시 SSAPI에는 약 200여명의 BJ가 등록되어 1분 간격으로 호출하더라도 2번 * 200명 = 400회의 API 호출이 필요한 상황이었습니다.

물론, 1분 간격으로 할 경우 방송이 켜진 후 1분간은 API로 데이터를 제공하지 못하는 문제가 있었기에 실제로는 더 짧은 주기로 API를 호출하였고 이는 네트워크 대역을 초당 10MB/s나 잡아먹게 하는 문제를 낳게 됩니다.
당시 SSAPI 트레픽 지표

다시 생각하기

기존의 API를 2번 호출했던 이유는 DB에 저장된 BJ 목록을 통해 broad_no 값을 가져올 때 한번, chat_no 값을 가져올 떄 한번 총 2번을 호출했기 때문입니다.

하지만 서비스에 등록 된 BJ수가 300여명 가까이 되었을 땐 이 방법을 다시 고민해봐야 하는 상황이 되었습니다.

이유는 크게 2가지가 있었는데,

  1. 600번의 API콜은 상대적으로 적은양 이지만 해당 API콜로 인해 대역을 많이 사용 할 경우 향우 아프리카TV측에서 향후 조치를 취할 가능성이 있기에

  2. 당시 300명의 데이터를 모두 업데이트 하기 위해서는 최소 25초의 시간이 필요했고 API의 콜이 항상 성공하지는 못했기 때문에 운이 나쁘면 API 연결에 5분까지도 소요되기도 했기에

그러다 문득 그런 생각이 들었습니다.
아프리카TV에서 방송하고 있는 사람이 몇명일 까라는 생각입니다.
당시에는 2천명이 조금 넘는 수준으로 확인되었습니다.
아프리카TV메인

생각해보니 메인페이지의 구성에 사용하는 main_broad_list_api.php 파일에서 60명의 broad_no를 반환했고 방송 중인 사람이 2천명으로 계산할 때 가존 방식 보다는 훨씬 효율적이었습니다.

기존방식
BJ 300명 * API 콜 2번 = 1사이클을 위해 600번 콜

새로운 방식
1. 방송 중인 사람 2천명 / 60 = API 약 34번 콜
2. chat_no을 가져오기 위한 API 콜 = 300번
34 + 300 = 1사이클을 위해 344번 콜

더군다나, 기존 방식은 해당 BJ가 방송중이 아니더라도 방송이 켜지면 즉각적인 API를 제공하기 위해 지속적으로 해당 API를 호출해야 했는데

새로운 방식에서는 메인API에 없는 BJ는 방송중이 아닐테니까 이러한 인터벌을 사용하지 않음으로써 기존 방식대비 API 콜을 50% 가량 줄일 수 있게 되었습니다.
개선된 트레픽 지표

어떻게 하면 대역을 적게 쓸까

개선 된 방식으로 제공하더라도 300명 정도의 BJ 가 등록되었을 경우 초당 4~6MB/s 정도의 트레픽이 발생하는 상황이었습니다.
서버입장에서는 큰 트레픽이 아니지만, 개발자 분들께서 받는 트레픽을 아껴드리고 싶었습니다. (이게 다 비용이니까요)

그래서 우리 API는 대역을 적게 사용할 수 있도록 2가지 옵션을 추가했습니다.

2가지 옵션?

1. 수신할 이벤트를 선택할 수 있도록 하자

개발자분들께서는 채팅과 후원데이터를 모두 받을지 후원데이터만 받을지 선택할 수 있습니다.
대부분의 경우 후원데이터만 필요로 하시기 때문에 이 옵션은 메우 유용합니다.

2. 데이터를 압축하자

압축을 할 경우 압축과 해제에 시간이 다소 소요되기 때문에 이는 다소 고민이 했던 포인트입니다.

이를 위해 여러 압축 알고리즘을 비교해보았고 구글에서 개발한 Snappy 라이브러리가 초당 7~9천개의 데이터를 지연없이 압축/해제 할 수 있었습니다.

압축률이 떨어지긴 압축/해제에 많은 리소스를 사용하는것을 지양하고 싶었고 매우 빠른 속도라는 부분도 중요했기 때문에 높은 압축률을 일부분 포기한 선택이었습니다.

그래서 결론은?

이를 통해 300명 정도의 BJ가 등록되었을 떄 서버가 받는 트레픽은 4~6MB/s 정도이지만 API를 통해 개발자 분들이 실제로 받는 트레픽은 최대 1MB/s도 안되는 수준으로 최적화 할 수 있게 되었습니다. (후원 데이터만 수신 할 경우)

이는 아주 적은 트레픽이기 때문에 서버가 아닌 일반 데스크톱 환경에서도 걱정없이 사용할 수 있을것으로 기대됩니다.

또 300명 까지의 BJ가 등록되는 환경보다 10명 이하의 BJ를 등록하는 환경이 더 많을것으로 예상되기 때문에 이 경우 수백 KB/s 정도의 대역이면 충분히 사용할 수 있을것으로 기대되었습니다.

더 자세한 퍼포먼스 벤치마크 데이터가 궁금하시다면?

띵동! 추가 트레픽 도착!

3월 무렵엔 약 300여명의 BJ로 부터 초당 천개 정도의 데이터를 수신하였습니다.

당시 데이터 IO

하지만 그 뒤로 여러 대형 마인크래프트 서버와 다양한 컨텐츠 개발자 분들의 성원 그리고 치지직 지원 등으로 인해 피크 기준 초당 2300개의 트레픽을 안정적으로 처리 할 필요가 생기게 되었습니다.

물론 많은 트레픽은 아닙니다.
다만 문제는 구조 자체가 수 많은 소켓과 프로세서의 연결고리이다 보니 예측이 어려운 문제가 간혹 발생하였고 이로 인해 프로세서가 죽는 상황이 발생했습니다.

당시 하나의 프로세서로 치지직과 아프리카TV의 데이터를 제공했기 때문에 프로세서 하나의 사망은 전체 서비스의 중단을 의미했습니다.

이미 여러번의 알고리즘 개선으로 우리는 프로세서가 죽더라도 최대 10초 정도면 프로세서를 복구 할 수 있었지만, 이를 하나의 프로세서가 죽었다고 치지직과 아프리카TV의 모든 데이터가 10초간 제공되지 않는 상황은 피하고 싶었습니다.

이를 위해 프로세서를 분산해야 했습니다.
어려운 작업은 아닙니다.

치지직과 아프리카TV의 프로세서를 분리하고 그 두개의 프로세서의 데이터를 합쳐주는 브릿지 프로세서를 만들어주면되니까요!
그렇게 탄생 된 아키텍쳐

비용 문제 해결

아이너리 하게도, 비용 문제를 해결하기 위해 서버 기반으로 돌아왔는데 해결될 것으로 기대되었는데 사용자가 한참 늘면서 트레픽이 서버 기반으로 해도 비용이 여전히 비쌋습니다.

저는 AWS를 사랑하기 때문에 AWS를 많이 사용하지만 트레픽 비용과 서버비용을 합쳐 월 30만원 정도가 청구되었으니까요

하지만 우리 서비스 무료 서비스입니다. 컨텐츠 제작자 분들에게 부담을 주지 않기 위해 개발 된 프로젝트인 만큼 앞으로도 가능한 비용을 받지 않고자 합니다.

많은 트레픽과 컴퓨팅을 더 저렴하게 쓸 수 있도록 개선이 필요했습니다

AWS를 쓴건 저의 오래된 관성입니다.
7년 넘게 AWS를 쓰다보니 이젠 AWS로 배포하는게 편합니다.

하지만 그런 생각이 들더라구요
아주 오래전? 8년전? 10년전 쯤 생각해보면 2코어 4기가 메모리 서버가 이렇게 비쌋던가? 라는 생각이요
생각해보니 그렇지 않았던것 같습니다.
일 하면서 수백~수천만원씩 결제할 떈 생각해보지 않았던 부분

저는 10년 전쯤에 가상서버를 cloudv나 PHP스쿨 같은 서비스를 썻습니다.
정확히 기억안나지만 2만원도 안되는 금액으로 가상서버를 싸게 썻던 기억이 있습니다.

cloudv를 오랜만에 들어가보니 클라우드 서비스를 취급하고 있길래 가격을 한번 비교해보았습니다.

당시 서버는 2코어의 8기가 메모리의 단일 서버였습니다.
가격비교 자료
물론 동일 사양에 동일 조건은 아니지만 서버를 비교했을땐 AWS에서 예약인스턴스를 구매하더라도 cloudv이 훨씬 저렴했습니다

서버 비용 이외에도 트레픽 비용 역시 AWS의 경우 GB당 137원 정도이지만, 1기가 용량을 약 70원 정도에 사용할 수 있었습니다.

개발을 오래 하면서 Vercel과 AWS만 주구장창 쓰다보니 다른 서비스를 비교하는 습관을 잃어버린것 같아 반성하면서 cloudv로 옮기기로 결정했습니다.

cloudv도 클라우드 방식이다보니 필요할 경우 서버의 사양을 간편하게 조절할 수 있었거든요!

당시 AWS에 납입하는 월 비용이 월 32만원 정도 되었는데 옮긴 후 약 15만원 정도로 50% 이상 절감을 기대하고 있습니다.

확실히 AWS에 비해 인터페이스나 기능 지원 측면에서 아쉽긴 하지만... 가격이 50% 이상 절감되는 걸요!

지금까지의 성과

SSAPI 서비스는 올해 2월 말 출시하여 약 2달 만에 API를 통해 제공 된 누적 후원액이 4억 돌파와 등록 BJ 300명 돌파라는 성과를 이루어냈습니다.

2개의 대형 마인크래프트 서버와 협업하였으며 여러 컨텐츠 제작자 분들과 버츄얼 예능 그룹 뻐스시간팀과도 프로젝트를 함께 하기도 했습니다.

출시 한 지 2달만에 많은 개발자분들, 컨텐츠 제작자분들과 소통하여 치지직과 아프리카TV를 모두 지원하게 되었습니다.

성과 자세히 알아보기

앞으로는...

앞으로도 많은 개발자 분들과 소통해 나가면서 수요가 있는 API와 기능들을 만들어 나갈 예정입니다.

현재 예상하는 방향은 아래와 같습니다.

  1. 더 많은 플렛폼 지원
    현재 또 많은 개발자 분들의 요청으로 트윕과 투네이션 그리고 유튜브 라이브 지원을 문의받고 있습니다. 추가로 지원할 플렛폼에 대한 고민을 하는 중 입니다.

  2. 다 많은 API 종류 지원
    현재 아프리카TV만의 도전미션과 대결미션 등의 API는 지원하지 않고 구독이나 채팅방 입/퇴장 API 등이 지원되지 않는데 차차 지원해나갈 예정입니다.

  3. 서버 이중화 구성
    아직까진 단일 서버로 구성되어 페일 오버에 대한 대책은 없는 상황입니다. 비용문제와 구성의 기술적 어려움 문제가 있긴 하지만 이 부분도 기회가 되면 차차 개선해보면 좋겠습니다.

  4. 자체 룰렛과 도우미 기능 지원
    아프리카도우미를 기반으로 하지 않기 때문에 룰렛도우미 같이 룰렛에 대한 기능과 API를 제공하지 못하는 점은 많은 개발자분들로 부터 아쉽다는 이야기가 나오고 있어 자체적인 룰렛 시스템 구축, 도우미 기능을 구축하고 이를 API로 제공하는 것을 현재 고려중입니다.

해당 API에 대해 궁금하신 점이 있으신 분은 디스코드 채널이나 @hutsak로 DM 주시길 바랍니다

긴 글 읽어주셔서 감사합니다.

post-custom-banner

0개의 댓글