PgBouncer 연결 풀러 사용

이 페이지에서는 AlloyDB Omni Kubernetes 운영자를 사용하여 AlloyDB Omni용 PgBouncer 연결 풀러를 사용 설정하고 사용하는 방법을 설명합니다.

많은 애플리케이션(특히 웹 애플리케이션)은 데이터베이스 연결을 자주 열고 닫으므로 데이터베이스 인스턴스에 상당한 부하를 줄 수 있습니다. PgBouncer는 연결을 더 효율적으로 관리하여 인스턴스 부하를 줄이는 데 도움이 됩니다. PgBouncer는 연결을 재사용하여 데이터베이스 인스턴스에 대한 연결 수를 최소화하여 인스턴스의 리소스를 확보합니다.

PgBouncer 서비스 만들기

AlloyDB Omni Kubernetes 연산자를 사용하면 데이터베이스에 전용 PgBouncer 서비스를 만들 수 있습니다. 그런 다음 PgBouncer 서비스를 통해 데이터베이스에 액세스하여 연결 풀링의 이점을 누릴 수 있습니다.

필요에 따라 PgBouncer 서비스를 구성하기 위한 전용 커스텀 리소스 정의 (CRD)가 있습니다.

데이터베이스에 PgBouncer 서비스를 만들려면 다음 단계를 따르세요.

  1. 다음과 같이 Kubernetes 클러스터에 PgBouncer 맞춤 리소스를 만듭니다.

    apiVersion: alloydbomni.dbadmin.goog/v1
    kind: PgBouncer
    metadata:
      name: PGBOUNCER_NAME
    spec:
      dbclusterRef: DB_CLUSTER_NAME
      allowSuperUserAccess: true
      podSpec:
        resources:
          memory: 1Gi
          cpu: 1
        image: "gcr.io/alloydb-omni/operator/g-pgbouncer:1.4.0"
      parameters:
        pool_mode: POOL_MODE
        ignore_startup_parameters: IGNORE_STARTUP_PARAMETERS
        default_pool_size: DEFAULT_POOL_SIZE
        max_client_conn: MAXIMUM_CLIENT_CONNECTIONS
        max_db_connections: MAXIMUM_DATABASE_CONNECTIONS
      serviceOptions:
        type: "ClusterIP"

    다음을 바꿉니다.

    • PGBOUNCER_NAME: PgBouncer 커스텀 리소스의 이름입니다.
    • DB_CLUSTER_NAME: AlloyDB Omni 데이터베이스 클러스터의 이름입니다. 이는 데이터베이스 클러스터를 만들 때 선언한 데이터베이스 클러스터 이름과 동일합니다.
    • POOL_MODE: 다른 클라이언트에서 데이터베이스 연결을 재사용할 수 있는 시점을 지정합니다. 매개변수를 다음 중 하나로 설정합니다.
      • session: 클라이언트 연결이 해제된 후 데이터베이스 연결이 풀에 다시 해제됩니다. 기본적으로 사용됩니다.
      • transaction: 트랜잭션이 완료되면 데이터베이스 연결이 풀에 다시 해제됩니다.
      • statement: 쿼리가 완료되면 데이터베이스 연결이 풀에 다시 해제됩니다. 이 모드에서는 여러 문에 걸친 트랜잭션이 허용되지 않습니다.
    • IGNORE_STARTUP_PARAMETERS: PgBouncer에서 허용하지 않는 매개변수를 지정하여 시작 중에 무시되도록 합니다(예: extra_float_digits). 자세한 내용은 PgBouncer 구성을 참고하세요.
    • DEFAULT_POOL_SIZE: 사용자-데이터베이스 쌍당 허용되는 데이터베이스 연결 수입니다(예: 8).
    • MAXIMUM_CLIENT_CONNECTIONS: 최대 클라이언트 연결 수입니다(예: 800).
    • MAXIMUM_DATABASE_CONNECTIONS: 최대 데이터베이스 연결 수입니다(예: 160).
  2. 매니페스트를 적용합니다.

    kubectl apply -f PATH_TO_MANIFEST -n NAMESPACE

    PATH_TO_MANIFEST을 매니페스트 파일의 경로로 바꿉니다(예: /fleet/config/pgbouncer.yaml).

  3. 만든 PgBouncer 객체가 준비되었는지 확인하려면 다음 쿼리를 실행합니다.

    kubectl get pgbouncers.alloydbomni.dbadmin.goog PGBOUNCER_NAME  -n NAMESPACE -w
    

    NAMESPACE를 PgBouncer 객체의 Kubernetes 네임스페이스 이름으로 바꿉니다.

    출력은 다음과 비슷합니다.

    NAMESPACE   NAME          ENDPOINT        STATE
    dbv2        mypgbouncer
    dbv2        mypgbouncer
    dbv2        mypgbouncer
    dbv2        mypgbouncer                   WaitingForDeploymentReady
    dbv2        mypgbouncer                   Acquiring IP
    dbv2        mypgbouncer   10.138.15.231   Ready
    

