PostgreSQL PgBouncer 연결 풀링

PostgreSQLBeginner
지금 연습하기

소개

이 랩에서는 PostgreSQL 을 위한 경량 연결 풀러 (connection pooler) 인 PgBouncer 를 설정하고 사용하는 방법을 배웁니다. 연결 풀링은 데이터베이스 성능을 향상시키는 중요한 기술이며, 특히 짧은 시간 동안만 유지되는 많은 연결을 처리하는 애플리케이션에 유용합니다. PgBouncer 는 재사용 가능한 데이터베이스 연결 풀을 관리함으로써 각 클라이언트 요청에 대한 새 연결 설정의 오버헤드를 줄여줍니다.

먼저 PgBouncer 를 설치하고 구성하며, 필요한 설정 및 사용자 인증 파일을 생성합니다. 다음으로 PgBouncer 서비스를 시작하고 풀러를 통해 PostgreSQL 데이터베이스에 연결을 테스트합니다. 그런 다음 표준 PostgreSQL 벤치마킹 도구인 pgbench를 사용하여 클라이언트 부하를 시뮬레이션하고 PgBouncer 가 연결을 관리하는 방식을 관찰합니다. 마지막으로 PgBouncer 관리 콘솔에 연결하여 성능을 모니터링하고 연결 통계를 확인하는 방법을 배웁니다.

PgBouncer 구성

이 단계에서는 PgBouncer 에 필요한 구성 파일을 생성합니다. 여기에는 데이터베이스 연결 문자열 정의 및 사용자 인증 파일 설정이 포함됩니다.

먼저 프로젝트 폴더 내에 PgBouncer 구성 파일을 위한 전용 디렉토리를 생성합니다.

mkdir -p /home/labex/project/pgbouncer
cd /home/labex/project/pgbouncer

다음으로 nano 편집기를 사용하여 기본 구성 파일인 pgbouncer.ini를 생성합니다.

nano pgbouncer.ini

편집기에 다음 구성을 붙여넣습니다. 이 구성은 PgBouncer 가 PostgreSQL 데이터베이스에 연결하는 방법과 클라이언트 연결을 위해 수신 대기할 포트를 지정합니다.

[databases]
postgres = host=127.0.0.1 port=5432 dbname=postgres

