Usar o pool de conexões do PgBouncer

Selecione uma versão da documentação:

Nesta página, descrevemos como ativar e usar o pooler de conexões PgBouncer para o AlloyDB Omni usando o operador do AlloyDB Omni no Kubernetes.

Muitos aplicativos, principalmente os da Web, abrem e fecham conexões de banco de dados com frequência, o que pode colocar uma carga significativa na instância do banco de dados. O PgBouncer ajuda a reduzir a carga da instância gerenciando as conexões com mais eficiência. Ao reutilizar conexões, o PgBouncer minimiza o número de conexões com a instância do banco de dados, liberando recursos na instância.

Criar um serviço do PgBouncer

O operador do AlloyDB Omni no Kubernetes permite criar um serviço PgBouncer dedicado para seu banco de dados. Em seguida, acesse o banco de dados pelo serviço PgBouncer para aproveitar o pool de conexões.

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

Para criar um serviço do PgBouncer para seu banco de dados, siga estas etapas:

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

    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:

    • PGBOUNCER_NAME: o nome do seu recurso personalizado do PgBouncer.
    • DB_CLUSTER_NAME: o nome do cluster de banco de dados do AlloyDB Omni. É o mesmo nome de cluster de banco de dados que você declarou ao criá-lo.
    • POOL_MODE: especifica quando uma conexão de banco de dados pode ser reutilizada por outros clientes. Defina o parâmetro como uma das seguintes opções:
      • session: a conexão com o banco de dados é liberada de volta para o pool quando o cliente se desconecta. Usado por padrão.
      • transaction: a conexão com o banco de dados é liberada de volta para o pool após a conclusão da transação.
      • statement: a conexão com o banco de dados é liberada de volta para o pool após a conclusão da consulta. Transações que abrangem várias instruções não são permitidas nesse modo.
    • IGNORE_STARTUP_PARAMETERS: especifica parâmetros que o PgBouncer não permite para que sejam ignorados durante a inicialização. Por exemplo, extra_float_digits. Para mais informações, consulte Configuração do PgBouncer.
    • DEFAULT_POOL_SIZE: o número de conexões de banco de dados permitidas por par usuário-banco de dados, por exemplo, 8.
    • MAXIMUM_CLIENT_CONNECTIONS: o número máximo de conexões de cliente, por exemplo, 800.
    • MAXIMUM_DATABASE_CONNECTIONS: o número máximo de conexões de banco 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 arquivo de manifesto, por exemplo, /fleet/config/pgbouncer.yaml.

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

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

    Substitua NAMESPACE pelo nome do namespace do Kubernetes para seu objeto PgBouncer.

    O resultado será o 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
    

Conectar-se ao endpoint do pooler de conexões

É possível se conectar ao pool de conexões do PgBouncer dentro ou fora de um cluster do Kubernetes.

Conectar de dentro de um cluster do Kubernetes

Para se conectar ao endpoint do pool de conexões usando o cliente psql, siga estas etapas:

  1. Crie um pod da seguinte maneira:

    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. Conecte-se ao aplicativo em contêiner:

    kubectl exec -it postgres -n NAMESPACE -- bash
    
  4. Verifique a conexão SSL com o endpoint do PgBouncer usando o cliente psql:

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

    Substitua:

    • HOST: o endpoint do pool de conexões que você obtém usando o comando kubectl get pgbouncers.alloydbomni.dbadmin.goog -n NAMESPACE. Se o PgBouncer não estiver exposto como um serviço, use o endereço IP dele.
    • PORT: a porta em que o PgBouncer fica à escuta.

    A janela do terminal mostra o texto de login psql que termina com um comando postgres=#.

Conectar de fora de um cluster do Kubernetes

Para acessar o pool de conexões do PgBouncer de fora de um cluster do Kubernetes, defina o campo type no atributo serviceOptions como LoadBalancer, o que cria um serviço loadbalancer.

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

    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 do PgBouncer que você criou está pronto, execute a seguinte consulta:

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

    O resultado será o seguinte:

    NAME          ENDPOINT       STATE
    mypgbouncer   10.138.15.207   Ready
    

Configurar as definições do PgBouncer

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

Parâmetro Descrição Valor padrão
pool_mode Especifica quando uma conexão de banco de dados pode ser reutilizada por outros clientes.
Os valores permitidos são os seguintes:
  • session: a conexão com o banco de dados é liberada de volta para o pool quando o cliente se desconecta.
  • transaction: a conexão com o banco de dados é liberada de volta para o pool após a conclusão da transação.
  • statement: a conexão com o banco de dados é liberada de volta para o pool depois que a consulta termina.
    Transações que abrangem várias instruções não são permitidas nesse modo.
session
ignore_startup_parameters Especifica parâmetros que o PgBouncer não permite para que sejam ignorados durante a inicialização.
default_pool_size O número de conexões de banco de dados permitidas por par usuário-banco de dados. 20
max_client_conn O número máximo de conexões de cliente. 100
max_db_connections O número máximo de conexões de banco de dados. 0

Personalizar a implantação do PgBouncer