연결 풀러 엔드포인트에 연결

Kubernetes 클러스터의 내부 또는 외부에서 PgBouncer 연결 풀러에 연결할 수 있습니다.

Kubernetes 클러스터 내에서 연결

psql 클라이언트를 사용하여 연결 풀러 엔드포인트에 연결하려면 다음 단계를 따르세요.

  1. 다음과 같이 포드를 만듭니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: postgres
    spec:
      containers:
      - image: "docker.io/library/postgres:latest"
        command:
         - "sleep"
         - "604800"
        name: db-client
    
  2. 매니페스트를 적용합니다.

    kubectl apply -f PATH_TO_MANIFEST -n NAMESPACE
    
  3. 컨테이너화된 애플리케이션에 연결합니다.

    kubectl exec -it postgres -n NAMESPACE -- bash
    
  4. psql 클라이언트를 사용하여 PgBouncer 엔드포인트에 대한 SSL 연결을 확인합니다.

    export PGSSLMODE="require"; psql -h HOST -d postgres -U postgres -p PORT
    

    다음을 바꿉니다.

    • HOST: kubectl get pgbouncers.alloydbomni.dbadmin.goog -n NAMESPACE 명령어를 사용하여 가져온 연결 풀러 엔드포인트입니다. PgBouncer가 서비스로 노출되지 않으면 IP 주소를 사용합니다.
    • PORT: PgBouncer가 리슨하는 포트입니다.

    터미널 창에 postgres=# 프롬프트로 끝나는 psql 로그인 텍스트가 표시됩니다.

Kubernetes 클러스터 외부에서 연결

Kubernetes 클러스터 외부에서 PgBouncer 연결 풀러에 액세스하려면 serviceOptions 속성의 type 필드를 LoadBalancer로 설정합니다. 그러면 loadbalancer 서비스가 생성됩니다.

  1. 다음과 같이 Kubernetes 클러스터에 PgBouncer 맞춤 리소스를 만듭니다.

    apiVersion: alloydbomni.dbadmin.goog/v1
    kind: PgBouncer
    metadata:
    name: PGBOUNCER_NAME
    spec:
    dbclusterRef: DB_CLUSTER_NAME
    allowSuperUserAccess: true
    replicaCount: 2
    parameters:
      pool_mode: POOL_MODE
      ignore_startup_parameters: IGNORE_STARTUP_PARAMETERS
      default_pool_size: DEFAULT_POOL_SIZE
      max_client_conn: MAXIMUM_CLIENT_CONNECTIONS
      max_db_connections: MAXIMUM_DATABASE_CONNECTIONS
    podSpec:
      resources:
        memory: 1Gi
        cpu: 1
      image: "gcr.io/alloydb-omni/operator/g-pgbouncer:1.4.0"
    serviceOptions:
      type: "LoadBalancer"
  2. 매니페스트를 적용합니다.

    kubectl apply -f PATH_TO_MANIFEST
  3. 만든 PgBouncer 객체가 준비되었는지 확인하려면 다음 쿼리를 실행합니다.

    kubectl get pgbouncers.alloydbomni.dbadmin.goog PGBOUNCER_NAME  -n NAMESPACE -w

    출력은 다음과 비슷합니다.

    NAME          ENDPOINT       STATE
    mypgbouncer   10.138.15.207   Ready
    

