서버 최적화 & 데이터 마이그레이션 작업 - 4 : 커넥션 풀 & 스레드 풀

최민길(Gale)·2023년 1월 4일
1

안녕하세요 오늘은 저번 시간에 알아보았던 내용에 대한 고찰을 포스팅해보려고 합니다.

저번 시간에는 커넥션 풀과 스레드 풀을 이용해서 TPS와 QPS를 향상시키는 작업을 진행했습니다. 하지만 지표 상으로 확인했을 땐 스레드 풀을 설정한 지표가 이전에 비해 더 적은 TPS와 QPS값을 나타내는데, 이 부분에 대해서 이해가 잘 되지 않아 SW마에스트로에서 인연을 쌓았던 강성욱 멘토님에게 조언을 구했습니다.

결론적으로 말씀드리자면 스레드 풀을 할당하는 시간이 추가되었기 때문에 TPS와 QPS가 감소한 것이었습니다. 스레드 풀 내부에 스레드가 얼마 되지 않는데 스레드 개수를 많이 만들어서 테스트하면 스레드 풀 내부에 가용 스레드가 있는지에 대한 검사를 진행하고, 만약 모든 스레드가 할당된 상태라면 사용한 후 반납한 스레드를 할당해야 하니 이런 프로세스에 대한 오버헤드가 발생했습니다.

또한 최적의 성능을 내기 위해선 커넥션 풀과 스레드 풀의 조합이 중요하다고 합니다. 커넥션 풀과 스레드 풀에 대해 다시 한 번 알아보자면,

커넥션 풀의 경우 일정량의 커넥션 객체를 미리 만들어서 풀에 저장하고, 요청이 오면 비어 있는 커넥션 객체를 할당하고 커넥션이 종료되면 다시 반납받아 풀에 저장하는 방식입니다. 이를 통해 커넥션 생성 및 삭제 비용을 절감할 수 있어서 전체적인 성능 향상을 기대해볼 수 있습니다.

스레드 풀의 경우 커넥션 풀과 마찬가지로 특정 개수의 스레드를 메모리에 캐싱하여 스레드 할당이 필요할 때 캐시에 대기 중인 스레드를 할당하고 작업이 종료되면 다시 반납받아 캐시로 돌아가는 방식입니다. 이 방식으로 스레드 생성 및 삭제 비용을 절감할 수 있어 처리 속도를 향상시킬 수 있습니다.

하지만 커넥션 풀과 스레드 풀의 경우 하나의 단점이 존재하는데, 바로 현재 사용 가능한 커넥션 객체 또는 스레드가 있는지 확인하는 작업이 추가로 소요된다는 것입니다. 커넥션 풀과 스레드 풀이 어떤 프로그램에서 구현되는지에 따라 조금씩 다르긴 하지만, Hikari CP의 커넥션 풀의 경우 요청 시 유휴 커넥션을 찾아서 반환하고 가능한 커넥션이 존재하지 않으면 HandOffQueue로 요청을 보내 유휴 커넥션이 발생할 때까지 대기 후 반납된 커넥션이 발생할 경우 큐 내에 있는 요청에 할당하는 방식입니다. MariaDB의 스레드 풀의 경우 유휴 스레드가 있는지 확인하고 사용 가능한 스레드가 없다면 스레드를 새로 생성해서 할당하는 방식으로 동작합니다. 따라서 각 풀에 가용한 자원이 있는지 확인하는 비용과 없을 시 대기하는 시간적 비용, 그리고 새로 생성하는 비용 등으로 인해 sysbench 결과가 더 성능이 안 좋게 나타난 것이었습니다.

이를 검증해보기 위해 스레드 개수를 1개로 설정하여 sysbench를 진행했습니다. 현재 DB 서버의 경우 스레드 풀에 4개의 스레드가 존재하기 때문에 4개 이하의 스레드로 테스트를 진행한다면 더 높은 성능이 나와야 할 것입니다.

따라서 t3.micro(2CPU,1G RAM)의 스펙의 10.5.18 버전의 MariDB의 RDS 인스턴스로 테스트를 진행하였습니다. RDS 프록시는 설정하지 않았고 가용 스레드 수는 1개와 10개로 테스트를 진행해보았습니다.


위의 2개의 경우 스레드 풀 없이 각각 스레드 1개와 10개로 진행한 결과이며,


위의 2개의 경우 스레드 풀 적용한 후 각각 스레드 1개와 10개로 진행한 결과입니다. 스레드 풀이 적용된 후 스레드 1개일 때는 TPS는 약 1.14배 증가하였으며, QPS도 약 1.14배 증가하였습니다. 스레드 10개일 경우 TPS는 약 0.99배, QPS도 약 0.99배로 오히려 감소하였습니다. 즉 스레드 풀 내부의 스레드 수보다 더 많은 스레드 요청이 들어올 경우 유휴 스레드를 확인하고 할당할 때까지 대기하는 비용으로 인해 오히려 성능이 감소하는 것을 확인할 수 있었습니다.

또한 RDS 프록시 적용 여부에 따른, 즉 커넥션 풀의 여부에 따른 성능도도 같이 테스트해보았습니다. t3.small(2CPU,2G RAM)의 스펙의 10.5.18 버전의 MariaDB의 RDS 인스턴스로 테스트를 진행하였고 가용 스레드 수 역시 1개와 10개로 진행했습니다. 또한 테스트 DB의 경우 스레드 풀 옵션을 적용한 상태로 진행했습니다.


위의 두 수치는 프록시 없이 진행한 sysbench 결과이고,


다음의 두 수치는 프록시 적용 후 진행한 sysbench 결과입니다. 보이시는 것처럼 프록시 적용 후, 즉 커넥션 풀이 적용된 후 스레드 1개일 때는 TPS는 약 5배, QPS는 약 6배 가량 향상되었고, 스레드 10개일 때는 TPS는 약 4배, QPS는 약 4배 가량 향상되었습니다. 즉 커넥션 풀은 실제로 유의미한 성능 향상을 가져오며, 처리 스레드 수가 늘어날 경우, 즉 DB의 요청 수가 늘어날수록 유휴 커넥션을 찾는 과정 및 대기 과정 등으로 인해 성능 향상의 폭이 감소하는 것을 확인할 수 있었습니다.

이로서 커넥션 풀과 스레드 풀에 대해 조금 더 깊게 알아볼 수 있었습니다. 이렇게 검증한 결과를 토대로 다음에는 커넥션 풀과 스레드 풀의 최적의 조합을 찾는 방법을 학습하면서 적용해보도록 하겠습니다. 그럼 오늘의 포스팅 마치도록 하겠습니다!

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글