O AlloyDB Omni usa recursos personalizados para gerenciar os componentes. Para personalizar a implantação do PgBouncer no AlloyDB Omni no Kubernetes, modifique o recurso personalizado PgBouncer da seguinte maneira:

  1. Liste os recursos personalizados PgBouncer:

    kubectl get pgbouncers -n NAMESPACE

    Substitua NAMESPACE pelo namespace em que você implantou o AlloyDB Omni.

  2. Para modificar o recurso, abra o arquivo de declaração do recurso PgBouncer no editor padrão:

    kubectl edit pgbouncers PGBOUNCER_NAME -n NAMESPACE
  3. No arquivo de declaração, encontre a seçã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 seu contêiner:

      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 tag de imagem do PgBouncer:

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

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

      Substitua:

      • NODE_AFFINITY_TYPE: defina o parâmetro como um dos seguintes:
        • requiredDuringSchedulingIgnoredDuringExecution: o Kubernetes programa o pod exatamente com base nas regras definidas.
        • preferredDuringSchedulingIgnoredDuringExecution: o programador do Kubernetes tenta encontrar um nó que atenda à regra definida para programação. No entanto, se não houver um nó desse tipo, o Kubernetes vai programar para um nó diferente no cluster.
      • LABEL_KEY: o rótulo do nó para a chave que serve como um indicador de local 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 como 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 precisa estar vazia.
        • DoesNotExist: a matriz de valores precisa estar vazia.
        • Gt: a matriz de valores precisa ter um único elemento, que é interpretado como um número inteiro.
        • Lt: a matriz de valores precisa ter um único elemento, que é interpretado como um número inteiro.
  4. Depois de fazer as mudanças, salve o arquivo de declaração. O operador do Kubernetes do AlloyDB Omni aplica automaticamente as mudanças à implantação do PgBouncer.

Excluir o recurso do PgBouncer

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

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

O resultado será o seguinte:

pgbouncer.alloydbomni.dbadmin.goog "mypgbouncer" deleted

Acessar registros do PgBouncer

É possível conferir e analisar os registros de qualquer instância de réplica do PgBouncer na implantação do AlloyDB Omni no Kubernetes da seguinte maneira:

  1. Receba uma lista de todos os pods do PgBouncer no seu namespace:

    kubectl get pods -n NAMESPACE

    O resultado será o 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. Veja os registros de um pod específico:

    kubectl logs -f POD_NAME -n NAMESPACE

    O resultado será o 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
    

Monitorar a performance e a atividade do PgBouncer

É possível conferir as métricas do pool de conexões do PgBouncer usando apenas um statsuser dedicado para acessar o banco de dados de estatísticas internas do PgBouncer. O statsuser é usado para autenticação ao se conectar ao banco de dados do PgBouncer.

  1. Conecte-se ao AlloyDB Omni como um superusuário ou um usuário com o privilégio CREATE ROLE usando o cliente psql:

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

    O resultado será o 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 será o seguinte:

    CREATE ROLE
    postgres=#
    
  3. Conecte-se ao banco de dados do PgBouncer como statsuser:

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

    O resultado será o 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 conferir o desempenho do PgBouncer e identificar possíveis problemas:

    pgbouncer=# SHOW STATS;
    

    O resultado será o 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)
    

Configurar o acesso à rede da instância do AlloyDB Omni

Para garantir a segurança da sua implantação do AlloyDB Omni no Kubernetes, é possível limitar o acesso à rede ao pool de conexões do PgBouncer definindo intervalos de endereços IP específicos usando a notação CIDR (roteamento entre domínios sem classe).

A notação CIDR combina um endereço IP com um tamanho de prefixo. Por exemplo, o bloco CIDR 192.168.1.0/24 especifica 192.168.1.0 para o endereço e 24 para o tamanho de prefixo. O tamanho 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 arquivo de declaração da implantação, localize a seção serviceOptions e adicione ou modifique a configuração loadBalancerSourceRanges:

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

Substitua CIDR_BLOCK por uma string CIDR que especifica os intervalos de endereços IP permitidos para conexões de entrada ao serviço LoadBalancer. A configuração loadBalancerSourceRanges filtra o tráfego de rede recebido e controla quais clientes podem acessar a instância de banco de dados.

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

kubectl get svc -n NAMESPACE -w

Substitua NAMESPACE pelo namespace em que a implantação do AlloyDB Omni está localizada.

O resultado será o 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 será preenchida com o endereço IP externo atribuído ao serviço LoadBalancer. As conexões com esse IP externo são filtradas com base na configuração loadBalancerSourceRanges.

Depois de verificar o IP externo, teste as conexões de aplicativos nos intervalos CIDR permitidos para garantir que eles possam se conectar.

Desativar o pooler de conexões do PgBouncer

Se você precisar desativar ou reverter o pool de conexões do PgBouncer, siga estas etapas:

  1. Verifique o status do pool de conexões:

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

    Esse comando mostra o manifesto de implantação do controlador principal para gerenciar a frota do AlloyDB Omni. Encontre a opção --enable-pgbouncer na seçã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 implantação do controlador para desativar o pool de conexões:

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

    ...
    --enable-pgbouncer=false
    
  4. Salve o arquivo e saia do editor. O kubectl aplica a mudança automaticamente.

A seguir