티스토리 뷰

서버 트래픽 급증으로 인한 DB 커넥션 부족 이슈

OPGG 해커톤 우승 후 기사가 나간날 예상치 못한 서버 트래픽 증가로 인해 DB 커넥션이 부족해지게 되었고, 결과적으로 서버가 느려지는 이슈가 발생했다.

커넥션 부족으로 타임 아웃 발생

이에 대한 해결법으로 3가지를 적용했는데 이를 정리하고자 한다.

1. EC2, RDS 규모 확장

기존에는 매달 720시간 무료로 사용할 수 있는 t2.micro 크기의 ec2, rds를 사용하고 있었다. 하지만 각 규모마다 가질 수 있는 최대 커넥션 제한이 있었고 이를 파악하지 못해 문제가 발생했다.

 

따라서, 근본적으로 더 많은 커넥션을 가질 수 있도록 규모를 medium으로 늘려주었다.

2. 커넥션 수립/해제 비용 최적화

스프링부트 2.0 이후 부터는  커넥션 관리를 위해 기본적으로 HikariCP를 사용하고 있다. HikariCP 방식은 가용할 수 있는 커넥션을 미리 DB에 모두 맺어놓고 요청이 올때마다 해당 커넥션을 주고, 반환 시 다시 맺어논 상태로 대기 시키는 방식이다. 이렇게 함으로서 요청이 올때마다 새로 커넥션을 수립하고 해제하는 비용을 줄 일 수 있다.

HikariCP 적용 후 DB 커넥션 수 변화의 모습

spring-boot-starter-jdbc를 통해 HikariCP를 사용할 수 있으며, application.yml에 hikari에 대한 설정값들을 작성함으로서 적용시켰다. 이를 통해 미리 커넥션을 맺어 놓고 요청이 있을 때 해당 커넥션을 전달하게 하여 연결의 수립 및 해제의 비용을 낮추었다.

3. Redis 적용

요청이 들어오는 구간에 로그를 찍어봤는데 반복적인 쿼리가 발생한다는 사실을 알게 되었다. 이에 리팩토링 기간을 잡고 잦은 쿼리를 최적화 하기 위한 방법으로 Redis를 도입하였다.

 

EC2 서버에 Redis 서버를 설치하고 코드상에 캐시메모리가 필요한 객체에 Serializable 구현했다. 반복적인 요청이 가능한 로직에는 @Cacheable 애노테이션을 추가하고, 캐시메모리 저장 시간 설정을 위해 Configuration 파일을 작성하였다. 쿼리 로그를 통한 테스트 결과 동일한 요청에 대해서는 쿼리 없이 응답받을 있었고 Redis 서버 내에 저장된 Key-Value 값을 확인할 있었다.

redis-server에 저장된 key-value 쌍

모든 조치를 한 후 nGrinder를 이용하여 가상의 트래픽 발생을 통한 테스트를 진행해 보았고 기존 Vusers가 200이었을 때 서버가 견디지 못하고 바로 테스트가 종료되었지만, 개선 이후에는 Vusers 300에서도 정상적으로 수행되는 것을 확인할 수 있었다. 또한, 기존에는 요청마다 일정한 시간이 소요되었지만, 최적화 이후에는 로딩 시간 없이 즉각적으로 결과를 반환받을  있었다.

반응형
Comments
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday