Use o PgBouncer connection pooler

Selecione uma versão da documentação:

Esta página descreve como ativar e usar o pooler de ligações PgBouncer para o AlloyDB Omni através do operador do Kubernetes do AlloyDB Omni.

Muitas aplicações, especialmente aplicações Web, abrem e fecham ligações à base de dados com frequência, o que pode exercer uma carga significativa na instância da base de dados. O PgBouncer ajuda a reduzir a carga da instância ao gerir as ligações de forma mais eficiente. Ao reutilizar as ligações, o PgBouncer minimiza o número de ligações à instância da base de dados, libertando recursos na instância.

Crie um serviço PgBouncer

O operador do Kubernetes do AlloyDB Omni permite-lhe criar um serviço PgBouncer dedicado para a sua base de dados. Em seguida, pode aceder à base de dados através do serviço PgBouncer para beneficiar da partilha de ligações.

Existe uma definição de recurso personalizado (CRD) dedicada para configurar o seu serviço PgBouncer conforme necessário.

Para criar um serviço PgBouncer para a sua base de dados, siga estes passos:

  1. Crie um PgBouncer recurso personalizado no seu cluster do Kubernetes da seguinte forma:

    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"

    Substitua o seguinte:

    • PGBOUNCER_NAME: o nome do seu recurso personalizado do PgBouncer.
    • DB_CLUSTER_NAME: o nome do cluster da base de dados do AlloyDB Omni. É o mesmo nome do cluster da base de dados que declarou quando o criou.
    • POOL_MODE: especifica quando uma ligação à base de dados pode ser reutilizada por outros clientes. Defina o parâmetro para uma das seguintes opções:
      • session: a ligação da base de dados é devolvida ao conjunto após a desconexão do cliente. Usado por predefinição.
      • transaction: a ligação à base de dados é libertada para o conjunto após a conclusão da transação.
      • statement: a ligação à base de dados é libertada para o conjunto após a conclusão da consulta. As transações que abrangem vários extratos são proibidas neste modo.
    • IGNORE_STARTUP_PARAMETERS: especifica parâmetros que o PgBouncer não permite para que sejam ignorados durante o arranque, por exemplo, extra_float_digits. Para mais informações, consulte o artigo Configuração do PgBouncer.
    • DEFAULT_POOL_SIZE: o número de ligações à base de dados a permitir por par de utilizador/base de dados, por exemplo, 8.
    • MAXIMUM_CLIENT_CONNECTIONS: o número máximo de ligações de clientes, por exemplo, 800.
    • MAXIMUM_DATABASE_CONNECTIONS: o número máximo de ligações à base de dados, por exemplo, 160.
  2. Aplique o manifesto:

    kubectl apply -f PATH_TO_MANIFEST -n NAMESPACE

    Substitua PATH_TO_MANIFEST pelo caminho para o seu ficheiro de manifesto, por exemplo, /fleet/config/pgbouncer.yaml.

  3. Para verificar se o objeto PgBouncer que criou está pronto, execute a seguinte consulta:

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

    Substitua NAMESPACE pelo nome do espaço de nomes do Kubernetes para o seu objeto PgBouncer.

    O resultado é semelhante ao seguinte:

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

Ligue-se ao ponto final do agrupador de ligações

Pode estabelecer ligação ao PgBouncer a partir de dentro ou fora de um cluster do Kubernetes.

Ligue a partir de um cluster do Kubernetes

Para se ligar ao ponto final do agrupador de ligações através do cliente psql, siga estes passos:

  1. Crie um Pod da seguinte forma:

    apiVersion: v1
    kind: Pod
    metadata:
      name: postgres
    spec:
      containers:
      - image: "docker.io/library/postgres:latest"
        command:
         - "sleep"
         - "604800"
        name: db-client
    
  2. Aplique o manifesto:

    kubectl apply -f PATH_TO_MANIFEST -n NAMESPACE
    
  3. Ligue-se à aplicação contentorizada:

    kubectl exec -it postgres -n NAMESPACE -- bash
    
  4. Valide a ligação SSL ao ponto final do PgBouncer através do cliente psql:

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

    Substitua o seguinte:

    • HOST: o ponto final do agrupador de ligações que obtém através do comando kubectl get pgbouncers.alloydbomni.dbadmin.goog -n NAMESPACE. Se o PgBouncer não estiver exposto como um serviço, use o respetivo endereço IP.
    • PORT: a porta na qual o PgBouncer está a escutar.

    A janela de terminal apresenta o texto de início de sessão psql que termina com um comando postgres=#.

