Iniciar PGAdapter

En esta página se explica cómo iniciar PGAdapter en Spanner. Para obtener información sobre PGAdapter, consulta el artículo Acerca de PGAdapter. Para obtener el archivo binario de PGAdapter, consulta Obtener PGAdapter.

Puedes iniciar PGAdapter de las siguientes formas:

  • Como proceso independiente
  • En un contenedor Docker
  • En Cloud Run
  • Usar PGAdapter como proxy sidecar (por ejemplo, en un clúster de Kubernetes)
  • En el proceso de tu aplicación Java

Antes de empezar

Antes de iniciar PGAdapter, asegúrate de que te has autenticado con una cuenta de usuario o una cuenta de servicio en la máquina en la que se ejecutará PGAdapter. Si utilizas una cuenta de servicio, debes saber la ubicación del archivo de clave JSON (el archivo de credenciales). A continuación, puedes especificar la ruta de las credenciales con la opción -c de PGAdapter o definiendo la variable de entorno GOOGLE_APPLICATION_CREDENTIALS.

Para obtener más información, consulta estos artículos:

Elegir un método para ejecutar PGAdapter

Puedes iniciar PGAdapter como un proceso independiente, en un contenedor Docker, en Cloud Run o en el proceso de tu aplicación Java. Cuando inicias PGAdapter, especificas el proyecto, la instancia de Spanner y la base de datos a los que quieres conectarte. También puedes especificar la ruta de un archivo de credenciales con formato JSON (archivo de clave).

Independiente

Descarga PGAdapter con el siguiente comando.

    wget https://storage.googleapis.com/pgadapter-jar-releases/pgadapter.tar.gz \
    && tar -xzvf pgadapter.tar.gz
    

Inicia PGAdapter con el siguiente comando.

    java -jar pgadapter.jar -p PROJECT_NAME -i INSTANCE_NAME -d DATABASE_NAME \
    -c CREDENTIALS_FILE_PATH \
    ADDITIONAL_OPTIONS
    

Debes seleccionar las siguientes opciones:

-p project_name
Nombre del proyecto en el que se ejecuta la base de datos de Spanner.
-i instance_name
Nombre de la instancia de Spanner.
-d database_name
Nombre de la base de datos a la que se va a conectar.

Las siguientes opciones son opcionales:

-r databaseRole=database_role
Rol de la base de datos que se va a usar en la sesión. Para obtener más información, consulta el artículo Autorización con PGAdapter.
-c credentials_file_path
Ruta completa del archivo de claves que contiene las credenciales de la cuenta de servicio en formato JSON. Si no se define esta opción, las credenciales se leen de la ruta especificada por la variable de entorno GOOGLE_APPLICATION_CREDENTIALS.

Para saber cómo crear una cuenta de servicio y descargar un archivo de clave en formato JSON, consulta Crear una cuenta de servicio.

Asegúrate de conceder a la cuenta de servicio las credenciales suficientes para acceder a la base de datos.

Puedes omitir esta opción si primero te autenticas con la CLI de Google Cloud con el siguiente comando:

gcloud auth application-default login

Para obtener más información, consulta el artículo Configurar la autenticación y la autorización.

-s port
Puerto en el que escucha PGAdapter. El valor predeterminado es 5432 (el puerto de PostgreSQL predeterminado).
-v version_number

Número de versión de PostgreSQL que se expondrá al cliente durante la conexión. El valor predeterminado es 14,1.

Algunas aplicaciones y controladores de PostgreSQL habilitan funciones adicionales en función de este número de versión. Es posible que Spanner no admita estas funciones. Consulta la lista completa de clientes admitidos en Controladores y clientes.

-x

Habilita las conexiones de hosts que no sean localhost. No uses cuando inicies PGAdapter en modo independiente. Úsalo solo cuando se inicie en un contenedor Docker.

De forma predeterminada, como medida de seguridad, PGAdapter solo acepta conexiones de localhost.

En el siguiente ejemplo, se inicia PGAdapter en modo independiente en el puerto 5432 con las credenciales de aplicación predeterminadas.

java -jar pgadapter.jar \
-p my-project \
-i my-instance \
-d my-database \
-s 5432

Docker

Inicia PGAdapter con el siguiente comando.

docker run -d -p HOST-PORT:DOCKER-PORT \
-v CREDENTIALS_FILE_PATH:/acct_credentials.json \
gcr.io/cloud-spanner-pg-adapter/pgadapter:latest \
-p PROJECT_NAME -i INSTANCE_NAME -d DATABASE_NAME  \
-c /acct_credentials.json -x OTHER_PGAdapter_OPTIONS

Además de las opciones de PGAdapter para especificar el proyecto, la instancia, la base de datos y las credenciales, se requieren las siguientes opciones:

-p 127.0.0.1:HOST-PORT:DOCKER-PORT

Esta opción de Docker asigna el puerto DOCKER-PORT dentro del contenedor Docker al puerto HOST-PORT fuera del contenedor. DOCKER-PORT debe coincidir con la forma en que se configura PGAdapter en el contenedor. El valor predeterminado es 5432. HOST-PORT es el puerto en el que Docker debe escuchar fuera del contenedor las solicitudes de conexión. Siempre debe ser un puerto disponible en localhost.

