[DB] Connection Pool

calm0_0·2023년 10월 25일
0

Database

목록 보기
3/6

DB Connection


데이터베이스 커넥션은 애플리케이션에서 데이터베이스에 접근하기 위해 진행하는 일련의 과정이다.

데이터베이스는 대부분의 프로그래밍 언어를 위한 드라이버를 지원하며, 애플리케이션에서는 DB 드라이버를 사용하여 데이터베이스와 연결을 맺는다.

예제 코드

다음은 Node.js 과 MySQL 를 연동한 예제이다.

const mysql      = require('mysql');

const connection = mysql.createConnection({  // 1.
  host     : 'localhost',
  user     : '< MySQL username >',
  password : '< MySQL password >',
  database : 'my_db'
});

connection.connect();  // 1.

// 2.
connection.query('SELECT * from Users', (error, rows, fields) => {
  if (error) throw error;
  console.log('User info is: ', rows);
});

connection.end();  // 3.
  1. DB 서버와 커넥션을 맺은 다음,
  2. DB에 접근하여 필요한 작업을 수행한다.
  3. 작업이 끝나면 연결을 종료한다.

주의할 점은 작업이 끝나고 연결을 해제(connection.end())하지 않으면 계속해서 DB 서버와 연결된 상태를 유지하게 된다. 때문에 불필요한 자원(네트워크 및 메모리)이 낭비된다.

DB Connection의 생애 주기

애플리케이션에서 데이터베이스에 접근하기 위해선 먼저 다음과 같이 데이터베이스 커넥션을 획득해야 한다.

  1. 애플리케이션에서 DB 드라이버를 통해 커넥션을 조회한다.
  2. DB 드라이버가 DB와 TCP/IP 연결을 맺는다. (3 way handshake 같은 TCP 통신을 위한 네트워크 동작이 발생)
  3. TCP/IP 연결이 성립되면, DB 드라이버는 ID, PW 등 기타 부가 정보를 DB에 전달한다.
  4. 이를 통해 DB는 내부 인증을 완료하고, 내부에 DB 세션을 생성한다.
  5. DB는 커넥션 생성이 완료되었다는 응답을 보낸다.
  6. DB 드라이버는 커넥션 객체를 생성해서 클라이언트에 반환한다.

이후 TCP 소켓을 사용하여 DB와 데이터 통신을 한다. 데이터 전송이 종료되면, 데이터베이스 커넥션을 닫고 TCP 연결을 해제한다.(4 way handshake 발생)

DB Connection의 문제점

위와 같이 물리적으로 DB 서버에 연결하여 커넥션 객체를 생성하는 작업은 복잡하고 비용이 많이 발생한다.

데이터베이스는 최초 접속 시 TCP 통신을 하며, TCP 통신의 연결 수립/해제 작업인 3 way handshake / 4 way handshake 를 수행하기 때문이다.

애플리케이션에서 클라이언트의 요청이 들어올 때마다 데이터베이스와 연결을 맺고 해제하는 반복적인 작업을 해야 한다는 것은 굉장히 비효율적이다. 이러한 문제점을 해결하기 위한 방법 중 하나가 데이터베이스 '커넥션 풀'이다.


Connection Pool


Connection Pool 이란 WAS(Web Application Server) 실행 시 DB와 연결해놓은 일정량의 Connection 객체들을 먼저 생성해 Pool 이라는 공간(캐시)에 저장해둔다. 그리고 DB 연결 요청이 있을 때마다 Pool 에서 Connection 객체를 꺼내 사용하고 사용이 끝나면 다시 Pool 에 반납하는 방식을 말한다.

예제 코드

const mysql = require('mysql');

// 커넥션 풀 생성
const connection = mysql.createPool({
  host     : 'localhost',
  user     : '< MySQL username >',
  password : '< MySQL password >',
  database : 'my_db',
  connectionLimit: 40  // 커넥션 풀에 몇 개의 커넥션을 두는지
});
  
...

// 커넥션 풀에서 커넥션 객체 가져오기
connection.getConnection((error, connection) => {
  	// 작업을 수행한 후
	connection.query('SELECT * FROM users', (error, result, fields) => {
    	if (error) {
        	throw error;
        }
      	
      	console.log(result);
      	// 커넥션 풀에 커넥션 반환
      	connection.release();
    })
});

다음과 같이 커넥션 풀을 생성한다. 커넥션 풀에는 몇 개의 커넥션 객체를 둘지 정할 수 있다.

DB에 접근할 작업이 필요한 경우 커넥션 객체를 얻어(getConnection()) DB에 접근하여 데이터를 가져온다.

이후 작업이 끝나면 release() 로 커넥션 풀에 커넥션 객체를 반환한다.

장점 및 특징

  • 미리 생성된 커넥션을 가져다 쓰는 방식이기 때문에 매 요청마다 커넥션을 생성하는 데 필요한 연결 시간이 소비되지 않는다.
  • 커넥션을 재사용할 수 있으며, 서버 환경에 따라 생성되는 커넥션 수를 조절할 수 있다.


Reference
https://velog.io/@mooh2jj/%EC%BB%A4%EB%84%A5%EC%85%98-%ED%92%80Connection-pool%EC%9D%80-%EC%99%9C-%EC%93%B0%EB%8A%94%EA%B0%80
https://hudi.blog/dbcp-and-hikaricp/
https://1-7171771.tistory.com/119
https://poiemaweb.com/nodejs-mysql
https://javacan.tistory.com/entry/78
https://bitkunst.tistory.com/entry/Nodejs-MySQL-5-%EC%BB%A4%EB%84%A5%EC%85%98-%ED%92%80-Connection-Pool

profile
공부한 내용들을 정리하는 블로그

0개의 댓글