Ligue a partir do exterior de um cluster Kubernetes

Para aceder ao pool de ligações do PgBouncer a partir do exterior de um cluster do Kubernetes, defina o campo type no atributo serviceOptions como LoadBalancer, o que cria um serviço loadbalancer.

  1. Crie um PgBouncer recurso personalizado no seu cluster do Kubernetes da seguinte forma:

    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. Aplique o manifesto:

    kubectl apply -f PATH_TO_MANIFEST
  3. Para verificar se o objeto PgBouncer que criou está pronto, execute a seguinte consulta:

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

    O resultado é semelhante ao seguinte:

    NAME          ENDPOINT       STATE
    mypgbouncer   10.138.15.207   Ready
    

Configure as definições do PgBouncer

Use os seguintes parâmetros para configurar as definições do PGBouncer:

Parâmetro Descrição Valor predefinido
pool_mode Especifica quando uma ligação à base de dados pode ser reutilizada por outros clientes.
Os valores permitidos são os seguintes:
  • session: a ligação da base de dados é devolvida ao conjunto após a desconexão do cliente.
  • transaction: a ligação à base de dados é libertada para o conjunto após a conclusão da transação.
  • statement: a ligação à base de dados é devolvida ao conjunto após a conclusão da consulta.
    As transações que abrangem várias declarações não são permitidas neste modo.
session
ignore_startup_parameters Especifica parâmetros que o PgBouncer não permite para que sejam ignorados durante o arranque.
default_pool_size O número de ligações à base de dados a permitir por par utilizador-base de dados. 20
max_client_conn O número máximo de ligações de clientes. 100
max_db_connections O número máximo de ligações à base de dados. 0

Personalize a implementação do PgBouncer

O AlloyDB Omni usa recursos personalizados para gerir os respetivos componentes. Para personalizar a implementação do PgBouncer no AlloyDB Omni no Kubernetes, modifique o recurso personalizado PgBouncer da seguinte forma:

  1. Liste os PgBouncerrecursos personalizados:

    kubectl get pgbouncers -n NAMESPACE

    Substitua NAMESPACE pelo espaço de nomes onde implementou o AlloyDB Omni.

  2. Para modificar o recurso, abra o ficheiro de declaração do recurso PgBouncer no seu editor predefinido:

    kubectl edit pgbouncers PGBOUNCER_NAME -n NAMESPACE
  3. No ficheiro de declaração, encontre a secção podSpec que contém a configuração e modifique qualquer um dos seguintes campos, conforme necessário:

    • resources: o cpu e o memory definidos para o seu contentor:

      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: o caminho para a etiqueta da imagem do PgBouncer:

      ...
        podSpec:
          resources:
            memory: 1Gi
            cpu: 1
          image: IMAGE
      ...
      
    • schedulingconfig: inclua a secção nodeaffinity para controlar onde os pods do PgBouncer são agendados:

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

      Substitua o seguinte:

      • NODE_AFFINITY_TYPE: defina o parâmetro para uma das seguintes opções:
        • requiredDuringSchedulingIgnoredDuringExecution: o Kubernetes agenda o pod exatamente com base nas regras definidas.
        • preferredDuringSchedulingIgnoredDuringExecution: o programador do Kubernetes tenta encontrar um nó que cumpra a regra definida para o agendamento. No entanto, se não existir esse nó, o Kubernetes agenda para um nó diferente no cluster.
      • LABEL_KEY: a etiqueta do nó para a chave que serve como indicador de localização e facilita a distribuição uniforme de pods no cluster, por exemplo, nodetype.
      • OPERATOR_VALUE: representa a relação de uma chave com um conjunto de valores. Defina o parâmetro para uma das seguintes opções:
        • In: a matriz de valores não pode estar vazia.
        • NotIn: a matriz de valores não pode estar vazia.
        • Exists: a matriz de valores tem de estar vazia.
        • DoesNotExist: a matriz de valores tem de estar vazia.
        • Gt: a matriz de valores tem de ter um único elemento, que é interpretado como um número inteiro.
        • Lt: a matriz de valores tem de ter um único elemento, que é interpretado como um número inteiro.
  4. Depois de fazer as alterações, guarde o ficheiro de declaração. O operador do Kubernetes do AlloyDB Omni aplica automaticamente as alterações à sua implementação do PgBouncer.

