커넥션 풀은 기존에 매번 쿼리를 요청하고 응답을 받을 때마다
데이터베이스와의 연결을 열고 닫아야 했던 작업을
효율적으로 관리하기 위해 도입된 개념이다.
커넥션 풀은 미리 일정 수의 연결을 생성하여 풀에 보관해두고,
요청이 들어올 때마다 풀에서 연결을 빌려주고,
작업이 완료되면 다시 풀에 반납하는 방식으로 연결을 관리합니다.
이를 통해 매번 연결을 생성하고 해제하는 오버헤드를 줄이고,
데이터베이스 서버의 부하를 관리할 수 있습니다.
따라서 커넥션 풀을 사용함으로써
연결 관리에 필요한 비용을 줄이고,
시스템의 성능과 효율성을 향상시킬 수 있다.
백엔드 서버
DB조회할 일 발생!
쿼리 요청
쿼리 결과 반환
(추가 작업)
(클라이언트) 요청 반환
이 과정은
네트워크 통신으로 이루어진다 !
그리고 일반적으로 이 네트워크 통신은 TCP기반으로 동작한다.
TCP는 높은 송수신 신뢰성을 가진다.
-> 반드시 연결을 하는 과정이 필요하다.
Open Connection & Close Connection
열고닫는 과정이 보기보다 시간이 많이 소요된다!!!
Open Connection -> 3-way-handshake
Close Connection -> 4-way-handshake
3-way handshake (연결 설정):
- 클라이언트가 서버에게 연결 요청 (SYN)
- 서버가 요청 받고, 클라이언트에게 응답 및 연결 수락 (SYN+ACK)
- 클라이언트는 서버에게 연결을 확립했다는 메시지 전송 (ACK)
ex) 악수와 유사하다!
먼저 한 사람이 손을 내민다.
상대방도 손을 내밀고, 손을 잡아준다.
먼저 손을 잡은 사람이 손을 놓는다.
4-way handshake (연결 해제):
- 한쪽에서 연결 해제하고자 할 때, 해당 쪽은 상대방에게 FIN메시지 보냄
- 상대방은 FIN 메시지 받고, 확인 메시지를 보내고 자신도 FIN메시지 보냄
- 처음 FIN 메시지 보낸 쪽은 상대방의 확인 메시지 받고 연결 닫음
ex) 이별과정.. 한 사람이 이별을 고하고, 상대방은 이를 받아들이고 응답을 한다.
그리고 상대방 또한 이별의 인사를 건넨다.
마지막으로 처음 이별을 고한 사람이 이를 받아들이고 이별이 완료된다....
*FIN메시지 : Finish약자.
그리고 여러 요청은 계속 들어오고,
각 요청은 한 번만 db에 접근하는 것도 아니다.
실시간 통신은 !!
=> 시간적 비용 많이 든다
=> 서비스 성능에 좋지 않다.
∴ 해결책!!
DBCP
백엔드 서버에서 DB로
연결 요청시에 새롭게 연결을 생성하고 종료하는 것이 아닌,
미리 연결 시켜둔 pool에서 연결을 빌려주는 것! (사용 후에는 반환 & 재사용)
Get Connection
Close Connection
∴ 응답 시간 감소
백엔드 서버 자체 더 좋은 성능 발휘
max_connections : client와 맺을 수 있는 최대 connection 수
wait_timeout : connection이 inactive할 때, 다시 요청이 오기까지 얼마의 시간을 기다린 뒤에 close할 지 결정
- 비정상적 connection 종료
- connection 다 쓰고 반환 안됨
- 네트워크 단절
등 상황에서
누군가 점유는 하고 있지만 사용하지는 않는 상태가 된다.
하지만 DB서버 입장에서는 멀쩡하게 연결되어 요청 오기를 기다리는 정상 상태이다.
-> 요청 올 때까지 기다림
-> 리소스 점유
-> db서버에 나쁜 영향
==> 적절 시점에 이를 해결해주어야함
이것을 해결해주는 것이 wait_timeout 파라미터 역할이다.
ex) wait_timeout = 60,
60초동안 요청이 오지 않으면 반환한다.
58초에 요청이 오면 처리하고
다시 0으로 초기화 된 뒤 60초 동안 기다린다.
minimumIdle : pool에서 유지하는 최소한의 idle conenction 수 (유휴 connection 수)
idle connection 수가 minimumIdle보다 작고,
전체 connection 수도 maximumPoolSize보다 작으면
신속하게 추가로 connection을 만든다.
minimumIdle 수 = maximumPoolSize 수를 권장한다.
connection 만들어주는 속도보다 트래픽 더 빨리 밀려오면
백엔드 서버가 제때 반응하지 못할(응답 느려질)수 있기 때문에
어느정도 넉넉하게 잡아두고 고정 개수로 사용한다.
maximumPoolSize : pool이 가질 수 있는 최대 connection 수,
idle과 active(in-use) connection 합쳐서 최대 수
maxLifetime : pool에서 connection의 최대 수명
maxLifetime을 넘기면 유휴 상태일 경우 pool에서 바로 제거,
active인 경우 pool로 반환된 후 제거
pool로 반환이 안되면 maxLifetime 동작 안함(Exception 발생; 미반환/누수 등)
pool로 반환을 잘 시켜주는 것이 중요!
DB의 connection time limit보다 몇 초 짧게 설정해야한다.
ex) wait_timeout = 60, maxLifetime = 60.
59초에 요청 오다가 connection 끊길 수도.
connectionTimeout : pool에서 connection을 받기 위한 대기 시간
ex) 만약 connectionTimeout = 30, 요청 우르르 발생!
connection 계속 기다리다가 30초 넘겨버리면 connectionTimeout으로 Exception 발생!
어떻게 설정할지는 일반적 사용자가 얼마나 기다릴지 잘 고려하여 확인해야한다.
ex) 일반 사용자는 약 10초도 기다리지 않는다. 30초까지 잡아두는 것도 별 의미가 없다.
데이터베이스와 웹서버 간 연결은 어떻게 할까?
바로 JDBC(Java Database Connectivity)를 사용해서 처리한다.
JDBC는 Java 를 사용하여 데이터베이스와 연결을 관리하고
쿼리를 실행하는 데 사용되는 Java 표준 API 이다!
이를 통해 Java 애플리케이션은 데이터베이스와 통신하여 데이터를 읽고 쓸 수 있다.
JDBC는
드라이버 로드
-> 연결 설정
-> 쿼리 실행
-> 결과 처리
단계로 이루어진다.
커넥션 풀 도입 배경
데이터베이스 연결 비용
데이터베이스와 연결은 비용이 많이 든다.
연결을 맺고 해제하는 과정에서 네트워크 오버헤드와 데이터베이스 서버의 부하가 발생한다.
특히, 많은 수의 요청이 동시에 들어올 때 이런 비용은 더욱 높아진다.
자원의 한계
데이터베이스는 동시에 처리할 수 있는 연결 수에 한계가 있다.
이 한계를 초과하면 추가적인 연결 요청은 거부되거나 대기하게 된다.
이는 데이터베이스 서버의 부하를 조절하고 공격으로부터 보호하기 위한 방법 중 하나이다.
연결의 재사용
매번 새로운 연결을 맺는 것보다 기존의 연결을 재사용하는 것이 효율적이다.
연결을 맺고 해제하는 과정에서 발생하는 오버헤드를 줄일 수 있고,
데이터베이스 서버에 대한 부하도 감소시킬 수 있다.
∴ 연결 관리가 어렵다. 많은 수의 요청이 들어올 때마다 매번 새로운 연결을 맺는 것은 비용이 많이 들고 효율적이지 않다.
=> 미리 일정 수의 연결을 생성하여 풀에 저장해두고,
요청이 들어올 때마다 풀에서 연결을 빌려주고 반납하는 방식으로 연결을 관리한다.
커넥션 풀이 제공하는 이점
자원 효율성
미리 일정 수의 연결을 생성해 풀에 보관한다.
요청이 들어올 때마다 새로운 연결을 맺는 비용을 줄일 수 있다.
성능 향상
재사용되는 연결을 통해 데이터베이스와의 통신을 더욱 효율적으로 수행할 수 있다.
또한 연결이 풀에 미리 생성되어 있으므로 필요한 시점에 바로 사용할 수 있다.
부하 분산
커넥션 풀을 사용함으로써 동시에 많은 요청을 처리할 수 있다.
풀에 보관되어 있는 연결은 여러 요청 간에 공유되므로 데이터베이스 서버의 부하를 분산시킬 수 있다.
유연성
동적으로 변하는 트래픽에 대응하여 연결 수를 조절하고, 효율적인 자원 할당을 통해 시스템의 유연성을 제공한다.
∴ 연결 생성과 해제에 따른 오버헤드를 줄이고, 데이터베이스 서버의 부하를 관리할 수 있다.
실시간 통신과 Connection Pool의 차이
- 실시간 통신: 실시간 통신은 요청이 발생할 때마다 데이터베이스와의 새로운 연결을 설정한다.
해당 요청에 대한 응답을 기다린다.
연결 설정 및 해제에 대한 비용이 많이 발생하며,
많은 요청이 발생할 경우 성능 문제를 야기할 수 있다.
- Connection Pool : Connection Pool은 미리 생성된 연결을 사용하여 요청을 처리한다.
요청이 발생할 때마다 새로운 연결을 설정하는 것이 아니라,
미리 생성된 연결 중 하나를 가져다 사용한다.
이는 요청을 더 효율적으로 처리하고 응용 프로그램의 성능을 향상시킨다.
또한 연결을 재사용하고 관리하여 자원을 효율적으로 활용할 수 있다.
'CS' 카테고리의 다른 글
S)Spring_09_스프링DI (0) | 2024.04.09 |
---|---|
S)DB_08_JOIN (0) | 2024.04.02 |
S)DB_07_B tree, B+tree (1) | 2024.03.30 |
S)DB_07_인덱스 (1) | 2024.03.30 |
S)DB_06_트리거 (1) | 2024.03.27 |