일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 스택
- Unity2D
- 구현
- 스파르타내일배움캠프
- Inventory
- FSM
- 이분탐색
- UnrealEngine
- C++
- 스파르타내일배움캠프TIL
- 문자열
- 순열
- Photon
- 알고리즘
- Unity
- 내일배움캠프
- QueryDSL
- 포톤
- 언리얼엔진
- 유클리드호제법
- c#
- Firebase
- UE4
- BFS
- 해시
- 프로그래머스
- 유니티
- Unity3d
- unityui
- 워크플로
- Today
- Total
개발 낙서장
[TIL] 내일배움캠프 81일차 - 대규모 트래픽 처리 본문
오늘의 학습 키워드📚
대규모 트래픽
순간적으로 많은 요청이 발생해 서버에 부하가 발생하는 것을 대규모 트래픽이라고 말한다.
어느 정도의 수준부터 대규모 트래픽이라고 부르는지는 모르겠지만 1초 안에 수백 개 이상의 요청이 발생할 경우부터 대규모 트래픽이라고 해도 되지 않을까 싶다.
대규모 트래픽 처리가 중요한 이유는 너무나도 간단하다. 서버가 퍼지면 안되기 때문이다!!
모든 서비스는 서버를 기반으로 실행되고 서버에 요청을 보내고 서버로부터 응답을 받는다.
그런데 순간 대규모 트래픽이 발생하여 서버가 다운되면 발생했던 수많은 요청은 갈 길을 잃을 것이고 사용자들은 두 번 다시 서비스를 이용하지 않을 것이다.
처리하는 방법은 정말 정말 여러가지가 있다.
가장 기본적으로 쿼리를 최적화해 DB 부하를 줄이고 최대 요청 개수나 처리 개수를 제한하여 서버의 부하를 줄이고 서버 스케일링이나 로드 밸런서를 활용해 발생하는 트래픽을 분산하거나 트래픽에 맞게 서버 용량을 유동적으로 조절하는 등 이 외에도 내가 알지 못하는 수많은 방법이 있을 것이다.
나는 수많은 방법 중 메세지 큐를 이용해 처리량 및 처리 속도를 조절하는 방식을 사용했다.
메세지 큐
먼저 큐(Queue)는 선입선출(FIFO - First In First Out) 방식의 자료구조이다.
먼저 들어온 데이터부터 나가기에 순서가 보장되어야 하고 데이터 중복이 발생하면 안 되는 기능에 사용한다.
메세지 큐는 큐의 특성을 활용한 통신 처리 방식인데 기존에는 요청이 클라이언트 - 서버 직접 통신했다면 메세지 큐는 중간 다리를 하나 놓아주어 요청을 조절하고 전송하는 역할을 한다.
클라이언트에서 요청을 보내면 메세지 큐에 순서대로 저장되고 큐에서 서버로 요청 메세지를 전송하여 데이터를 처리한다.
(클라이언트 - 서버 뿐만 아니라 다른 시스템 혹은 서비스 간 통신에서도 쓰인다.)
시스템 간 직접적인 의존성을 제거해 느슨한 결합을 제공하며 비동기 및 병렬 처리가 가능하여 서버의 부하를 줄일 수 있고 사용자 입장에서도 응답 속도가 개선되는 등의 장점이 있다.
Redis와 SQS
현재 프로젝트에서 기존에 주문 및 재고 관리 부분에서 Redis의 Single Thread 방식으로 동시성 제어 및 데이터 처리를 했었다.
동시성 제어는 잘 되었지만 대규모 트래픽에 대한 대비가 되지 않았기에 Redis의 락 경합 및 서버 불안정 등의 위험이 발생할 수 있었다.
하지만 Redis를 사용하기 위해 이를 전부 대비하는 것은 개발 비용 낭비라고 생각했고 다른 방법을 모색하던 중 AWS의 SQS를 찾게 되었다.
SQS는 두 가지 방식의 메세지 큐를 제공하는데 하나는 처리 속도가 매우 빠르지만 데이터의 순서가 보장되지 않고 중복이 발생할 수 있는 기본 방식이고 다른 하나는 FIFO 방식을 사용해 처리 속도는 살짝 느리지만 데이터의 순서가 보장되며 중복을 제거해 주는 방식이 있다.
해당 프로젝트는 주문 및 재고 관리가 확실하게 되어야 하고 대규모 트래픽이 발생할 경우 동시성 제어 또한 되어야 하기에 FIFO 방식을 사용했다.
클라이언트에서 주문 요청을 하면 SQS로 주문 정보에 대한 메세지를 보내고 서버에서는 이를 하나씩 수신하여 처리하였다.
Redis와 SQS의 차이를 보기 위해 JMeter로 부하 테스트를 진행했고 1초에 1000번의 요청을 5번씩 발생시켜 평균 및 최소, 최댓값을 도출했다.
[Redis]
표본 수 | 평균 | 최소값 | 최대값 | 표준편차 | 오류(%) | 처리량 |
5000 | 2283 | 80 | 4464 | 1031.078 | 0 | 193.91042 |
[SQS]
표본 수 | 평균 | 최소값 | 최대값 | 표준편차 | 오류(%) | 처리량 |
5000 | 541.75 | 27 | 1451 | 150.5425 | 0 | 722 |
결과는 SQS가 Redis에 비해 무려 약 76%나 빠른 속도를 보여주었다.
Redis 방식은 Redis에서 재고를 관리하기에 Redis에서 재고를 가져와 감소하고 DB에 저장하는 과정을 거쳐 Redis 통신 및 데이터 접근 횟수가 많아 시간이 오래 걸렸고 또한 기존에 사용했던 방식은 요청-응답 과정을 거쳐야 하기에 지연 시간이 발생했다.
하지만 SQS는 발생한 요청을 먼저 메세지로 큐에 전송하고 서버에서는 비동기적으로 큐에서 메세지를 수신해 처리하기 때문에 굉장히 빠른 처리 시간을 보였고 DB에 직접 접근하여 처리하기 때문에 상대적으로 빠른 처리가 가능했다고 생각한다.
오늘의 회고💬
대용량 테스트는 처음 해보는데 테스트 환경을 계획하고 구성하는 게 마냥 쉽지만은 않았던 것 같다. 그리고 실제로 테스트를 해보니 평소에는 몰랐던 오류들이 종종 발생해 대용량 트래픽 처리 과정에서 발생하는 오류 대응 방안도 생각해 볼 필요가 있는 것 같다.
내일의 계획📜
배포 환경에서 웹 소켓이 HTTPS에서는 에러가 발생하는데 로컬에서 HTTPS 환경을 구성해 돌려보니 정상적으로 작동돼 매우 매우 당황스럽다.....
내일은 이 부분을 좀 더 파고들 것 같은데 잘 모르겠다.
'Java > Sparta' 카테고리의 다른 글
[TIL] 내일배움캠프 82일차 - WebSocket Connection Failed (0) | 2024.04.25 |
---|---|
[TIL] 내일배움캠프 80일차 - 기술 면접 대비 (0) | 2024.04.23 |
[TIL] 내일배움캠프 79일차 - SSE (0) | 2024.04.19 |
[TIL] 내일배움캠프 78일차 - SQS 동시성 테스트 (0) | 2024.04.18 |
[TIL] 내일배움캠프 77일차 - AWS SQS FIFO (0) | 2024.04.17 |