PgBouncer 설정 구성

다음 매개변수를 사용하여 PGBouncer 설정을 구성합니다.

매개변수 설명 기본값
pool_mode 다른 클라이언트에서 데이터베이스 연결을 재사용할 수 있는 시점을 지정합니다.
허용되는 값은 다음과 같습니다.
  • session: 클라이언트 연결이 해제된 후 데이터베이스 연결이 풀에 다시 해제됩니다.
  • transaction: 트랜잭션이 완료되면 데이터베이스 연결이 풀에 다시 해제됩니다.
  • statement: 쿼리가 완료되면 데이터베이스 연결이 풀에 다시 해제됩니다.
    이 모드에서는 여러 문에 걸친 트랜잭션이 허용되지 않습니다.
session
ignore_startup_parameters PgBouncer에서 허용하지 않는 매개변수를 지정하여 시작 중에 무시되도록 합니다.
default_pool_size 사용자-데이터베이스 쌍당 허용되는 데이터베이스 연결 수입니다. 20
max_client_conn 최대 클라이언트 연결 수입니다. 100
max_db_connections 데이터베이스 연결의 최대 수입니다. 0

PgBouncer 배포 맞춤설정

AlloyDB Omni는 맞춤 리소스를 사용하여 구성요소를 관리합니다. Kubernetes의 AlloyDB Omni 내에서 PgBouncer 배포를 맞춤설정하려면 다음과 같이 PgBouncer 커스텀 리소스를 수정합니다.

  1. PgBouncer 커스텀 리소스를 나열합니다.

    kubectl get pgbouncers -n NAMESPACE

    NAMESPACE를 AlloyDB Omni를 배포한 네임스페이스로 바꿉니다.

  2. 리소스를 수정하려면 기본 편집기에서 PgBouncer 리소스의 선언 파일을 엽니다.

    kubectl edit pgbouncers PGBOUNCER_NAME -n NAMESPACE
  3. 선언 파일에서 구성이 포함된 podSpec 섹션을 찾아 필요에 따라 다음 필드를 수정합니다.

    • resources: 컨테이너에 정의된 cpumemory:

      apiVersion: alloydbomni.dbadmin.goog/v1
      kind: PgBouncer
      metadata:
        name: PGBOUNCER_NAME
      spec:
        dbclusterRef: DB_CLUSTER_NAME
        replicaCount: 2
        parameters:
          pool_mode: POOL_MODE
          ignore_startup_parameters: IGNORE_STARTUP_PARAMETERS
          default_pool_size: DEFAULT_POOL_SIZE
          max_client_conn: MAXIMUM_CLIENT_CONNECTIONS
          max_db_connections: MAXIMUM_DATABASE_CONNECTIONS
        podSpec:
          resources:
            memory: 1Gi
            cpu: 1
      ...
      
    • image: PgBouncer 이미지 태그의 경로입니다.

      ...
        podSpec:
          resources:
            memory: 1Gi
            cpu: 1
          image: IMAGE
      ...
      
    • schedulingconfig: PgBouncer 포드가 예약되는 위치를 제어하는 nodeaffinity 섹션을 포함합니다.

      ...
        podSpec:
          resources:
            memory: 1Gi
            cpu: 1
          image: IMAGE
          schedulingconfig:
            nodeaffinity:
              NODE_AFFINITY_TYPE:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: LABEL_KEY
                    operator: OPERATOR_VALUE
                    values:
                    - pgbouncer
      ...
      

      다음을 바꿉니다.

      • NODE_AFFINITY_TYPE: 매개변수를 다음 중 하나로 설정합니다.
        • requiredDuringSchedulingIgnoredDuringExecution: Kubernetes는 정의된 규칙에 따라 정확하게 포드를 예약합니다.
        • preferredDuringSchedulingIgnoredDuringExecution: Kubernetes 스케줄러가 정의된 예약 규칙을 충족하는 노드를 찾으려고 시도합니다. 그러나 이러한 노드가 없으면 Kubernetes는 클러스터의 다른 노드로 예약합니다.
      • LABEL_KEY: 위치 표시기 역할을 하고 클러스터 전반에서 균일한 포드 분배를 용이하게 하는 키의 노드 라벨입니다(예: nodetype).
      • OPERATOR_VALUE: 키와 값 집합의 관계를 나타냅니다. 매개변수를 다음 중 하나로 설정합니다.
        • In: 값 배열은 비어 있지 않아야 합니다.
        • NotIn: 값 배열은 비어 있지 않아야 합니다.
        • Exists: 값 배열은 비어 있어야 합니다.
        • DoesNotExist: 값 배열은 비어 있어야 합니다.
        • Gt: 값 배열에는 정수로 해석되는 단일 요소가 있어야 합니다.
        • Lt: 값 배열에는 정수로 해석되는 단일 요소가 있어야 합니다.
  4. 변경 후 선언 파일을 저장합니다. AlloyDB Omni Kubernetes 연산자는 변경사항을 PgBouncer 배포에 자동으로 적용합니다.

