HOME > 게시판 > 용어
게시판| 용어
※ 게시판 용도에 맞지 않는 글(광고및 홍보 글 등)은 임의삭제될 수 있습니다.

 
작성일 : 02-08-26 17:51
Pool에 대한 개념을 설명해 주세요
 글쓴이 : 김선달
조회 : 3,642  

원문출처 : http://www.javastudy.co.kr/docs/webdox/DBPool.htm

WebDox.co.kr

Database 접속을 Pool로 관리하자

김세곤 <sehkone@bawi.org>

2000년 4월 20일

개요

  데이터베이스의 성능

근래의 웹 개발을 비롯한 모든 개발에 있어서 데이터베이스 사용은 필수적이다. 이에 따라, 대부분의 웹 개발 솔루션(Java, CGI(ASP, PHP, Perl))은 데이터베이스를 사용할 수 있는 방법들을 제시하고 있다. 데이터베이스는 데이터 관리에 있어서 파일 처리에 비해 비교할 수 없는 수준으로 간편하고 강력한 방법을 제공하는데 반해, 수행 성능은 데이터베이스를 어떻게 사용하느냐에 따라 편차가 심할 수 있다. 웹 사이트 운영에 있어서 성능의 대부분은 데이터베이스 운영에서 결정이 나며, 심각한 경우 데이터베이스가 병목이 되어 웹 사이트 전체가 느려지는 현상이 생길 수도 있다. 따라서, 웹 사이트 개발자 및 운영자는 언제나 데이터베이스가 최상의 성능을 발휘할 수 있도록 최선을 다해야 한다.

데이터베이스의 성능을 향상하기 위해서는 여러가지 기법을 사용할 수 있다. 물리적으로는 데이터베이스를 분산 운영하는 방법이 있을 수 있으며, 데이터베이스 스키마를 잘 설계하는 것으로서 많은 효과를 볼 수도 있다. 한 애플리케이션이 데이터베이스를 이용하여 작업을 수행할 때, 가장 데이터베이스에 부하를 많이 주는 작업은 데이터베이스 접속과 해제인데, 이 접속과 해제를 최대한 줄이는 방법만으로도 데이터베이스의 전체적인 성능 향상을 쉽게 꾀할 수 있다

웹 애플리케이션의 경우 클라이언트가 웹 문서를 요청할 때마다 데이터베이스에 접속하고 해제하는 일을 수행하는 것은 데이터베이스에 많은 부담을 주게 된다. 이런 부담을 줄이기 위해 데이터베이스와의 접속을 pool로 관장하는 기법이 많이 사용되는데, 이 글에서는 데이터베이스의 접속을 pool로 관장할 수 있도록 해 주는 프로그램을 소개하려고 한다. 소개하려는 프로그램은 Gefion Software 사에서 만든 것으로서 비상업적 목적이라면 사용과 배포가 자유롭도록 되어 있다. 프로그램의 소스 코드가 공개된 만큼, 상업적 목적으로 사용하려는 사람도 소스를 통해 개념을 익힌다면 자신이 직접 간단하게 만들 수 있다.

  사용 환경

이 프로그램은 웹 개발 시 Servlet, JSP 등의 Java 기법을 사용하려는 경우에 적용된다. 따라서, Servlet, JSP가 구동될 수 있는 환경이 갖추어져야 한다. 리눅스 플랫폼의 경우 JServ + GNUJSP 혹은 Tomcat 등의 freeware를 사용할 수 있으며 이들의 설치 방법은 WebDox의 문서들을 참조하면 쉽게 알 수 있다.

J2EE기반이라면 여기서 소개하는 프로그램과 같은 미들웨어가 필요하지 않다. JDBC 2.0 Standard Extension API 에서 직접 데이터베이스를 pool로 운영할 수 있는 클래스를 제공하고 있기 때문에 javax.sql.* 클래스를 사용하면 된다.

설치 방법