Elimine o recurso PgBouncer

Para eliminar um recurso personalizado do PgBouncer, execute o seguinte comando:

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

O resultado é semelhante ao seguinte:

pgbouncer.alloydbomni.dbadmin.goog "mypgbouncer" deleted

Veja os registos do PgBouncer

Pode ver e analisar os registos de qualquer instância de réplica do PgBouncer na sua implementação do AlloyDB Omni no Kubernetes da seguinte forma:

  1. Obtenha uma lista de todos os pods do PgBouncer no seu espaço de nomes:

    kubectl get pods -n NAMESPACE

    O resultado é semelhante ao seguinte:

    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. Ver registos de um Pod específico:

    kubectl logs -f POD_NAME -n NAMESPACE

    O resultado é semelhante ao seguinte:

    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
    

Monitorize o desempenho e a atividade do PgBouncer

Só pode ver as métricas do conjunto de ligações do PgBouncer através de um statsuser dedicado para aceder à base de dados de estatísticas internas do PgBouncer. O statsuser é usado para a autenticação quando se liga à base de dados do PgBouncer.

  1. Ligue-se ao AlloyDB Omni como superutilizador ou utilizador com o privilégio CREATE ROLE através do cliente psql:

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

    O resultado é semelhante ao seguinte:

    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. Crie o statsuser no AlloyDB Omni:

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

    O resultado é semelhante ao seguinte:

    CREATE ROLE
    postgres=#
    
  3. Associe-se à base de dados do PgBouncer como statsuser:

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

    O resultado é semelhante ao seguinte:

    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. Execute o comando SHOW STATS para ver o desempenho do PgBouncer e identificar potenciais problemas:

    pgbouncer=# SHOW STATS;
    

    O resultado é semelhante ao seguinte:

         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)
    

Configure o acesso à rede da sua instância do AlloyDB Omni

Para garantir a segurança da sua implementação do AlloyDB Omni no Kubernetes, pode limitar o acesso à rede ao pool de ligações do PgBouncer definindo intervalos de endereços IP específicos através da notação CIDR (Classless Inter-Domain Routing).

A notação CIDR combina um endereço IP com um comprimento do prefixo. Por exemplo, o bloco CIDR 192.168.1.0/24 especifica 192.168.1.0 para o endereço e 24 para o comprimento do prefixo. O comprimento do prefixo especifica o número de bits no endereço IP que são usados para a parte da rede e define a máscara de sub-rede.

No ficheiro de declaração da implementação, localize a secção serviceOptions e adicione ou modifique a definição loadBalancerSourceRanges:

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

Substitua CIDR_BLOCK por uma string CIDR que especifique os intervalos de endereços IP permitidos para ligações recebidas ao serviço LoadBalancer. A definição loadBalancerSourceRanges filtra o tráfego de rede recebido e controla que clientes podem aceder à sua instância da base de dados.

Para verificar se a configuração do loadBalancerSourceRanges foi aplicada corretamente, use o seguinte comando para verificar o endereço IP externo atribuído ao seu serviço LoadBalancer:

kubectl get svc -n NAMESPACE -w

Substitua NAMESPACE pelo espaço de nomes onde a sua implementação do AlloyDB Omni está localizada.

O resultado é semelhante ao seguinte:

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

Quando o LoadBalancer estiver pronto, a coluna EXTERNAL_IP é preenchida com o endereço IP externo atribuído ao serviço LoadBalancer. As ligações a este IP externo são filtradas com base na definição loadBalancerSourceRanges.

Depois de validar o IP externo, teste as ligações a partir de aplicações nos seus intervalos CIDR permitidos para garantir que conseguem estabelecer ligação.

Desative o PgBouncer connection pooler

Se precisar de desativar ou reverter o PgBouncer, siga estes passos:

  1. Verifique o estado do agrupador de ligações:

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

    Este comando mostra o manifesto de implementação do controlador principal para gerir a frota do AlloyDB Omni. Encontre a opção --enable-pgbouncer na secção args da matriz containers:

    ...
     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. Edite a configuração da implementação do controlador para desativar o pooler de ligações:

    kubectl edit deployment fleet-controller-manager --namespace alloydb-omni-system
  3. No manifesto de implementação, altere o valor da opção --enable-pgbouncer de true para false:

    ...
    --enable-pgbouncer=false
    
  4. Guarde o ficheiro e saia do editor. O kubectl aplica automaticamente a alteração.

O que se segue?