PgBouncer 리소스 삭제

PgBouncer 맞춤 리소스를 삭제하려면 다음 명령어를 실행합니다.

kubectl delete pgbouncers.alloydbomni.dbadmin.goog PGBOUNCER_NAME -n NAMESPACE

출력은 다음과 비슷합니다.

pgbouncer.alloydbomni.dbadmin.goog "mypgbouncer" deleted

PgBouncer 로그 보기

다음과 같이 Kubernetes의 AlloyDB Omni 배포에서 PgBouncer 복제 인스턴스의 로그를 보고 분석할 수 있습니다.

  1. 네임스페이스의 모든 PgBouncer 포드 목록을 가져옵니다.

    kubectl get pods -n NAMESPACE

    출력은 다음과 비슷합니다.

    NAME                                          READY   STATUS    RESTARTS   AGE
    al-092d-dbcluster-sample-0                    3/3     Running   0          3d1h
    mypgbouncer-pgb-deployment-659869f95c-4kbgv   1/1     Running   0          27m
    
  2. 특정 Pod의 로그를 보려면 다음 안내를 따르세요.

    kubectl logs -f POD_NAME -n NAMESPACE

    출력은 다음과 비슷합니다.

    2025-01-21 06:57:39.549 UTC [7] LOG kernel file descriptor limit: 1048576 (hard: 1048576); max_client_conn: 800, max expected fd use: 812
    2025-01-21 06:57:39.550 UTC [7] LOG listening on 0.0.0.0:6432
    2025-01-21 06:57:39.550 UTC [7] LOG listening on [::]:6432
    2025-01-21 06:57:39.550 UTC [7] LOG listening on unix:/tmp/.s.PGSQL.6432
    2025-01-21 06:57:39.550 UTC [7] LOG process up: PgBouncer 1.23.0, libevent 2.1.12-stable (epoll), adns: evdns2, tls: OpenSSL 3.0.13 30 Jan 2024
    2025-01-21 06:58:17.012 UTC [7] LOG C-0x55f2b1b322a0: (nodb)/(nouser)@10.138.15.215:48682 registered new auto-database: alloydbadmin
    2025-01-21 06:58:17.012 UTC [7] LOG S-0x55f2b1b4ecb0: alloydbadmin/alloydbpgbouncer@10.138.0.48:5432 new connection to server (from 10.12.1.113:53156)
    2025-01-21 06:58:17.042 UTC [7] LOG S-0x55f2b1b4ecb0: alloydbadmin/alloydbpgbouncer@10.138.0.48:5432 SSL established: TLSv1.3/TLS_AES_256_GCM_SHA384/ECDH=prime256v1
    2025-01-21 06:58:17.052 UTC [7] LOG C-0x55f2b1b322a0: pgbouncer/statsuser@10.138.15.215:48682 login attempt: db=pgbouncer user=statsuser tls=TLSv1.3/TLS_AES_256_GCM_SHA384 replication=no
    2025-01-21 06:58:19.526 UTC [7] LOG C-0x55f2b1b322a0: pgbouncer/statsuser@10.138.15.215:48682 closing because: client close request (age=2s)
    2025-01-21 06:58:20.344 UTC [7] LOG C-0x55f2b1b322a0: pgbouncer/statsuser@10.138.15.215:46796 login attempt: db=pgbouncer user=statsuser tls=TLSv1.3/TLS_AES_256_GCM_SHA384 replication=no
    

