데이터베이스 연결(DB Connection)

정재현·2023년 7월 18일
1

Development

목록 보기
1/6

데이터베이스(DB) 연결은 애플리케이션과 DB 간의 통신을 가능하게 하는 수단이다. 이를 위해 데이터베이스 드라이버와 데이터베이스 연결 정보를 포함하는 URL이 필요하다. 자바의 DB 연결에는 주로 JDBC(Java Database Connectivity)가 사용되며, 이는 URL 형식을 사용한다.

데이터베이스 연결 구조

데이터베이스 연결 구조에는 2Tier와 3Tier 두 가지가 있다.

  • 2Tier: 자바 프로그램(예: JSP)이 클라이언트로서 직접 데이터베이스 서버에 접근하여 데이터를 액세스하는 구조이다.
  • 3Tier: 자바 프로그램과 데이터베이스 서버 사이에 미들웨어 계층이 존재하는 구조이다. 미들웨어 계층은 비즈니스 로직 구현, 트랜잭션 처리, 리소스 관리 등을 담당한다.

JDBC

JDBC는 Java Database Connectivity의 약어로, 다양한 종류의 관계형 데이터베이스에 접속하고 SQL 문을 수행할 때 사용되는 표준 SQL 인터페이스 API이다. 각 DBMS에 맞는 JDBC 드라이버를 이용하면 다양한 DBMS(MySQL, MsSQL, Oracle, PostgreSQL 등)와 쉽게 연동할 수 있다.

자바 애플리케이션에서 데이터베이스에 접근하기 위해서는 다음과 같은 구조로 동작한다: Java (Web) Application -> JDBC API -> JDBC Driver -> DB

JDBC 드라이버

JDBC 드라이버는 자바 프로그램의 요청을 DBMS가 이해할 수 있는 프로토콜로 변환해 주는 클라이언트 측 어댑터이다. 각 DBMS 제공자는 자신에게 알맞은 JDBC 드라이버를 제공한다.

JDBC 실행과정

JDBC를 이용한 데이터베이스 연결 및 쿼리 수행의 기본적인 순서는 다음과 같다:
1. DB 벤더에 맞는 드라이버 로드
2. DB 서버의 IP, ID, PW 등을 DriverManager 클래스의 getConnection() 메소드를 사용하여 Connection 객체 생성
3. Connection에서 PreparedStatement 객체를 생성
4. executeQuery를 수행하고 ResultSet 객체를 받아 데이터를 처리
5. 사용했던 ResultSet, PreparedStatement, Connectionclose 하여 자원을 반납

Connection Pool(DBCP)

매번 사용자가 요청할 때마다 JDBC 드라이버를 로드하고 연결 객체를 생성하는 것은 비효율적이다. 이를 해결하기 위해 커넥션 풀(Connection Pool)을 사용한다.

connection pool은 웹 컨테이너(WAS)가 실행될 때 일정량의 Connection 객체를 미리 만들어서 pool에 저장한다. 클라이언트 요청이 오면 Connection 객체를 빌려주고, 임무가 완료되면 다시 Connection 객체를 pool에 반환한다.

Connection pool 풀의 장점

  • DB 접속 설정 객체를 미리 만들어 연결하여 메모리 상에 등록해 놓기 때문에 불필요한 작업(connection 생성, 삭제)이 사라지므로 클라이언트가 빠르게 DB에 접속이 가능하다.
  • DB Connection 수를 제한할 수 있어서 과도한 접속으로 인한 서버 자원 고갈 방지가 가능하다.
  • DB 접속 모듈을 공통화하여 DB 서버의 환경이 바뀔 경우 쉬운 유지 보수가 가능하다.
  • 연결이 끝난 Connection을 재사용함으로써 새로 객체를 만드는 비용을 줄일 수 있다.

Connection pool의 주의사항

동시 접속자가 많을 경우나 너무 많은 DB 접근이 발생할 경우, connection은 한정되어 있기 때문에 쓸 수 있는 connection이 발납될 때까지 기다려야 한다. 이때, 너무 많은 connection을 생성하면 메모리 소모가 크고 프로그램의 성능을 떨어뜨릴 수 있다. 따라서 사용량에 따라 적정량의 connection 객체를 생성해 두어야 한다.

Connection Pool의 크기와 성능 관계

Connection Pool의 크기를 무한정 늘리면 성능이 좋아질까? 그렇지 않다. Connection의 주체는 Thread이므로 Thread와 함께 고려해야 한다.

Thread Pool 크기가 Connection Pool 크기보다 작으면 남는 Connection은 메모리 공간만 차지하게 됩니다. 반면에 Thread Pool 크기와 Connection Pool 크기가 동시에 증가하면 더 많은 Context Switching이 발생하여 성능에 부정적인 영향을 미칠 수 있다.

적절한 Connection Pool 크기 설정

Connection Pool의 크기를 어떻게 설정해야 적절한가에 대해 Hikari CP의 공식 문서에서는 아래의 공식을 제시하고 있다.

1 connections = ((core_count) * 2) + effective_spindle_count

여기서 core_count는 현재 서버에서 사용하는 CPU 개수를 나타내고, effective_spindle_count는 DB 서버가 처리할 수 있는 동시 I/O 요청 수를 나타냅니다. 이 공식에 따르면, CPU 속도가 Disk I/O 보다 월등히 빠르므로, Thread가 Disk 작업에서 블로킹되는 시간에 다른 Thread의 작업을 처리할 수 있는 여유가 생긴다는 점을 반영하고 있다.

Connection pool의 종류

  1. commons-dbcp: 아파치에서 제공하는 대표적인 connection pool 라이브러리이다.
  2. tomcat-jdbc-pool: Tomcat에 내장되어 있으며, Apache Commons DBCP 라이브러리를 기반으로 만들어졌다.
  3. HikariCP: 스프링 부트 2.0부터 default JDBC connection pool로 사용되며, zero-overhead의 특징을 가지고 있다.

결론

JDBC는 자바 애플리케이션이 데이터베이스에 접근할 수 있도록 만든 JAVA에서 제공하는 API이며, connection pool은 JDBC 실행 과정 중에서 생성되어야 할 Connection 객체를 미리 만들어 저장해두는 기법이다. 이로 인해 불필요한 과정(Connection 객체 생성,삭제)을 줄여 성능을 향상시킬 수 있다.

그러나 Connection Pool의 크기를 크게 설정하면 메모리 소모가 크며, 많은 사용자가 대기 시간이 줄어들지만, 반대로 작게 설정하면 대기 시간이 길어집니다. 따라서 사용량에 따라 적정량의 Connection 객체를 생성해 두어야 한다.

profile
BlockChain Engineer

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

아주 유용한 정보네요!

답글 달기