使用 PgBouncer 连接池程序

选择文档版本:

本页面介绍了如何使用 AlloyDB Omni Kubernetes operator 为 AlloyDB Omni 启用和使用 PgBouncer 连接池程序。

许多应用(尤其是 Web 应用)会频繁打开和关闭数据库连接,这可能会给数据库实例带来大量负载。PgBouncer 通过更有效地管理连接,来帮助减少实例负载。通过重复使用连接,PgBouncer 可最大限度地减少与数据库实例的连接数,从而释放实例上的资源。

创建 PgBouncer 服务

借助 AlloyDB Omni Kubernetes operator,您可以为数据库创建专用的 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 自定义资源的名称。
    • 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. 创建 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 监听的端口。

    终端窗口会显示以 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:包含 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 operator 会自动将更改应用于您的 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_KEYvalues 数组必须为空。
    • DoesNotExist:节点上不得存在标签 LABEL_KEYvalues 数组必须为空。
    • 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 设置可确保仅在带有 nodetype=pgbouncer 标签的节点上调度 PgBouncer Pod。

删除 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 连接池指标。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_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 准备就绪后,系统会使用分配给 LoadBalancer 服务的外部 IP 地址填充 EXTERNAL_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 会自动应用更改。

后续步骤