Database Pool

HunkiKim·2022년 9월 27일
0

Database Pool

Connection Pool이라고도 부른다.애플리케이션의 스레드에서 DB에 접근하기 위해 Connection이 필요하다. 이 풀은 데이터베이스와 Connection한 객체들을 미리 생성해 Pool에 저장해두었다가, 클라이언트의 요청이 들어올 때마다 사용/반환하는 방식이다.

접근 과정

  1. 웹 컨테이너가 실행되면 데이터베이스와 연결된 Connection 객체들을 미리 생성해 Pool에 저장한다.
  2. 클라이언트 요청 시 Pool에서 Conncection 객체를 가져와 데이터베이스 접근한다.
  3. 요청 처리가 끝나면 사용된 Conncetion 객체를 다시 Pool에 반환한다.

장점

  1. DB 접속 설정 객체를 미리 만들어 메모리에 등록해 놔서 생성/삭제 등과 같은 작업들을 이후에 하지않아 클라이언트가 빠르게 DB에 접근이 가능하다.
  2. DB Conncetion 수를 제한할 수 있어 과도한 접속으로 인한 서버 자원 고갈 방지가 가능하다.
  3. DB 접속 모듈을 공통화해 DB 서버 환경이 바뀔 경우 쉬운 유지 보수가 가능하다.
  4. 연결이 끝난 Conncection을 재사용함으로써 새로 객체를 만드는 비용을 줄일 수 있다.

단점

  1. Conncetion 또한 객체이므로 메모리를 차지한다.
  2. 개수를 잘 못 설정하면 노는 Conncetion이 생겨 자원을 낭비한다.

유의사항

  1. 동시 접속자가 많을 경우 : 너무 많은 DB 접근이 발생할 경우에는 커넥션이 한정되어 있어 쓸 수 있는 커넥션이 반납될 때까지 기다려야 한다. 또한 너무 많은 커넥션을 생성하면 커넥션 또한 객체이므로 많은 메모리를 차지하게 되고, 프로그램의 성능을 떨어뜨리는 원인이 된다. 즉 이러한 Trade-off 관계에 있기 때문에 적정량의 커넥션 객체를 생성해 두어야 한다.

  2. Conncetion Pool의 주체는 Thread이므로 Thread와 함께 고려해야 한다. Thread Pool가 Conncetion Pool의 크기보다 크다면 Thread Pool에서 트랜잭션을 처리하는 Thread가 사용하는 Connection 외에 남는 Connection은 실질적으로 메모리 공간만 차지하게 된다. 반대로 Thread Pool 크기와 Connection Pool 모두 크기가 증가한다면 Thread 증가로 인해 더 많은 Context Switching이 발생한다. Disk 경합 측면에서 성능 한계가 발생한다. 즉, 특정 시점부터는 성능적인 증가가 Disk 병목으로 인해 갈수록 미비해진다.

따라서 데이터베이스 입자에서 Conncetion은 Thread와 어느 정도 일치한다고 볼 수 있다. Connection이 많다는 의미는 데이터베이스 서버가 Thread를 많이 쓴다는 것이고, 이에 따라 Context Switching으로 인한 오버헤드가 더 많이 발생하기 때문에 Connection Pool을 늘려도 성능적 한계가 존재한다.

Connection Pool의 크기

그러면 Connection Pool의 크기는 몇이 적당할까? Hikari CP 공식 문서에서는 1 connections = ((core_count * 2) + effective_spindle_count)로 정의된다.

  • core_count는 현재 사용하는 서버 환경에서의 CPU 개수를 의미한다.
  • core_count 2를 하는 이유는 Context Switch의 오버헤드를 고려해도 DB에서 I/O(혹은 DRAM 처리 속도)보다 CPU속도가 월등히 빠르다. 따라서 Thread가 Disk와 같은 작업에서 블로킹되는 시간에 다른 Thread의 작업을 처리할 수 있는 작업을 처리할 여유가 생기고, 여유 정도에 따라 멀티 스레드 작업을 수행할 수 있다. Hikari CP가 제시한 공식은 계수를 2로 선정해 Thread개수를 지정하였다. 한마디로 CPU 처리속도가 워낙 빨라 Context Switch 고려해도 2 까지의 여유는 있다.
  • effective_spindle_count는 기본적으로 DB서버가 관리할 수 있는 동시 I/O 요청수이다. 하드 디스크 하나는 spindle 하나를 갖는다. 디스크가 16개 있는 경우, 시스템은 동시에 16개의 I/O가 가능하다.

종류

  1. commons-dbcp : 아파치에서 제공하는 대표적인 커넥션 풀 라이브러리이다. commons-dbcp에서는 dbms에 로그인을 시도하고 있는 커넥션도 사용 중인 것으로 간주한다. 만약 DBMS에 로그인을 시도한 상태에서 무한 대기에 빠진다면, 모든 커넥션이 사용중인 상태가 되어 새로운 요청을 처리 못할 수도 있다. 이런 경우 장ㅇ애 확산을 최소화 하려면 Microsoft SQL Server의 JDBC드라이버에서 설정하는 loginTimeout 과 같은 타임아웃 속성을 설정하는 것이 좋다.
  2. tomcat-jdbc-pool : tomcat 내장이다. 위의 라이브러리를 바탕으로 만들어졌다. Spring boot 2.0.0 하위 버전에서 사용하는 기본 DBCP이다.
  3. HikariCP : 2.0부터 default JDBC Connection Pool이다. zero-overhead의 특징이 있다. overhead란 어떤 처리를 하기 위해 들어가는 간접적인 처리 시간 및 메모리이다. 즉 자원이다. Springboot환경에서는 속성설정을 통해 간단하게 설정이 가능하며 다양한 설정을 할 수 있다.

0개의 댓글