PostgreSQL
강의

#8 - PgBouncer 실전 운영 챕터 - Spring Boot 읽기·쓰기 분리 전략

중년개발자
중년개발자

@loxo

16일 전

23

PgBouncer 실전 운영 챕터

Master / Replica 분리, DNS 설계, Spring Boot 읽기·쓰기 분리 전략


0. 이 챕터의 전제 (중요)

이 문서는 PgBouncer 공식 문서의 동작 원리를 기반으로,

  • PostgreSQL Master / Replica 구조
  • DNS 또는 엔드포인트 분리
  • PgBouncer databases 섹션 설계
  • Spring Boot 입장에서의 쓰기 / 읽기 분리 전략

실제 운영에서 가장 많이 쓰이는 방식으로 정리한 실전 가이드다.

목표는 "개념 설명"이 아니라 운영자가 그대로 가져다 쓸 수 있는 설정이다.


1. PostgreSQL Master / Replica 구조 복습

PostgreSQL 자체는 Read / Write 분리를 자동으로 해주지 않는다.

  • Write → 반드시 Master
  • Read → Replica 여러 대로 분산 가능

따라서 분리는 반드시 애플리케이션 또는 미들웨어 계층에서 수행해야 한다.


2. PgBouncer의 핵심 한계 (중요한 오해 정리)

PgBouncer는:

  • ❌ SQL을 파싱해서 읽기/쓰기를 구분하지 않는다
  • ❌ SELECT 를 자동으로 Replica 로 보내주지 않는다

PgBouncer는 오직:

"어떤 접속 엔드포인트(alias) 로 들어왔는가"만 본다

👉 읽기/쓰기 분리는 접속 단에서 이미 결정되어 있어야 한다

이 점이 실전 설계의 출발점이다.


3. 실전 표준 아키텍처 (DNS + PgBouncer)

핵심 설계 포인트

  • PgBouncer 인스턴스는 논리적으로 2개

    • write 전용
    • read 전용
  • 실제로는 같은 서버 / 같은 프로세스여도 무방

  • DNS 또는 Service 이름으로 역할을 분리


4. pgbouncer.ini 실전 구성 (Master / Replica 분리)

4.1 databases 섹션 – 핵심 중의 핵심

ini
[databases] # Write 전용 (Master) mydb_write = host=pg-master.mydb.internal port=5432 dbname=mydb # Read 전용 (Replica Pool) mydb_read = host=pg-replica.mydb.internal port=5432 dbname=mydb

중요한 포인트

  • pg-replica.mydb.internal 은:

    • DNS Round Robin
    • 또는 L4/L7 Load Balancer
    • 또는 Cloud Provider Read Endpoint
  • PgBouncer는 Replica 개수를 모른다

  • 단지 "이 host 로 연결한다"고만 이해한다


4.2 PgBouncer 공통 설정 (실전 표준)

ini
[pgbouncer] listen_addr = 0.0.0.0 listen_port = 6432 auth_type = scram-sha-256 auth_file = /etc/pgbouncer/userlist.txt pool_mode = transaction max_client_conn = 5000 default_pool_size = 100 reserve_pool_size = 20 server_idle_timeout = 60 server_lifetime = 3600 logfile = /var/log/pgbouncer/pgbouncer.log pidfile = /var/run/pgbouncer/pgbouncer.pid

5. userlist.txt 실전 운영 방식

PgBouncer는 PostgreSQL 자체 인증을 하지 않는다.

  • userlist.txt 만 신뢰
  • 이 파일은 PostgreSQL 에서 SELECT 로 생성해야 한다

5.1 userlist.txt 형식

"app_user" "SCRAM-SHA-256$..."

5.2 운영 패턴 (권장)

  1. PostgreSQL 에서 사용자/비밀번호 관리
  2. pg_authid 또는 pg_shadow 조회
  3. 스크립트로 userlist.txt 생성
  4. PgBouncer reload

👉 인증의 단일 진실 소스는 PostgreSQL


6. Spring Boot 입장에서의 읽기 / 쓰기 분리

6.1 가장 중요한 사실

Spring Boot는:

  • ❌ PgBouncer에게 읽기/쓰기를 맡기지 않는다
  • DataSource 를 분리해서 직접 제어한다

6.2 실전 표준: DataSource 2개

yaml
spring: datasource: write: url: jdbc:postgresql://pgbouncer-write.mydb.internal:6432/mydb username: app_user password: ******** read: url: jdbc:postgresql://pgbouncer-read.mydb.internal:6432/mydb username: app_user password: ********

6.3 트랜잭션 라우팅 전략

가장 많이 쓰이는 방식:

  • @Transactional(readOnly = true) → Read DataSource
  • 나머지 → Write DataSource

이 로직은 Spring 레벨에서 결정된다

PgBouncer는 단순히 연결을 효율적으로 관리할 뿐이다.


7. 흔한 실수 TOP 5

  1. PgBouncer가 SQL을 보고 Replica로 보내줄 거라 착각
  2. Write / Read 를 같은 엔드포인트로 사용
  3. Replica 에서 트랜잭션 쓰기 시도
  4. userlist.txt 수동 편집
  5. pool_mode = session 사용

8. 운영자 관점 한 줄 요약

PgBouncer는 트래픽을 분산하지 않는다.
PgBouncer는 연결 비용을 줄일 뿐이다.

읽기/쓰기 분리는:

  • DNS
  • Endpoint
  • Application

이 셋 중 하나에서 반드시 명확히 결정되어야 한다.


9. 공식 문서 참고 포인트

  • PgBouncer does not do query routing
  • Databases section defines logical endpoints
  • Pooling happens per database + user

(공식 문서: https://www.pgbouncer.org/usage.html)


마지막 정리 문장

"PgBouncer는 DB 아키텍처를 대신 설계해주지 않는다.
대신, 올바른 설계를 전제로 했을 때 시스템을 버티게 해준다."

목차

#PgBouncer#PostgreSQL#Spring Boot#Read/Write Splitting#Master/Replica

댓글 0

Ctrl + Enter를 눌러 등록할 수 있습니다
※ AI 다듬기는 내용을 정제하는 보조 기능이며, 최종 내용은 사용자가 확인해야 합니다.