Para obtener más información, consulta Publicar o exponer un puerto (-p, --expose) en la documentación de Docker.

-v CREDENTIALS_FILE_PATH:in_container_mount_point

Esta opción de Docker monta un volumen compartido. Asigna la ruta del host fuera del contenedor a un volumen (punto de montaje) dentro del contenedor. Las rutas del host y del contenedor están separadas por dos puntos (:).

Esta opción permite que PGAdapter acceda al archivo de credenciales JSON que está fuera del contenedor. En el ejemplo anterior, la opción -c hace referencia al punto de montaje del contenedor. En este ejemplo se asigna un nombre al punto de montaje en el contenedor /acct_credentials.json. Puedes ponerle el nombre que quieras.

Para obtener más información, consulta VOLUME (sistemas de archivos compartidos) en la documentación de Docker.

-x

Habilita las conexiones de hosts que no sean localhost. Esto es necesario porque el puerto del contenedor que se asigna al puerto del host no aparece en PGAdapter como localhost.

Las siguientes opciones son opcionales:

-r databaseRole=database_role
Rol de la base de datos que se va a usar en la sesión. Para obtener más información, consulta Autorización con PGAdapter.

En el siguiente ejemplo, tanto el puerto de Docker como el puerto del host se han definido en el puerto predeterminado 5432 del servicio de base de datos PostgreSQL.

docker run -d -p 127.0.0.1:5432:5432 \
-v /tmp/credentials.json:/acct_credentials.json \
gcr.io/cloud-spanner-pg-adapter/pgadapter:latest \
-p my_project -i my_instance -d my_database \
-c /acct_credentials.json -x

Cloud Run

No puedes desplegar PGAdapter como un servicio independiente en Cloud Run, pero sí como un proxy sidecar.

Se recomienda ejecutar PGAdapter con un patrón sidecar en lugar de hacerlo como un servicio independiente por los siguientes motivos:
  • Evita un único punto de fallo. El acceso de cada aplicación a tu base de datos es independiente del de las demás, lo que las hace más resilientes.
  • El número de instancias de PGAdapter se escala automáticamente de forma lineal con el número de instancias de la aplicación.

El repositorio de GitHub de PGAdapter contiene varias aplicaciones de ejemplo que funcionan con Cloud Run y PGAdapter como proxy sidecar para varios lenguajes de programación.

En el siguiente archivo de configuración se muestra cómo añadir PGAdapter como proxy sidecar a Cloud Run:

  apiVersion: serving.knative.dev/v1
  kind: Service
  metadata:
  annotations:
    # This example uses an in-memory volume for Unix domain sockets.
    # This is a Cloud Run beta feature.
    run.googleapis.com/launch-stage: BETA
  name: pgadapter-sidecar-example
  spec:
  template:
    metadata:
      annotations:
        run.googleapis.com/execution-environment: gen1
        # This registers 'pgadapter' as a dependency of 'app' and ensures that pgadapter starts
        # before the app container.
        run.googleapis.com/container-dependencies: '{"app":["pgadapter"]}'
    spec:
      # Create an in-memory volume that can be used for Unix domain sockets.
      volumes:
        - name: sockets-dir
          emptyDir:
            # This directory contains the virtual socket files that are used to
            # communicate between your application and PGAdapter.
            sizeLimit: 50Mi
            medium: Memory
      containers:
        # This is the main application container.
        - name: app
          # Example: europe-north1-docker.pkg.dev/my-test-project/cloud-run-source-deploy/pgadapter-sidecar-example
          image: MY-REGION.pkg.dev/MY-PROJECT/cloud-run-source-deploy/pgadapter-sidecar-example
          # The PGADAPTER_HOST variable is set to point to /sockets, which is the shared in-memory
          # volume that is used for Unix domain sockets.
          env:
            - name: SPANNER_PROJECT
              value: my-project
            - name: SPANNER_INSTANCE
              value: my-instance
            - name: SPANNER_DATABASE
              value: my-database
            - name: PGADAPTER_HOST
              value: /sockets
            - name: PGADAPTER_PORT
              value: "5432"
          ports:
            - containerPort: 8080
          volumeMounts:
            - mountPath: /sockets
              name: sockets-dir
        # This is the PGAdapter sidecar container.
        - name: pgadapter
          image: gcr.io/cloud-spanner-pg-adapter/pgadapter
          volumeMounts:
            - mountPath: /sockets
              name: sockets-dir
          args:
            - -dir /sockets
            - -x
          # Add a startup probe that checks that PGAdapter is listening on port 5432.
          startupProbe:
            initialDelaySeconds: 10
            timeoutSeconds: 10
            periodSeconds: 10
            failureThreshold: 3
            tcpSocket:
              port: 5432
  

Proxy de sidecar

Puedes usar PGAdapter como proxy sidecar en un clúster de Kubernetes, por ejemplo. Los contenedores sidecar de Kubernetes se ejecutan en paralelo con el contenedor principal del pod.