먼저, 소스를 다운받고, 압축을 푼다. 압축을 풀면 DBConnectionManager.java와 db.properties 파일이 생길 것이다.

압축을 풀었으면, 다음처럼 하여 컴파일한다.

javac DBConnectionManager.java

컴파일한 후 DBConnectionManager$DBConnectionPool.class, DBConnectionManager.class 두 개의 파일이 생성되면 된다.

이제 생성된 두 개의 클래스 파일과 db.properties 파일을 자신의 Servlet, JSP 구동 환경에서 지정하는 클래스 디렉토리에 복사한다. JServ + GNUJSP 환경이라면 zone 설정 파일(*.properties)의 repositories에서 지정한 디렉토리여야 한다. CLASSPATH에 잡혀 있는 디렉토리에 복사하지 않도록 한다. 대부분의 Servlet, JSP 환경에서 CLASSPATH에 지정된 디렉토리의 클래스 파일들은 수정 시 reload가 되지 않으므로 꼭 자신의 환경 설정 파일에서 지정하는 동적 클래스 파일 디렉토리에 세 파일을 위치하도록 한다.

이제 db.properties 파일을 자신의 환경에 맞게 설정해야 한다.

1   drivers=postgresql.Driver sun.jdbc.odbc.JdbcOdbcDriver
2   logfile=/path/to/pool.log
3
4   mydb.url=jdbc:postgresql:dbname
5   mydb.maxconn=0
6   mydb.user=owner
7   mydb.password=ownerpassword
8
9   mydb2.url=jdbc:postgresql:dbname2
10  mydb2.maxconn=20
11  mydb2.user=owner2
12  mydb2.password=owner2password

우선, 맨 위의 drivers의 값으로는 사용하는 JDBC 드라이버 이름을 열거한다. 이 값은 데이터베이스가 제공하는 JDBC 드라이버에 따라 정해지는데 자신이 사용하는 JDBC의 문서들을 참고하면 쉽게 알 수 있다. postgreSQL이라면 postgresql.Driver이다. 이 값은 Class.forName() 메쏘드의 인자값과 같다. Class.forName() 메쏘드에 대해서는 WebDox의 JDBC를 익히자를 참고한다.

2번 행에서는 로그 파일의 위치를 지정해 준다. 여기서 주의할 것은 로그 파일이 위치하는 디렉토리는 nobody가 읽고 쓸 수 있도록 해 주는 일이다.

4번 행부터 7번 행까지는 접속하려는 데이터베이스를 지정하고 이 데이터베이스와의 접속 수를 설정하는 일을 한다. url, maxconn, user, password 앞에 붙는 mydb, mydb2와 같은 이름은 사용자가 임의로 설정하면 되고 이 이름이 추후 소스에서 데이터베이스를 접속할 때 사용하는 이름이 된다.

4번 행의 url 값으로는 자신이 사용하는 JDBC에 맞는 프로토콜과 데이터베이스 이름을 지정해 준다. 이 값은 DriverManager.getConnection() 메쏘드의 첫번째 인자값과 같아야 하는데, 첫번째 두 단어(위의 예에서는 jdbc:postgresql)는 JDBC의 프로토콜이며 사용하는 JDBC 드라이버에 따라 정해지고, 마지막 단어(dbname)는 접속하고자 하는 데이터베이스의 이름을 말한다. DriverManager.getConnection() 메쏘드의 인자에 대해서는 WebDox의 JDBC를 익히자를 참고한다.

5번 행은 4번 행에서 지정한 데이터베이스 pool이 관장하는 최대 접속 수를 설정할 수 있도록 해 준다. 0이라면 제한을 두지 않는다는 의미다.

6번 행과 7번 행은 각각 4번 행에서 지정한 데이터베이스의 접속 권한을 갖는 유저의 아이디와 패스워드를 적는다.

