DB CP(Connection Pool)

지식저장공간·2023년 6월 7일
0

DB

목록 보기
18/19

Connection Pool

CP가 존재하지 않는 경우

백엔드 서버로 요청이 들어오고, DB를 사용해야 하는경우 시퀀스 다이어그램. 백엔드 서버와 데이터베이스 서버는 TCP 기반으로 동작한다.

TCP는 연결지향 프로토콜이며, 데이터 순서를 보장하며 신뢰성이 높다.

백엔드 서버는 데이터베이스 서버와 통신하기위해 커넥션을 생성하고 통신이 끝난 후 커넥션을 제거한다.

open connection : 3 ways handshake
close connection : 4 ways handshake

통신을 열고 닫는경우 단순한 작업이 아닌 생각 보다 복잡한 과정이기 때문에 시간이 소비된다. 매번 connection을 열고 닫는 시간적 비용 발생 서비스 성능에 좋지 않다.

CP의 개념과 원리

백엔드 서버가 실행될 때 미리 데이터베이스와 연결되는 커넥션을 생성 하고 백엔드 서버와 데이터베이스를 연결 시켜 놓는다. 대부분 커넥션은 1개 이상 존재하기 때문에 pool이라 부르고, connnection pool이라고 한다.

백엔드 서버로 요청이 들어오면 connection pool에서 사용되지 않고 있는 connection을 획득하고, 데이터베이스와 처리가 끝난 경우 커넥션을 닫는게 아닌, 사용을 마친 커넥션을 pool에 반납한다.

★ 데이터베이스와 통신이 필요한 경우 매번 커넥션을 열고 닫는게 아닌, 미리 준비된 커넥션을 사용 및 반납하며 커넥션들을 재사용한다.

DBCP 설정

스프링부트 Hikari CP, MySQL 기준

CP는 백엔드서버와 데이터베이스 서버 사이의 연결과 통신이기 때문에 백엔드 서버와 데이터베이스 서버 각각의 설정법을 잘 알고 있어야한다.

DB 서버

max_connections

DB레벨에서 max_connections : client와 (동시에) 맺을 수 있는 최대 connection 수

DB의 동시 연결 가능한 최대 커넥션의 갯수가 4인 경우, 백엔드 서버로 계속해서 클라이언트 요청이 들어오면 커넥션이 계속 사용되고 데이터베이스가 처리할 수 있는 요청은 최대 4개 뿐이다. 백엔드 서버를 증설해도 데이터베이스에서는 커넥션을 더 받아들일 수 가 없다.

wait_timeout

wait_timeout : connection이 비활성 상태일 때 다시 요청이 오기까지 얼마의 시간을 기다린 뒤에 close할 것인지를 결정한다.

비정상적으로 connection이 종료되고, connection을 사용 후 반환이 안되거나 네트워크가 단절된 경우 데이터베이스에서 connection을 계속 사용하는 상태로 인식하여 관리할 수가 없다.

계속해서 open되어 있는 커넥션이 반환도 안되고, 데이터베이스 측에서 TCP로 연결되어있고 백엔드 서버로 부터 요청을 기다린다.

연결 종료가 안된 경우 어느 정도의 시간이 지난 후 자동적으로 connection을 close하기 위한 time설정

마지막으로 백엔드 서버로부터 요청을 받은 시간을 계산하여 백엔드 서버로 부터 요청을 받지 못하면 일정 시간 이후 커넥션을 close한다.

만약, wait_timeout 시간내에 백엔드 서버로부터 요청이 도착하면 0으로 초기화된다.

백엔드 서버 (스프링부트,Hikari CP 기준)

minimumIdle

minimumIdle : pool에서 유지하는 최소한의 idle connection 수

maximumPoolSize

maximumPoolSize : pool이 가질 수 있는 최대 connection 수
idle 커넥션 갯수 + active 커넥션의 최대 갯수

idle == inactive, active == in-use(히카리 기준)

커넥션을 추가해야 하는 경우

idle 상태인 커넥션 수가 minimumIdle 수보다 작고, 전체 커넥션 수도 maximumPoolSize보다 작다면 추가적으로 connection을 만든다.

예시

커넥션 풀에 커넥션이 2개가 있는 상황에서 요청이 들어오는 경우 커넥션 1개는 사용이 되고, idle 커넥션 갯수는 1개가 된다. 따라서, minimumIdle의 수는 2이기 때문에 커넥션을 추가적으로 생성하고 idle 커넥션 갯수를 2개로 맞춰 총 커넥션 갯수는 3개가된다.