Se recomienda ejecutar PGAdapter con un patrón sidecar en lugar de hacerlo como un servicio independiente por los siguientes motivos:

  • Evita un único punto de fallo. El acceso de cada aplicación a tu base de datos es independiente del de las demás, lo que las hace más resistentes.
  • Como PGAdapter consume recursos en una relación lineal con el uso, este patrón te permite acotar y solicitar recursos de forma más precisa para que se ajusten a tus aplicaciones a medida que se escalan.

En el siguiente archivo de configuración se muestra cómo añadir PGAdapter como proxy sidecar a tu clúster de Kubernetes:

containers:
- name: pgadapter
image: gcr.io/cloud-spanner-pg-adapter/pgadapter
ports:
  - containerPort: 5432
args:
  - "-p my-project"
  - "-i my-instance"
  - "-d my-database"
  - "-x"
resources:
  requests:
    # PGAdapter's memory use scales linearly with the number of active
    # connections. Fewer open connections will use less memory. Adjust
    # this value based on your application's requirements.
    memory: "512Mi"
    # PGAdapter's CPU use scales linearly with the amount of IO between
    # the database and the application. Adjust this value based on your
    # application's requirements.
    cpu: "1"

El repositorio de GitHub de PGAdapter contiene una guía paso a paso y una aplicación de ejemplo. En este ejemplo se incluyen instrucciones para usar Workload Identity Federation for GKE con PGAdapter.

Java In-process

Crea e inicia una instancia de PGAdapter con tu código Java. Esta es la configuración recomendada para las aplicaciones Java.

Si usas una cuenta de servicio para la autenticación, asegúrate de que la variable de entorno GOOGLE_APPLICATION_CREDENTIALS esté definida en la ruta del archivo de credenciales.

  1. Añade google-cloud-spanner-pgadapter como dependencia a tu proyecto. Para obtener más información, consulta el artículo Obtener PGAdapter.
  2. Crea un servidor con la clase com.google.cloud.spanner.pgadapter.ProxyServer.
  3. /**
    * Starts PGAdapter in-process and returns a reference to the server. Use this reference to
    * gracefully shut down the server when your application shuts down.
    *
    * @param project the Google Cloud project that PGAdapter should connect to
    * @param instance the Spanner instance that PGAdapter should connect to
    * @param credentialsFile the full path of a credentials file that PGAdapter should use, or 
    *     null if PGAdapter should use the application default credentials
    */
    static Server startPGAdapter(String project, String instance, String credentialsFile) {
    OptionsMetadata.Builder builder =
        OptionsMetadata.newBuilder()
            .setProject(project)
            .setInstance(instance)
            // Start PGAdapter on any available port.
            .setPort(0);
    if (credentialsFile != null) {
      builder.setCredentialsFile(credentialsFile);
    }
    ProxyServer server = new ProxyServer(builder.build());
    server.startServer();
    server.awaitRunning();
    
    return new PGAdapter(server);
    }

El repositorio de GitHub de PGAdapter contiene una aplicación de ejemplo completa.

Guía de asignación de recursos para el proxy de sidecar de PGAdapter

Las siguientes directrices pueden ayudarte a configurar los recursos de CPU y memoria del proxy sidecar de PGAdapter. Los valores óptimos varían en función de la carga de trabajo específica.

Memoria

Como PGAdapter no almacena en caché muchos datos, necesita memoria para convertir los resultados de las consultas del formato gRPC de Spanner al formato del protocolo de conexión de PostgreSQL. Esto es especialmente importante en el caso de las cargas de trabajo con columnas binarias grandes, ya que Spanner y PostgreSQL gestionan estos tipos de datos de forma diferente.

Para determinar cuánta memoria asignar, usa la siguiente fórmula, donde <var>number of concurrent connections</var> es el número de conexiones simultáneas que gestiona tu aplicación:

384 MB + (2 MB * number of concurrent connections)

Por ejemplo, si tu aplicación gestiona 200 conexiones simultáneas, asigna aproximadamente 784 MB de memoria:

384 MB + (2 MB * 200) = 784 MB

Empieza con esta asignación de memoria de referencia. Monitoriza su uso con una carga realista para ajustar el valor a tus necesidades específicas.

CPU

PGAdapter no requiere un uso intensivo de la CPU. Esto se debe a que su función principal es actuar como proxy de transferencia. Sin embargo, el uso de la CPU aumenta con la cantidad de datos que se envían y reciben.

A la hora de asignar CPU, ten en cuenta los siguientes factores:

  • Carga de trabajo: las aplicaciones que ejecutan consultas que devuelven grandes cantidades de datos requieren más potencia de CPU por conexión que las que devuelven solo unas pocas filas y columnas.
  • Patrón de acceso de la aplicación: si tu aplicación accede a Spanner de forma síncrona, estará inactiva mientras espera los datos del proxy. En este caso, es menos probable que la aplicación y el proxy compitan por los recursos de la CPU.

Empieza con una asignación de CPU de referencia. Monitoriza su uso con una carga realista para ajustar el valor a tus necesidades específicas.

Siguientes pasos