PgBouncer 성능 및 활동 모니터링

전용 statsuser만 사용하여 PgBouncer 내부 통계 데이터베이스에 액세스하여 PgBouncer 연결 풀 측정항목을 볼 수 있습니다. statsuser은 PgBouncer 데이터베이스에 연결할 때 인증에 사용됩니다.

  1. psql 클라이언트를 사용하여 수퍼유저 또는 CREATE ROLE 권한이 있는 사용자로 AlloyDB Omni에 연결합니다.

    export PGPASSWORD="ChangeMe123"; export PGSSLMODE="require"; psql -h HOST -d postgres -U postgres -p PORT
    

    출력은 다음과 비슷합니다.

    psql (16.6 (Ubuntu 16.6-0ubuntu0.24.04.1), server 15.7)
    SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
    Type "help" for help.
    
  2. AlloyDB Omni에서 statsuser를 만듭니다.

    postgres=# CREATE USER "statsuser" WITH PASSWORD 'tester';
    

    출력은 다음과 비슷합니다.

    CREATE ROLE
    postgres=#
    
  3. statsuser로 PgBouncer 데이터베이스에 연결합니다.

    export PGPASSWORD="ChangeMe123"; export PGSSLMODE="require"; psql -h HOST -d pgbouncer -U statsuser -p PORT
    

    출력은 다음과 비슷합니다.

    psql (16.6 (Ubuntu 16.6-0ubuntu0.24.04.1), server 1.23.0/bouncer)
    WARNING: psql major version 16, server major version 1.23.
    Some psql features might not work.
    SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
    Type "help" for help.
    
  4. SHOW STATS 명령어를 실행하여 PgBouncer 성능을 확인하고 잠재적인 문제를 식별합니다.

    pgbouncer=# SHOW STATS;
    

    출력은 다음과 비슷합니다.

         database   | total_server_assignment_count | total_xact_count | total_query_count | total_received | total_sent | total_xact_time | total_query_time | total_wait_time | avg_server_assignment_count | avg_xact_count | avg_query_count | avg_recv | avg_sent | avg_xact_time | avg_query_time | avg_wait_time
       -------------+-------------------------------+------------------+-------------------+----------------+------------+-----------------+------------------+-----------------+-----------------------------+----------------+-----------------+----------+----------+---------------+----------------+---------------
       alloydbadmin |                             1 |                0 |                 0 |              0 |        330 |               0 |                0 |           41730 |                           0 |              0 |               0 |        0 |        2 |             0 |              0 |         41730
       pgbouncer    |                             0 |                5 |                 5 |              0 |          0 |               0 |                0 |               0 |                           0 |              0 |               0 |        0 |        0 |             0 |              0 |             0
       (2 rows)
    

AlloyDB Omni 인스턴스에 대한 네트워크 액세스 구성

