使用 PgBouncer 連線集區

本頁說明如何使用 AlloyDB Omni Kubernetes 運算子,為 AlloyDB Omni 啟用及使用 PgBouncer 連線集區。

許多應用程式 (尤其是網頁應用程式) 經常開啟及關閉資料庫連線,這可能會對資料庫執行個體造成重大負擔。PgBouncer 可更有效率地管理連線,有助於降低執行個體負載。PgBouncer 會重複使用連線,盡量減少資料庫執行個體的連線數量,釋放執行個體上的資源。

建立 PgBouncer 服務

AlloyDB Omni Kubernetes 運算子可讓您為資料庫建立專屬的 PgBouncer 服務。接著,您就能透過 PgBouncer 服務存取資料庫,享受連線集區的優點。

您可以透過專用的自訂資源定義 (CRD),視需要設定 PgBouncer 服務。

如要為資料庫建立 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 自訂資源的名稱。
    • :AlloyDB Omni 資料庫叢集的名稱。DB_CLUSTER_NAME也就是建立資料庫叢集時宣告的名稱。
    • 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. 建立 Pod 的步驟如下:

    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 監聽的通訊埠。

    終端機視窗會顯示 psql 登入文字,結尾為 postgres=# 提示。

從 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:加入 nodeaffinity 區段,控管 PgBouncer Pod 的排程位置:

      ...
        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 會根據定義的規則排定 Pod。
        • preferredDuringSchedulingIgnoredDuringExecution:Kubernetes 排程器會嘗試尋找符合排程定義規則的節點。不過,如果沒有這類節點,Kubernetes 會排程至叢集中的其他節點。
      • LABEL_KEY:節點的鍵標籤,可做為位置指標,並在叢集中平均分配 Pod,例如 nodetype
      • OPERATOR_VALUE:代表鍵與一組值的關係。將參數設為下列其中一個值:
        • In:值陣列不得為空。
        • NotIn:值陣列不得為空。
        • Exists:值陣列必須為空白。
        • DoesNotExist:值陣列必須為空白。
        • Gt:值陣列必須只有一個元素,且會解譯為整數。
        • Lt:值陣列必須只有一個元素,且會解譯為整數。
  4. 變更完成後,請儲存聲明檔案。AlloyDB Omni Kubernetes 運算子會自動將變更套用至 PgBouncer 部署作業。

使用節點親和性排程

您可以使用節點親和性,控管 PgBouncer Pod 的排程位置,比一般排程更精確。節點親和性可確保 PgBouncer Pod 放置在符合特定條件的節點上,例如具有特定標籤。

如要為 PgBouncer Pod 指定節點親和性,請修改 PgBouncer 自訂資源,將 schedulingconfig 區段新增至 podSpec 區段:

apiVersion: alloydbomni.dbadmin.goog/v1
kind: PgBouncer
metadata:
  name: PGBOUNCER_NAME
spec:
  # ... other PgBouncer configuration ...
  podSpec:
    # ... other podSpec settings ...
    schedulingconfig:
      nodeaffinity:
        NODE_AFFINITY_TYPE:
          nodeSelectorTerms:
          - matchExpressions:
            - key: LABEL_KEY
              operator: OPERATOR_VALUE
              values:
              - pgbouncer

更改下列內容:

  • NODE_AFFINITY_TYPE:將參數設為下列其中一個值:
    • requiredDuringSchedulingIgnoredDuringExecution:Kubernetes 會根據定義的規則排定 Pod。
    • preferredDuringSchedulingIgnoredDuringExecution:Kubernetes 排程器會嘗試尋找符合排程定義規則的節點。不過,如果沒有這類節點,Kubernetes 會排程至叢集中的其他節點。
  • LABEL_KEY:節點標籤鍵。例如:disktype=ssd
  • OPERATOR_VALUE:代表鍵與一組值的關係。將參數設為下列其中一個值:
    • In:節點標籤值必須與 values 陣列中的值相符。
    • NotIn:節點標籤值不得與 values 陣列中的任何值相符。
    • Exists:節點上必須有 LABEL_KEY 標籤。values 陣列必須為空。
    • DoesNotExist:節點上不得有 LABEL_KEY 標籤。values 陣列必須為空。
    • Gt:節點標籤值必須大於 values 陣列中的單一值,且會解譯為整數。
    • Lt:節點標籤值必須小於 values 陣列中的單一值,該值會解讀為整數。

以下範例說明如何在標示為 nodetype=pgbouncer 的節點上排定 PgBouncer Pod:

apiVersion: alloydbomni.dbadmin.goog/v1
kind: PgBouncer
metadata:
  name: mypgbouncer
spec:
  # ... other PgBouncer configuration ...
  podSpec:
    # ... other podSpec settings ...
    schedulingconfig:
      nodeaffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: nodetype
              operator: In
              values:
              - pgbouncer

在本範例中,requiredDuringSchedulingIgnoredDuringExecution 設定可確保 PgBouncer Pod 只會排程至標籤為 nodetype=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 Pod:

    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 連線集區指標。連線至 PgBouncer 資料庫時,系統會使用 statsuser 進行驗證。

  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_BLOCK 替換為 CIDR 字串,指定允許連入 LoadBalancer 服務的 IP 位址範圍。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」EXTERNAL_IP欄會填入指派給 LoadBalancer 服務的外部 IP 位址。系統會根據 loadBalancerSourceRanges 設定,篩選連線至這個外部 IP 的連線。

驗證外部 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 會自動套用變更。

後續步驟