만약 한번의 요청이 더 들어오게 되면 커넥션이 4개가되고, idle을 다시 2로 맞춘다. 모든 커넥션이 사용자의 요청을 처리하는 경우에는 maximumPoolSize는 4이기 때문에 커넥션을 추가할 수가 없다.

권장사항 :
히카리 CP에서는 minimumIdle의 수와 maximumPoolSize의 수를 동일하게 하도록 권장한다. pool size가 고정되고, 사용자의 요청이 몰려와도 추가적으로 connection을 생성하지 않고, idle 상태인 커넥션을 재사용하도록한다.

maxLifetime

maxLifetime : pool에서 connection의 최대 수명. maxLifetime을 넘기면 idle일 경우 pool에서 바로 제거, active인 경우 pool로 반환된 후 제거된다.

제거된 connection을 대체하기 위해 백엔드 서버와 데이터 베이스 서버는 새롭게 connection을 생성하고 open한다.

만약 데이터베이스 서버에서 사용되던 connection이 pool로 반환되지 않으면 active상태로 판단하기 때문에 반환될 때까지 제거되지 않는다.

데이터베이스 서버에서는 wait_timeout 기다리다가, 사용자의 요청이 오지 않으면 연결을 끊어버리고, 백엔드 서버가 연결이 끊어진 커넥션을 사용할 경우 Exception이 발생한다.

애플리케이션 CP의 maxLifetime을 DB의 wait_timeout보다 몇초 정도 짧게 설정해야한다.

백엔드 서버와 통신 중 데이터베이스 서버로 커넥션을 사용하여 요청을 보내려고 할때 wait_timeout이 지나 데이터베이스 서버에서 커넥션을 close할 수도 있다.
DB측에서 커넥션을 끊기 몇초전 미리 끊어놓아야 예상치 못한 상황을 방지할 수 있다.

connectionTimeout

백엔드 서버에서 CP로 부터 커넥션을 받기위해 대기하는 시간. 사용자의 요청이 많아 특정 요청이 계속해서 커넥션을 획득하지 못하고 대기 하는 상황에서 만약 시간내에 CP에서 커넥션을 얻지 못한경우 Exception 발생

사용자가 29초까지 기다리다가 연결을 끊어버리는 경우 비용 낭비가 생길 수 있다. 따라서, connectionTimeout을 적절하게 설정해야한다. (5초 정도)

정리

적절한 connection 수

주로 실무에서 데이터베이스 서버를 고가용성(HA:High availability)을 보장하기 위해 replication을 사용한다. primary server는 read-write가 가능하며, secondary server들은 read만 가능하다.

request per second : 1초에 request(요청)을 얼마나 처리할 수 있는가
avg response time : 평균 응답 시간

트래픽이 많이 발생할 수록 1초에 처리할 수 있는 요청의 갯수가 증가되지 않고, 평균 응답시간도 늘어나는 경우 해당 시점을 모니터링 한다.

우선 백엔드 서버의 리소스 사용률과 여유 리소스들을 확인해 본다. 백엔드 서버의 CPU, 메모리 사용률이 높은 경우 서버 자체의 스팩이 부족하기 때문에 스케일 업 또는 스케일 아웃을 통해 여유 리소스를 확보한다. (코드적으로 해결이 안되는 경우)

하지만, 백엔드 서버의 리소스 사용률은 정상이고, DB 서버의 CPU, 메모리 사용률이 높은경우 replication, cache layer 추가, sharding 등을 이용할 수 있다.

백엔드 서버도 정상이고, DB 서버도 정상인 경우

하나의 요청마다 쓰레드 1개를 사용하는 경우. 쓰레드 병목현상이 발생할 수 있다. 쓰레드 풀에 쓰레드 갯수가 5개이고 사용되는 쓰레드가 5개인경우 쓰레드를 증가 시키는 방법도 있을것이다.

쓰레드 풀에 쓰레드 갯수가 100개이고, active 쓰레드가 50개인 경우 쓰레드 병목현상은 발생하지 않지만, 성능이 안나오는 경우 connection 수를 확인한다.
maxumumPoolSize 올려보고 테스트 해본다. 백엔드 애플리케이션의 커넥션 수를 조정하면 DB 레벨의 max_connection도 그에 맞게 조정해주어야한다.

출처 : 쉬운코드 유튜브

네이버 D2

profile
발전하는 개발자가 꿈입니다. 지식을 쌓고 지식을 활용해 목표 달성을 추구합니다.

0개의 댓글