Kubernetes에서 AlloyDB Omni 배포의 보안을 보장하려면 CIDR (클래스 없는 도메인 간 라우팅) 표기법을 사용하여 특정 IP 주소 범위를 정의하여 PgBouncer 연결 풀러에 대한 네트워크 액세스를 제한할 수 있습니다.

CIDR 표기법은 IP 주소와 접두사 길이를 결합합니다. 예를 들어 CIDR 블록 192.168.1.0/24은 주소에 192.168.1.0을 지정하고 접두사 길이에 24을 지정합니다. 접두사 길이는 IP 주소에서 네트워크 부분에 사용되는 비트 수를 지정하고 서브넷 마스크를 정의합니다.

배포 선언 파일에서 serviceOptions 섹션을 찾아 loadBalancerSourceRanges 설정을 추가하거나 수정합니다.

  serviceOptions:
    type: "LoadBalancer"
    loadBalancerSourceRanges:
    - "CIDR_BLOCK"

CIDR_BLOCKLoadBalancer 서비스에 대한 수신 연결에 허용되는 IP 주소 범위를 지정하는 CIDR 문자열로 바꿉니다. loadBalancerSourceRanges 설정은 수신되는 네트워크 트래픽을 필터링하고 데이터베이스 인스턴스에 액세스할 수 있는 클라이언트를 제어합니다.

loadBalancerSourceRanges 구성이 올바르게 적용되었는지 확인하려면 다음 명령어를 사용하여 LoadBalancer 서비스에 할당된 외부 IP 주소를 확인합니다.

kubectl get svc -n NAMESPACE -w

NAMESPACE를 AlloyDB Omni 배포가 있는 네임스페이스로 바꿉니다.

출력은 다음과 비슷합니다.

NAME                     TYPE           CLUSTER_IP      EXTERNAL_IP   PORT(S)         AGE
al-mypgbouncer-pgb-svc   LoadBalancer   34.118.230.149  10.138.0.26   6432:31367/TCP  3m39s

LoadBalancer가 준비되면 EXTERNAL_IP 열에 LoadBalancer 서비스에 할당된 외부 IP 주소가 채워집니다. 이 외부 IP에 대한 연결은 loadBalancerSourceRanges 설정에 따라 필터링됩니다.

외부 IP를 확인한 후 허용된 CIDR 범위 내 애플리케이션의 연결을 테스트하여 연결할 수 있는지 확인합니다.

PgBouncer 연결 풀러 사용 중지

PgBouncer 연결 풀러를 비활성화하거나 롤백해야 하는 경우 다음 단계를 따르세요.

  1. 연결 풀러의 상태를 확인합니다.

    kubectl get deployment fleet-controller-manager --namespace alloydb-omni-system  -o json | jq '.spec.template.spec.containers[0].args'

    이 명령어는 AlloyDB Omni 함대를 관리하기 위한 기본 컨트롤러의 배포 매니페스트를 보여줍니다. containers 배열의 args 섹션에서 --enable-pgbouncer 옵션을 찾습니다.

    ...
     spec:
      containers:
      - name: fleet-controller-manager
        image:...
        args:
        --health-probe-bind-address=:8081",
        --metrics-bind-address=127.0.0.1:8080",
        --leader-elect",
        --image-registry=gcr.io",
        --data-plane-image-repository=alloydb-omni-staging",
        --control-plane-agents-image-repository=aedi-gbox",
        --control-plane-agents-tag=jan19v3",
        --additional-db-versions-for-test-only=latest",
        --enable-multiple-backup-solutions=true",
        --enable-pgbouncer=true
    
  2. 연결 풀러를 사용 중지하도록 컨트롤러 배포의 구성을 수정합니다.

    kubectl edit deployment fleet-controller-manager --namespace alloydb-omni-system
  3. 배포 매니페스트에서 --enable-pgbouncer 옵션의 값을 true에서 false로 변경합니다.

    ...
    --enable-pgbouncer=false
    
  4. 파일을 저장하고 편집기를 종료합니다. kubectl이 변경사항을 자동으로 적용합니다.

다음 단계