대용량 트래픽을 처리하는 방법
대용량 트래픽을 처리하는 방법
이전에 진행했던 티켓 예매 프로젝트를 통해 대용량 트래픽을 처리하는 방법을 알아봤다.
티켓 예매 서비스 특성상, 콘서트를 예매할 시기에 트래픽이 과도하게 몰릴 것이고 원활한 서비스를 제공하기 위해서 대용량 트래픽을 감당할 수 있어야 했다.
대용량 트래픽 처리를 위해 할 수 있는 방법은 크게 애플리케이션 관점과 하드웨어 관점으로 나눌 수 있을 것 같다.
애플리케이션 관점
시간 복잡도 최적화
애플리케이션 관점에서 가장 먼저 고민해야 할 부분인 것 같다. 애플리케이션의 비즈니스 로직이 원활하게 동작할 수 있도록 시간 복잡도를 최적화를 시켜줘야 한다.
만약 100만개의 데이터가 들어오는데 시간 복잡도가 O($n^{2}$)라면 10조가 나오게 되지만, O($n$)라면 100만이 나오기 때문에 훨씬 원활한 처리가 가능할 것이다.
DB 인덱스, 캐시
인덱스를 이용하면 검색 속도가 향상되어 많은 트래픽이 몰려올 때, 빠르게 처리를 할 수 있기 때문에 대용량 트래픽을 처리할 수 있도록 도와준다. 여기에 캐시 처리를 하면 데이터베이스를 거치지 않고 처리할 수 있기 때문에 보다 빠르게 데이터를 처리할 수 있다. 그렇게 되면 대용량 트래픽이 몰려와도 처리할 수 있다.
Pool
pool에는 Thread Pool과 Connection Pool이 있다.
먼저 Thread Pool은 미리 일정 개수의 스레드를 생성하여 관리하는 것이다. 스프링부트에서는 기본적으로 스레드 10개로 설정되어 있다. 작업이 발생되면 미리 생성된 스레드들 중에 대기 중인 스레드가 사용되고, 사용을 다 하게 된다면 다시 대기 상태가 되면서 새로운 작업을 기다린다.
Connection Pool은 Thread Pool과 비슷한 개념으로 Database 연결과 관련되어 있는 것이다. Connection Pool도 기본적으로 10개로 설정되어 있고 동작도 Thread Pool과 같은 개념으로 동작한다.
그렇다면 이 Pool Size를 적절하게 설정한다면 대용량 트래픽을 처리할 수 있을 것이다.
Nonblocking / Async
nonblocking에 대해서는 아직 학습하지는 않아 잘 모르겠다.
async는 비동기로 하나의 일을 처리하는 동안 다음 일도 처리할 수 있도록 한 것이다. 논블로킹과 비동기에 대해서는 나중에 학습을 다시 해봐야겠다.
하여튼 이렇게 병렬적으로 처리를 하게 되면 더 많은 연결을 처리할 수 있기 때문에 대용량 트래픽을 감당할 수 있다.
CQRS
CQRS는 읽기와 쓰기 작업을 분리하는 패턴이다.
데이터베이스에서 비교적 오래 걸리는 쓰기 작업을 진행하는 동안 읽기 작업 동작이 원활하게 돌아가지 않기 때문에 이를 분리하여 병목 현상을 해결하면서 성능을 최적화하고, 복잡성을 감소시킬 수 있다.
그러면 대용량 트래픽을 처리할 수 있다.
MSA
MSA 구조를 사용하게 되면 하나의 애플리케이션을 여러 개의 서비스로 분리하여 특정 비즈니스 기능을 독립적으로 관리하기 때문에 배포 및 확장에 유연하다. 특정 서비스에 트래픽이 몰리면 해당 서비스만 확장시키거나, 장애가 있으면 해당 서비스만 손 봐주면 되기 때문에 대용량 트래픽에 유용하다.
Client Side
서버에서만 대용량 트래픽을 처리하는 것만은 아니다. 클라이언트 측에서도 대용량 트래픽을 처리하기 위해서 할 수 있는 것이 있다.
클라이언트에서는 사용자가 몰리는 특정 기능 부분을 처리해주면 된다.
예를 들면 사용자가 무슨 작업을 요청하는 버튼을 계속 누르지 못하도록 disabled를 시켜주는 방식이 있을 것이다.
하드웨어 관점
Scale Up / Out
하드웨어 관점에서 가장 먼저 생각나는 것은 Scale Up과 Scale Out이다.
Scale Up은 서버의 성능을 올리는 것이고, Scale Out은 서버의 개수를 늘리는 것을 말한다.
리소스를 일정 이상 사용하게 되면 Scale Up 또는 Scale Out을 하여 대용량 트래픽을 감당할 수 있도록 할 수 있다.
DB Sharding / Partitioning
샤딩은 데이터를 여러 개의 데이터베이스 인스턴스로 분산시키는 기술이다. 각 데이터베이스 인스턴스는 데이터의 일부만을 저장하고 처리한다.
파티셔닝은 테이블을 여러 파티션으로 나누어 저장하는 기술이다. 각 파티션은 같은 데이터베이스 내에 존재하며, 주로 특정 기준(예: 날짜, 범위, 해시 등)에 따라 데이터가 나누어진다.
이를 통해 데이터베이스의 성능을 향상시키고 대용량 트래픽을 처리할 수 있도록 할 수 있다.
CDN
CDN은 전 세계에 분산된 서버 네트워크를 활용하여 사용자에게 콘텐츠를 빠르게 전달한다. 이를 통해 웹사이트의 성능과 가용성을 크게 향상시킬 수 있다.
마무리
이렇게 대용량 트래픽을 처리할 수 있는 방법들을 알아봤다.
몇 개는 프로젝트를 진행하면서 사용해 본 것도 있지만 비용 측면에서 사용하지 못한 것들도 있다.
추후에 좋은 기회가 있다면 MSA와 같이 다양한 방법들도 시도해보고 싶다.