접속하려는 데이터베이스가 여러 개라면 9번부터 12번 행처럼 4번부터 7번 행까지를 접속하려는 데이터베이스에 맞게 고쳐서 추가하면 된다.

사용 방법

  데이터베이스 접속 얻기

DBConnectionManager클래스는 클라이언트가 데이터베이스 접속을 요구할 때 새로 데이터베이스와 접속을 시도하는 것이 아니라 우선 놀고 있는 접속이 있는지 살펴서 여유분이 있다면 그 접속을 바로 넘겨준다. 만일 여유분이 없다면 새로 데이터베이스에 접속을 한다. 사용자는 이런 메카니즘은 신경을 쓰지 않아도 되고 데이터베이스 접속 부분을 다음처럼 코딩하면 된다.

   DBConnectionManager connMgr;
   connMgr = DBConnectionManager.getInstance();
   Connection db = connMgr.getConnection("mydb");

DBConnectionManager의 getConnection() 메쏘드의 인자로는 앞의 db.properties에서 설정한 이름을 적어준다. 예를 들면 4번에서 7번 행에서 지정한 데이터베이스라면 url, maxconn, username, password 앞의 이름인 mydb를 적어 넣으면 된다.

  데이터베이스 접속 돌려주기

데이터베이스를 사용한 작업이 모두 끝나면 얻은 접속을 pool에 돌려 주어야 하는데 이를 위해서는 다음처럼 코딩한다.

   connMgr.freeConnection("mydb", db);

freeConnection() 메쏘드의 첫번째 인자는 getConnection() 메쏘드의 인자값과 같아야 하고 두번째 인자로는 접속한 데이터베이스를 다루었던 Connection 클래스의 인스턴스를 지정한다.

  주의 사항

Pool에서 놀고 있는 데이터베이스 접속을 받아서 사용하고 다시 돌려 주는 방법을 사용하기 때문에, 다시 돌려 줄 때 이 접속에 대한 환경을 원래의 값으로 복원시켜 주는 일을 잊으면 안된다. 예를 들어 Statement나 PreparedStatement 클래스의 setMaxRows() 메쏘드를 통하여 SELECT에서 한 번에 얻어지는 tuple의 갯수를 지정했다면 이 값은 받은 접속을 돌려주어도 그 접속에 대해서는 계속 유효하다. 따라서, setMaxRows()로 변경하기 전의 값으로 돌려 놓아야 돌려준 접속을 다음에 사용할 때 문제가 발생하지 않는다. 필자가 확인한 것으로는 setMaxRows() 메쏘드가 있지만 다른 경우에도 비슷한 상황이 발생할 수 있으므로 주의하도록 한다.

이 프로그램은 singlet 기법을 사용하므로 쓰레드에 민감하다. 사용하는 JDK가 native 쓰레드라면 동작이 잘 되지 않을 수도 있다. 만일 동작이 제대로 되지 않거나 오래 사용했을 때 웹 서버가 느려지는 일이 발생한다면 JDK를 다른 것으로 바꾸면 해결할 수 있다.

마치며

데이터베이스 관리는 웹 개발과 유지에 있어서 매우 중요하다. Pool로 관리를 한다면 Pool이 동작하는 메카니즘을 잘 이해하고 로그 파일도 수시로 살펴서 발생되는 문제에 현명하게 대처할 수 있어야 한다. 본 글에서 제시하는 프로그램의 소스는 singlet의 전형적인 예를 보여주는 코드로서 한번쯤은 분석해 볼만한 가치가 있다. 소스에 간략한 주석이 달아져 있으므로 이해하기 어렵지 않다. 자바 코딩에 관심있는 독자라면 꼭 소스 코드를 살펴보기 바란다.

J2EE 기반에서 javax.sql.* 클래스를 사용하여 데이터베이스를 pool로 관리하는 방법에 대한 설명은 다음 기회로 남겨둔다.


이 글을 트위터로 보내기 이 글을 페이스북으로 보내기