[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 6432
auth_type = md5
auth_file = /home/labex/project/pgbouncer/userlist.txt
admin_users = postgres
pidfile = /home/labex/project/pgbouncer/pgbouncer.pid
logfile = /home/labex/project/pgbouncer/pgbouncer.log
pool_mode = session
default_pool_size = 20
max_client_conn = 100

주요 매개변수를 검토해 보겠습니다.

  • [databases]: 대상 데이터베이스의 연결 문자열을 정의합니다.
  • listen_port: PgBouncer 가 수신 대기할 포트입니다 (6432). 애플리케이션은 이 포트에 연결됩니다.
  • auth_type: 인증 방법을 지정합니다. md5는 일반적인 선택입니다.
  • auth_file: 사용자 이름과 암호가 포함된 파일의 경로입니다.
  • admin_users: PgBouncer 관리 콘솔에 연결할 수 있는 사용자 목록을 쉼표로 구분하여 지정합니다.
  • pool_mode: session으로 설정됩니다. 이는 서버 연결이 전체 세션 동안 클라이언트에 할당됨을 의미합니다.

Ctrl+O를 눌러 파일을 저장하고, Enter를 누른 다음, Ctrl+X를 눌러 nano를 종료합니다.

이제 구성에서 참조한 인증 파일 userlist.txt를 생성합니다.

nano userlist.txt

파일에 다음 줄을 추가합니다. 암호 labex_password는 랩 설정 단계에서 postgres 사용자에 대해 설정되었습니다.

"postgres" "labex_password"

Ctrl+O, Enter, Ctrl+X를 눌러 편집기를 저장하고 종료합니다.

이제 PostgreSQL 데이터베이스의 연결을 관리하도록 PgBouncer 를 성공적으로 구성했습니다.

PgBouncer 시작 및 연결 테스트

구성이 완료되었으므로 다음 단계는 PgBouncer 서비스를 시작하고 이를 통해 PostgreSQL 데이터베이스에 연결할 수 있는지 확인하는 것입니다.

터미널에서 생성한 구성 파일을 사용하여 데몬 (-d 플래그) 으로 PgBouncer 를 시작합니다.

pgBouncer -d /home/labex/project/pgbouncer/pgbouncer.ini

다음 명령으로 PgBouncer 프로세스가 실행 중인지 확인할 수 있습니다. pgbouncer 프로세스가 나열된 것을 볼 수 있어야 합니다.

ps aux | grep pgbouncer

출력은 다음과 유사하게 표시됩니다.

labex      1234  0.0  0.0  12345   678 ?        Ss   12:00   0:00 pgbouncer -d /home/labex/project/pgbouncer/pgbouncer.ini

이제 PgBouncer 가 수신 대기하는 포트 (6432) 에 연결하기 위해 psql을 사용합니다. 기본 PostgreSQL 포트 (5432) 가 아닙니다.

psql -h 127.0.0.1 -p 6432 -U postgres -d postgres

암호를 묻는 메시지가 표시됩니다. labex_password를 입력합니다. 연결에 성공하면 psql 프롬프트가 표시됩니다.

데이터베이스에 연결되었는지 확인하려면 간단한 쿼리를 실행하여 PostgreSQL 버전을 확인합니다.

SELECT version();

출력에는 PostgreSQL 서버 버전이 표시되어 PgBouncer 가 연결을 성공적으로 프록시했음을 확인합니다.

                                                 version
---------------------------------------------------------------------------------------------------------
 PostgreSQL 14.18 (Ubuntu 14.18-0ubuntu0.22.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.4.0...
(1 row)

마지막으로 \q를 입력하고 Enter를 눌러 psql 셸을 종료합니다.

\q

pgbench 를 사용한 클라이언트 부하 시뮬레이션

연결 풀링이 작동하는 것을 관찰하기 위해 PostgreSQL 에 포함된 표준 벤치마킹 도구인 pgbench를 사용합니다. pgbench는 여러 클라이언트가 데이터베이스에 동시에 액세스하는 것을 시뮬레이션할 수 있습니다.

먼저 pgbench 환경을 초기화해야 합니다. 이렇게 하면 몇 개의 테이블이 생성되고 샘플 데이터로 채워집니다. 다음 명령을 실행하고 PgBouncer 포트 (6432) 를 통해 연결해야 합니다.

pgbench -i -h 127.0.0.1 -p 6432 -U postgres postgres

암호 (labex_password) 를 묻는 메시지가 표시됩니다. -i 플래그는 벤치마킹을 위해 데이터베이스를 초기화합니다. 테이블이 생성되고 채워졌음을 나타내는 출력이 표시되어야 합니다.

dropping old tables...
NOTICE:  table "pgbench_accounts" does not exist, skipping
NOTICE:  table "pgbench_branches" does not exist, skipping
NOTICE:  table "pgbench_history" does not exist, skipping
NOTICE:  table "pgbench_tellers" does not exist, skipping
creating tables...
generating data (client-side)...
100000 of 100000 tuples (100%) done (elapsed 0.01 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done in 0.13 s (drop tables 0.00 s, create tables 0.00 s, client-side generate 0.06 s, vacuum 0.04 s, primary keys 0.02 s).

이제 벤치마크를 실행하여 로드를 시뮬레이션합니다. 다음 명령은 10 개의 동시 클라이언트 (-c 10) 를 시뮬레이션하며 각 클라이언트는 300 개의 트랜잭션 (-t 300) 을 실행합니다.

pgbench -c 10 -t 300 -h 127.0.0.1 -p 6432 -U postgres postgres

다시 암호를 묻는 메시지가 표시되면 입력합니다. 벤치마크는 몇 초 동안 실행된 다음 결과 요약을 표시합니다. 여기에는 초당 트랜잭션 수 (tps) 가 포함됩니다.

pgbench (14.18 (Ubuntu 14.18-0ubuntu0.22.04.1))
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 300
number of transactions actually processed: 3000/3000
latency average = 5.935 ms
initial connection time = 1.342 ms
tps = 1685.027854 (without initial connection time)

이 테스트는 PgBouncer 를 통해 상당한 트래픽을 생성했으며, 이는 다음 단계에서 검사할 것입니다.

PgBouncer 통계 모니터링

PgBouncer 는 활동을 모니터링하고 연결 풀에 대한 통계를 볼 수 있는 특수 관리 데이터베이스를 제공합니다.

PgBouncer 관리 콘솔에 연결합니다. 데이터베이스 이름은 pgbouncer입니다.

psql -h 127.0.0.1 -p 6432 -U postgres -d pgbouncer

암호 labex_password를 묻는 메시지가 표시되면 입력합니다.

연결되면 특수 SHOW 명령을 실행할 수 있습니다. 먼저 모든 데이터베이스에 대한 전체 통계를 확인합니다.

SHOW STATS;

이 명령은 PgBouncer 가 마지막으로 시작된 이후의 누적 데이터를 표시합니다. total_xact_count(총 트랜잭션) 및 total_query_count와 같은 열이 표시되며, 이는 pgbench 테스트로 인해 높은 값을 가져야 합니다.

pgbouncer=## SHOW STATS;
 database  | total_xact_count | total_query_count | total_received | total_sent | total_xact_time | total_query_time | total_wait_time | avg_xact_count | avg_query_count | avg_recv | avg_sent | avg_xact_time | avg_query_time | avg_wait_time
-----------+------------------+-------------------+----------------+------------+-----------------+------------------+-----------------+----------------+-----------------+----------+----------+---------------+----------------+---------------
 pgbouncer |                1 |                 1 |              0 |          0 |               0 |                0 |               0 |              0 |               0 |        0 |        0 |             0 |              0 |             0
 postgres  |             3019 |             21033 |        2860191 |     561691 |        17758077 |         16667957 |          277707 |             36 |             250 |    34117 |     6700 |          5882 |            792 |          3312
(2 rows)

다음으로 연결 풀의 실시간 상태를 보려면 SHOW POOLS 명령을 사용합니다.

SHOW POOLS;

이 명령은 연결 풀의 스냅샷을 제공하며 클라이언트와 서버 모두에 대한 활성 및 유휴 연결을 보여줍니다.

  • cl_active: 서버 연결에 적극적으로 연결된 클라이언트 연결입니다.
  • sv_active: 현재 사용 중인 서버 연결입니다.
  • sv_idle: 유휴 상태이며 새 클라이언트에서 사용할 준비가 된 서버 연결입니다.
 database  |   user    | cl_active | cl_waiting | cl_cancel_req | sv_active | sv_idle | sv_used | sv_tested | sv_login | maxwait | maxwait_us | pool_mode
-----------+-----------+-----------+------------+---------------+-----------+---------+---------+-----------+----------+---------+------------+-----------
 pgbouncer | pgbouncer |         1 |          0 |             0 |         0 |       0 |       0 |         0 |        0 |       0 |          0 | statement
 postgres  | postgres  |         0 |          0 |             0 |         0 |      10 |       0 |         0 |        0 |       0 |          0 | session
(2 rows)

이러한 통계를 검토하면 PgBouncer 가 연결을 얼마나 효과적으로 관리하고 클라이언트 요청을 처리하기 위해 재사용하는지 이해할 수 있습니다.

완료되면 psql 셸을 종료합니다.

\q

요약

이 실습에서는 PostgreSQL 연결 풀링을 위해 PgBouncer 를 성공적으로 구성하고 사용했습니다. pgbouncer.ini 구성 파일과 userlist.txt 인증 파일을 생성하는 방법을 배웠습니다. PgBouncer 서비스를 시작하고 PostgreSQL 데이터베이스에 대한 연결을 프록시할 수 있는지 확인했습니다. pgbench를 사용하여 실제 클라이언트 로드를 시뮬레이션한 다음 PgBouncer 의 관리 콘솔을 사용하여 결과를 모니터링했습니다. 이를 통해 연결 풀링이 어떻게 작동하는지, 그리고 효율적인 데이터베이스 성능을 보장하기 위해 어떻게 모니터링할 수 있는지에 대한 실질적인 통찰력을 얻었습니다.