[AWS Community Day 2020 세션 레포트] 전 세계 팬들이 모일 수 있는 플랫폼 만들기 – 강진우님 (beNX)
안녕하세요! 클래스메소드 주식회사 의 김태우입니다.
작년에는 한국에서 AWS 소모임이나 각종 행사들이 열릴때마다 항상 가고싶어서 부러워하곤 했는데요..ㅋㅋ 올해부터는 적극적으로 한국의 AWS 행사에도 참여하고자 합니다! 그런 의미에서 저도 지난 1/21(화) 에 열린 AWS Community Day 2020 에 다녀왔습니다.
본 블로그는 beNX 의 강진우님께서 발표하신 세션을 참가하면서 개인적으로 노트했던 내용을 정리한 글입니다.
본 행사의 다른 블로그도 작성해두었으니 관심있으신 분들은 읽어주세요 :)
[AWS Community Day 2020 세션 레포트] 전 세계 팬들이 모일 수 있는 플랫폼 만들기 – 강진우님 (beNX)
[AWS Community Day 2020 세션 레포트] 스푼라디오 일본에서 한국으로 이전하기 – 최상기님 (마이쿤)
목차
세션 슬라이드
발표자 소개
- 강진우님 (DevSecOps 팀장, beNX)
- 리눅스 커널이야기의 저자
- Brunch 블로그
세션 소개
글로벌 서비스에서 트래픽과 관련한 내용을 이야기하고자한다. 순간적으로 많은 트래픽이 유입되는 서비스에 도입이 되면 좋겠다.
발표내용 노트
beNX 의 트래픽 패턴
- 일반적으로 서비스의 트래픽 패턴은 시간의 흐름에 따라 완만하게 높아지거나 낮아지는 형태
- beNX 의 트래픽 패턴은 이러한 일반적 패턴과는 다름
Weverse 서비스의 ALB 트래픽
- 그래프의 단위가 분 단위이기때문에 보이는 값은 굉장히 큰값임.
- 평상시에는 거의 제로인데, 특정시간에 몰림
- 슬라이드를 만든때가 보름 전인데, 지금은 이것보다 더 큰 요청이 들어온다.
- 1분에 270만개의 요청이 순간적으로 들어옴.
- 평상시랑 비교하면 100배정도의 트래픽양
이런 경우에는 어떻게 서버 운영을 해야할까?
- 오토스케일링을 활용해야하지만, AutoScaling Policy 에 의존하면 대응이 한 템포 늦음
- AutoScaling Policy 에 의존하면 유저는 버벅거리는 앱을 보거나 아예 안열리는 앱을 보게됨
- 그렇다고해서 한순간을 위해 수많은 서버를 운영할 수도 없음
- 그럼 사전에 증설되어야하는 순간을 감지할 수 없을까?
Event Driven Autoscaling
- 어떤 이벤트를 정의행야할까?
- Predefined Event : 미리 정의되어 있는 이벤트 (ex. MD 판매 이벤트)
- Undefined Event : 미리 정의되어 있지 않은 이벤트 (ex. 아티스트들의 글 작성)
- Undefined Event 의 경우 정확한 사전 대응은 힘들다.
Predefined Event
- 언제 발생할지 알고 있기 때문에 사전 대응이 가능하다
- 핵심은 사람 대응이 최소화된 자동화
- 아키텍쳐
- 이벤트를 캘린더에 등록
- 람다가 주기적으로 캘린더 이벤트를 조회 (현시간 기준으로 몇시간 이내에 발생할 이벤트가 있는지 등이 조건)
- 람다함수가 조건에 맞는 이벤트를 찾아내면 ASG 그룹 수정 (Desired / Min / Max 값을 수정)
- 람다함수는 작업 결과를 Slack 에 전달
- 이 순간부터 모니터링 대기를 하고있고, 추가 대응이 필요한 지 확인
Undefined Event
- 언제 발생할 지 알 수 없기 때문에 사전 대응이 불가능
- 이때 상당한 양의 트래픽이 발생함
- 정말 방법이 없을까?
- 푸쉬서버를 활용 --> 푸쉬를 보낼게 생겼다는 건 이벤트가 발생한 것
- 푸쉬서버를 오토스케일링의 시작점으로 삼아보자
- 아키텍쳐
- 푸쉬서버에서 푸쉬 발송 (FCM 등)
- 비동기적으로 그와 동시에 API Gateway 에 Autoscailing API 호출
- Lambda 함수 호출 ※ 아래에 보충설명
- ASG 수정 (Desired / Min / Max)
- 작업 결과를 슬랙 채널에 공유
- Undefined event 가 발생했다는 걸 모니터링하고 추가 작업 진행
※ 보충설명
- 그 외에도 CW Event 를 통한 주기적 호출 --> Undefined event 가 종료되었는지를 확인
- 종료는 2가지로 정의
- 이벤트 유지 시간 및 트래픽량이 기준이 됨
- 우선은 30분간 증설된 인스턴스를 유지시키는 폴리시 등
해결해야 할 과제들
- AutoScaling 에 소요되는 시간의 최소화 --> 배포과정 최적화
- 증설되는 동안 최대한 버티기 --> 인스턴스 성능최적화
튜닝 전의 배포 아키텍쳐
- JAR 배포해서 API 서버가 생성됨 (굉장히 심플함)
- 오토 스케일링 같은 경우도 똑같이 진행됨
- 전체 과정이 5분 정도 소요
- 그냥 AMI 띄워서 Ansible 실행만 시키면 끝나니까 굉장히 심플함. 근데 5분이나 소요됨.
개선된 배포 아키텍쳐
- JAR 배포 직전의 커스텀 AMI 를 생성 (Packer 를 사용)
- 전체과정이 3분 정도 소요
- 목표는 1분 안에 증설 완료
인스턴스 성능 최적화
개인적으로 이 부분이 정말 유익했다고 생각합니다!! 최고!!
- 잘 튜닝된 t3.medium, 열 c5.xlarge 안 부럽다
- 성능 최적화의 핵심은 모든 리소스를 최대한 활용하는것 (CPU, 메모리 등을 어떻게 쥐어짜고 쥐어짜고 또 쥐어짜낼 수 있느냐)
장애상황의 CloudWatch 메트릭
- CPU 사용량이 1% 도 안됨.
- 근데 이거 장애 상황임
- 튜닝이 안되면 활용가능한 리소스가 펑펑 남아도는데도 불구하고 장애가 발생하는 상황이 발생
- 튜닝을 하지 않아서 10배 정도의 서버를 증설해서 대응해야하는 경우도 생김
OS의 디폴트 설정은 대부분 낮음 (p39 ~ )
- (직접 찍은 사진 해상도가 좋지 않아서 슬라이드 39페이지부터 참조해주세요)
- OS 디폴트 설정으로 인해 애플리케이션 설정에 영향을 받지 않아야한다.
- 그러니까 이걸 다 적절하게 바꿔야한다는 의미
- 빨간 부분은 특히 더 증요하게 생각하시는 부분.
- 현재 운영중인 서비스에서는 OS 디폴트값보다 훨씬 크게 사용하고 있다.
- 애플리케이션 쓰레드 개수와 동시 접속 가능한 소켓 수에 영향을 준다. (매우매우 중요함)
- 네트워크 성능튜닝 관련 글 - 강추!!
nginx 의 성능에 직접적으로 영향을 주는 가장 중요한 항목 (p41 ~ )
- 특히 리버스 프록시로 사용하는 경우 worker_conenction 은 클라이언트/서버 양쪽을 고려한 커넥션이므로 1024 라고 써도 512 밖에 안됨
- 이 경우에는 CPU 가 튀지도 않는데 장애가 남
Tomcat 의 기본 설정화면 (p47)
- maxThreads
- minSpareThreads
- 이거 디폴트로 쓰면 장애가 남.
- 특히 쓰레드 수가 낮으면 CPU 사용률이 낮아도 장애가 남
- "충분한" 숫자의 커넥션 풀 설정이 필요
- 인스턴스의 CPU 코어 수에 맞게, 메모리 용량에 맞게 설정하는 것이 중요함
- 개인적으로 메모리보다는 CPU 에 맞춰서 튜닝하는게 효과적
- spare threads 가 너무 큰가 싶기도 하겠지만 적으면 순간적으로 트래픽이 들어올 때 다 만들어야하므로 충분히 크게 주는게 좋음
스프링부트에 커넥션 풀 쓸때 설정 (p48)
- RDS 의 최대 커넥션 갯수와 밀접한 관련이 있음. 잘 보고 띄워야함.
- 여기서 100개를 주면 RDS 에서는 10000개의 커넥션을 처리하게끔 하는것. 유의해야함.
다음단계를 위한 준비
- 더빨리 스케일 아웃을 해야함
- 스케일아웃까지 1분컷을 위해 고려하고 있는 것들
- EKS on Fargate
- EC2 Hibernate
세션 후의 Q&A
Q. 구체적으로 어떤 리소스에 대한 요청에 대한 트래픽이었는지 궁금하다. 동적컨텐츠라면 CloudFront 도 고려할 수 있지 않나?
A. 결국에는 API 서버를 거쳐야하는 트래픽이라 CloudFront 는 고려대상이 아니다. 댓글은 2만개 정도가 순식간에 달리고 그 이후로는 서비스 상에서 정책적으로 댓글을 아예 받지도 않는다. 캐싱이 전혀 먹히질 않는다.
Q. 캐시 레이어에서 대응은 어렵나? 3분 정도는 캐시에서도 충분히 버틸 수 있을것 같은데?
A. 캐싱이 문제가 아니라 트래픽 양 자체를 인스턴스에서 못버틴다. 평소에 20대 정도를 운영하다가 트래픽이 급증하면 130대 정도까지 올라간다. 비용적인 면에서 생각해도 문제는 없다. 급증한 트래픽이 주로 20분 정도 유지가 되는데 이에 대해서도 비용면에서 초당 과금방식이기때문에 효율적이라 할 수 있겠다.
세션 후기
아무리 클라우드 기술이 멋지고 훌륭해도 모든 케이스를 클라우드 상의 기능으로는 커버할 수 없다는걸 다시한번 느낄 수 있었던 정말 유익했던 세션이었습니다. 특히 리눅스 커널 디폴트 설정이 일반적으로 굉장히 낮게 설정되어있다는 사실은 처음 알았던 사실이라 이 부분 관련해서도 공부해야할 필요성을 느꼈습니다.
네트워크 상의 설정으로 신경써야할 대표적인 항목들을 정리해보면,
- 각종 스레드 수
- 커넥션 풀
- 워커 프로세스/스레드 수
등이 중요한 지표로 작용하는 것 같습니다.
또한, 위와는 다르지만 비슷한 사례로 ECS 를 사용한 컨테이너 환경의 경우, EC2 보다 훨씬 더 빠르게 스케일 아웃을 할 수 있습니다. 이런 경우, Autoscaling Policy 에 의존해도 괜찮지만, 이보다 더 빠른 초간격 스케일아웃을 하고 싶은 경우에는 Step Functions 를 CloudWatch Event 를 통해 초단위로 주기적으로 호출하는 방법도 있습니다. 일본어 블로그이긴 하지만, 그림을 많이 포함하고 있으므로 일본어를 읽지 못하시는 분들도 대략 훑어보시면 어떤 내용인지 아실 수 있을 것 같습니다.
위 내용은 AWS Samples 의 깃헙 레포지토리에 등록된 코드를 직접 실행시켜본 내용입니다.