En esta página, se describe el concepto avanzado de sesiones en Spanner, incluidas las prácticas recomendadas para crear una biblioteca cliente, usar las APIs de REST o RPC o las bibliotecas cliente de Google.
Descripción general de las sesiones
Una sesión representa un canal de comunicación con el servicio de base de datos de Spanner. Una sesión se usa para realizar transacciones que leen, escriben o modifican datos en una base de datos de Spanner. Cada sesión se aplica a una única base de datos.
Las sesiones pueden ejecutar una o varias transacciones a la vez. Cuando se realizan varias transacciones, la sesión se denomina sesión multiplexada.
Las operaciones de lectura, escritura y consultas independientes usan una transacción a nivel interno.
Beneficios de rendimiento de un grupo de sesiones
Crear una sesión es costoso. Para evitar el costo de rendimiento cada vez que se realiza una operación de base de datos, los clientes deben mantener un grupo de sesiones, que es un conjunto de sesiones disponibles listas para usarse. El grupo debe almacenar las sesiones existentes y mostrar el tipo de sesión correspondiente cuando se lo solicite, así como controlar la limpieza de las sesiones que no se usan. Para ver un ejemplo de cómo implementar un grupo de sesiones, consulta el código fuente de una de las bibliotecas cliente de Spanner, como la biblioteca cliente de Go o la biblioteca cliente de Java.
Se espera que las sesiones duren mucho tiempo, por lo que, después de usar una sesión para una operación de base de datos, el cliente debe devolver la sesión al grupo para que se vuelva a usar.
Descripción general de los canales de gRPC
El cliente de Spanner usa canales de gRPC para la comunicación. Un canal de gRPC equivale aproximadamente a una conexión TCP. Un canal de gRPC puede controlar hasta 100 solicitudes simultáneas. Esto significa que una aplicación necesitará al menos la misma cantidad de canales de gRPC que la cantidad de solicitudes simultáneas que ejecutará, dividida por 100.
El cliente de Spanner crea un grupo de canales de gRPC cuando lo creas.
Prácticas recomendadas para usar bibliotecas cliente de Google
A continuación, se describen las prácticas recomendadas para usar las bibliotecas cliente de Google para Spanner.
Configura la cantidad de sesiones y canales de gRPC en los grupos
Las bibliotecas cliente tienen una cantidad predeterminada de sesiones en el grupo de sesiones y una cantidad predeterminada de canales de gRPC en el grupo de canales. Ambos valores predeterminados son adecuados para la mayoría de los casos. A continuación, se muestran las sesiones mínimas y máximas predeterminadas, y la cantidad predeterminada de canales gRPC para cada lenguaje de programación.
C++
MinSessions: 100
MaxSessions: 400
NumChannels: 4
C#
MinSessions: 100
MaxSessions: 400
NumChannels: 4
Go
MinSessions: 100
MaxSessions: 400
NumChannels: 4
Java
MinSessions: 100
MaxSessions: 400
NumChannels: 4
Node.js
El cliente de Node.js no admite varios canales de gRPC. Por lo tanto, se recomienda crear varios clientes en lugar de aumentar el tamaño del grupo de sesiones más allá de 100 sesiones para un solo cliente.
MinSessions: 25
MaxSessions: 100
PHP
El cliente de PHP no admite una cantidad configurable de canales de gRPC.
MinSessions: 1
MaxSessions: 500
Python
Python admite cuatro tipos de conjuntos de sesiones diferentes que puedes usar para administrar las sesiones.
Ruby
El cliente de Ruby no admite varios canales de gRPC. Por lo tanto, se recomienda crear varios clientes en lugar de aumentar el tamaño del grupo de sesiones más allá de 100 sesiones para un solo cliente.
MinSessions: 10
MaxSessions: 100
La cantidad de sesiones que usa tu aplicación es igual a la cantidad de transacciones simultáneas que ejecuta. Debes modificar la configuración del grupo de sesiones predeterminado solo si esperas que una sola instancia de la aplicación ejecute más transacciones simultáneas de las que puede manejar el grupo de sesiones predeterminado.
Para aplicaciones de alta simultaneidad, se recomienda lo siguiente:
- Establece
MinSessions
en la cantidad esperada de transacciones simultáneas que ejecutará un cliente único. - Establece
MaxSessions
en la cantidad máxima de transacciones simultáneas que puede ejecutar un cliente único. - Establece
MinSessions=MaxSessions
si la simultaneidad esperada no cambia mucho durante el ciclo de vida de la aplicación. Esto evita que el grupo de sesiones se escale hacia arriba o hacia abajo. El aumento o la reducción del grupo de sesiones también consume algunos recursos. - Establece
NumChannels
enMaxSessions / 100
. Un canal de gRPC puede controlar hasta 100 solicitudes de forma simultánea. Aumenta este valor si observas una latencia de cola alta (latencia p95/p99), ya que esto podría ser un indicador de congestión del canal de gRPC.
Aumentar la cantidad de sesiones activas implica el uso de recursos adicionales en el servicio de la base de datos de Spanner y en la biblioteca cliente. Aumentar la cantidad de sesiones más allá de la necesidad real de la aplicación podría degradar el rendimiento del sistema.
Aumenta el grupo de sesiones en lugar de aumentar la cantidad de clientes
El tamaño del grupo de sesiones de una aplicación determina cuántas transacciones simultáneas puede ejecutar una sola instancia de la aplicación. No se recomienda aumentar el tamaño del grupo de sesiones más allá de la simultaneidad máxima que puede controlar una sola instancia de la aplicación. Si la aplicación recibe una ráfaga de solicitudes que supera la cantidad de sesiones en el grupo, las solicitudes se ponen en cola mientras esperan a que una sesión esté disponible.
Los recursos que consume la biblioteca cliente son los siguientes:
- Cada canal de gRPC usa una conexión TCP.
- Cada invocación de gRPC requiere un subproceso. La cantidad máxima de subprocesos que usa la biblioteca cliente es igual a la cantidad máxima de consultas simultáneas que ejecuta la aplicación. Estos subprocesos se encuentran por sobre cualquier subproceso que la aplicación use para su propia lógica empresarial.
No se recomienda aumentar el tamaño del grupo de sesiones más allá de la cantidad máxima de subprocesos que puede controlar una sola instancia de la aplicación. En su lugar, aumenta la cantidad de instancias de la aplicación.
Administra la fracción de sesiones de escritura
Para algunas bibliotecas cliente, Spanner reserva una parte de las sesiones destinada a las transacciones de lectura y escritura llamada fracción de sesiones de escritura. Si tu app usa todas las sesiones de lectura, Spanner usa las sesiones de lectura y escritura, incluso para las transacciones de solo lectura. Las sesiones de lectura y escritura requieren una spanner.databases.beginOrRollbackReadWriteTransaction
. Si el usuario tiene el rol de IAM spanner.databaseReader
, la llamada fallará y Spanner mostrará el siguiente mensaje de error:
generic::permission_denied: Resource %resource% is missing IAM permission:
spanner.databases.beginOrRollbackReadWriteTransaction
Para las bibliotecas cliente que mantienen una fracción de las sesiones de escritura, puedes establecer la fracción de las sesiones de escritura.
C++
Todas las sesiones de C++ son iguales. No hay sesiones de solo lectura o lectura y escritura.
C#
La fracción de sesiones de escritura predeterminada para C# es 0.2. Puedes cambiar la fracción con el campo WriteSessionsFraction de SessionPoolOptions
.
Go
Todas las sesiones de Go son iguales. No hay sesiones de solo lectura o lectura y escritura.
Java
Todas las sesiones de Java son iguales. No hay sesiones de solo lectura o lectura y escritura.
Node.js
Todas las sesiones de Node.js son iguales. No hay sesiones de solo lectura o lectura y escritura.
PHP
Todas las sesiones de PHP son iguales. No hay sesiones de solo lectura o lectura y escritura.
Python
Python admite cuatro tipos de conjuntos de sesiones diferentes que puedes usar para administrar las sesiones de lectura y de lectura y escritura.
Ruby
La fracción de sesiones de escritura predeterminada para Ruby es 0.3. Puedes cambiar la fracción con el método de inicialización client.
Prácticas recomendadas para crear una biblioteca cliente o usar REST/RPC
A continuación, se describen las prácticas recomendadas para implementar sesiones en una biblioteca cliente de Spanner o con el fin de usar sesiones con las APIs de REST o RPC.
Estas prácticas recomendadas solo se aplican si desarrollas una biblioteca cliente o si usas las APIs de REST/RPC. Si usas una de las bibliotecas cliente de Google para Spanner, consulta Prácticas recomendadas para usar bibliotecas cliente de Google.
Crea y ajusta el tamaño del grupo de sesiones
Para determinar el tamaño óptimo del grupo de sesiones para un proceso de cliente, establece el límite inferior destinado a la cantidad de transacciones simultáneas esperadas y establece el límite superior destinado a la prueba inicial, como 100. Si el límite superior no es adecuado, auméntalo. Aumentar la cantidad de sesiones activas implica el uso de recursos adicionales en el servicio de la base de datos de Spanner, por lo que si no se limpian las sesiones que no se usaron, puede que disminuya el rendimiento. Para los usuarios que trabajan con la API de RPC, recomendamos tener no más de 100 sesiones por canal de gRPC.
Administra sesiones borradas
Existen tres maneras de borrar una sesión:
- Un cliente puede borrar una sesión.
- El servicio de base de datos de Spanner puede borrar una sesión cuando esta está inactiva durante más de 1 hora.
- El servicio de base de datos de Spanner puede borrar una sesión si tiene más de 28 días.
Los intentos de usar una sesión borrada darán como resultado NOT_FOUND
. Si se genera, crea y usa una sesión nueva, agrega la nueva sesión al grupo y quita la sesión borrada de este.
Mantén en funcionamiento una sesión inactiva
El servicio de base de datos de Spanner se reserva el derecho a descartar una sesión que no se usa. Si necesitas sí o sí mantener en funcionamiento una sesión inactiva, por ejemplo, si se espera un aumento significativo en el uso de la base de datos a corto plazo, entonces puedes evitar que se descarte la sesión. Realiza una operación poco costosa, como la ejecución de la consulta de SQL SELECT 1
para mantener en funcionamiento la sesión. Si tienes una sesión inactiva que no es necesaria para un uso a corto plazo, permite que Spanner la descarte y crea una nueva la próxima vez que necesites una.
Un caso para mantener en funcionamiento las sesiones es controlar la demanda máxima normal en la base de datos. Si el uso intensivo de bases de datos ocurre todos los días de 9:00 a.m. a 6:00 p.m., debes mantener algunas sesiones inactivas en funcionamiento durante ese tiempo, ya que es probable que sean necesarias durante el uso máximo. Después de las 6:00 p.m., puedes permitir que Spanner descarte las sesiones inactivas. Antes de las 9:00 a.m. todos los días, crea algunas sesiones nuevas a fin de que estén listas para la demanda esperada.
Otro caso es si tienes una aplicación que usa Spanner, pero debe evitar la sobrecarga de conexión cuando lo hace. Puedes mantener un conjunto de sesiones en funcionamiento para evitar la sobrecarga de conexión.
Oculta detalles de sesión del usuario de la biblioteca cliente
Si estás creando una biblioteca cliente, no expongas las sesiones al consumidor de la biblioteca cliente. Proporciona al cliente la posibilidad de realizar llamadas a la base de datos sin la complejidad de crear y mantener sesiones. Para ver un ejemplo de una biblioteca cliente que oculta los detalles de la sesión del consumidor de la biblioteca cliente, consulta la biblioteca cliente de Spanner para Java.
Soluciona errores para escribir transacciones que no son idempotentes
Las transacciones de escritura sin protección de reproducción pueden aplicar mutaciones más de una vez.
Si una mutación no es idempotente, una mutación que se aplica más de una vez podría provocar un error. Por ejemplo, una inserción puede fallar con ALREADY_EXISTS
, incluso si la fila no existía antes del intento de escritura. Esto podría ocurrir si el servidor de backend confirmó la mutación, pero no pudo comunicar el resultado exitoso al cliente. En ese caso, se podría intentar otra vez la mutación, lo que provocaría el error ALREADY_EXISTS
.
A continuación, se indican algunas formas posibles de solucionar esta situación cuando implementas tu propia biblioteca cliente o usas la API de REST:
- Estructura las escrituras para que sean idempotentes.
- Usa escrituras con protección de reproducción.
- Implementa un método que ejecute la lógica “upsert”: inserta una nueva o actualiza la existente.
- Soluciona el error en nombre del cliente.
Mantén conexiones estables
A fin de obtener el mejor rendimiento, la conexión que usas para alojar una sesión debe permanecer estable. Cuando la conexión que aloja una sesión cambia, Spanner puede anular la transacción activa en la sesión y causar una pequeña carga adicional en tu base de datos mientras actualiza los metadatos de la sesión. No hay problema si algunas conexiones cambian de forma esporádica, pero debes evitar situaciones que podrían cambiar una gran cantidad de conexiones al mismo tiempo. Si usas un proxy entre el cliente y Spanner, debes mantener la estabilidad de conexión para cada sesión.
Supervisa las sesiones activas
Puedes usar el comando ListSessions
para supervisar sesiones activas en tu base de datos desde la línea de comandos, con la API de REST o con la API de RPC.
ListSessions
muestra las sesiones activas de una base de datos determinada. Esto es útil si necesitas buscar la causa de una pérdida de sesión. (Una pérdida de sesión es un incidente en el que se crean sesiones, pero no se devuelven a un grupo de sesiones para volver a usarse).
ListSessions
te permite ver los metadatos de tus sesiones activas, incluso cuándo se creó una sesión y cuándo se usó por última vez. Si analizas estos datos, te guiarán en la dirección correcta para solucionar problemas de sesiones. Si la mayoría de las sesiones activas no tienen un approximate_last_use_time
reciente, esto podría indicar que tu aplicación no está volviendo a usar las sesiones de forma correcta. Consulta la sección sobre la referencia de la API de RPC para obtener más información sobre el campo approximate_last_use_time
.
Consulta la referencia de la API de REST, la referencia de la API de RPC o la referencia de la herramienta de línea de comandos de gcloud para obtener más información sobre el uso de ListSessions
.
Limpieza automática de filtraciones de sesión
Cuando usas todas las sesiones de tu grupo de sesiones, cada transacción nueva espera hasta que se devuelve una sesión al grupo. Cuando se crean sesiones, pero no se devuelven al grupo de sesiones para volver a usarse, se denomina fuga de sesión. Cuando hay una filtración de sesión, las transacciones que esperan una sesión abierta se bloquean de forma indefinida y bloquean la aplicación. Las filtraciones de sesión suelen deberse a transacciones problemáticas que se ejecutan durante un tiempo extremadamente largo y no se confirman.
Puedes configurar tu grupo de sesiones para que resuelva automáticamente estas transacciones inactivas. Cuando habilitas tu biblioteca cliente para que resuelva automáticamente la transición inactiva, identifica las transacciones problemáticas que podrían causar una filtración de sesión, las quita del grupo de sesiones y las reemplaza por una nueva.
El registro también puede ayudar a identificar estas transacciones problemáticas. Si el registro está habilitado, los registros de advertencia se comparten de forma predeterminada cuando se usa más del 95% del grupo de sesiones. Si el uso de tu sesión es superior al 95%, debes aumentar la cantidad máxima de sesiones permitidas en el grupo de sesiones o es posible que tengas una filtración de sesión. Los registros de advertencia contienen seguimientos de pila de transacciones que se ejecutan más tiempo de lo esperado y pueden ayudar a identificar la causa de la alta utilización del grupo de sesiones. Los registros de advertencia se envían según la configuración del exportador de registros.
Habilita la biblioteca cliente para que resuelva automáticamente las transacciones inactivas
Puedes habilitar la biblioteca cliente para que envíe registros de advertencia y resuelva automáticamente las transacciones inactivas, o bien habilitar la biblioteca cliente para que solo reciba registros de advertencia.
Java
Para recibir registros de advertencia y quitar transacciones inactivas, usa setWarnAndCloseIfInactiveTransactions
.
final SessionPoolOptions sessionPoolOptions = SessionPoolOptions.newBuilder().setWarnAndCloseIfInactiveTransactions().build()
final Spanner spanner =
SpannerOptions.newBuilder()
.setSessionPoolOption(sessionPoolOptions)
.build()
.getService();
final DatabaseClient client = spanner.getDatabaseClient(databaseId);
Para recibir solo registros de advertencia, usa setWarnIfInactiveTransactions
.
final SessionPoolOptions sessionPoolOptions = SessionPoolOptions.newBuilder().setWarnIfInactiveTransactions().build()
final Spanner spanner =
SpannerOptions.newBuilder()
.setSessionPoolOption(sessionPoolOptions)
.build()
.getService();
final DatabaseClient client = spanner.getDatabaseClient(databaseId);
Go
Para recibir registros de advertencia y quitar transacciones inactivas, usa SessionPoolConfig
con InactiveTransactionRemovalOptions
.
client, err := spanner.NewClientWithConfig(
ctx, database, spanner.ClientConfig{SessionPoolConfig: spanner.SessionPoolConfig{
InactiveTransactionRemovalOptions: spanner.InactiveTransactionRemovalOptions{
ActionOnInactiveTransaction: spanner.WarnAndClose,
}
}},
)
if err != nil {
return err
}
defer client.Close()
Para recibir solo registros de advertencia, usa customLogger
.
customLogger := log.New(os.Stdout, "spanner-client: ", log.Lshortfile)
// Create a logger instance using the golang log package
cfg := spanner.ClientConfig{
Logger: customLogger,
}
client, err := spanner.NewClientWithConfig(ctx, db, cfg)
Sesiones multiplexadas
Las sesiones multiplexadas te permiten crear una cantidad ilimitada de solicitudes simultáneas a la vez. Las sesiones multiplexadas tienen las siguientes ventajas:
- Reducción de los requisitos de recursos del backend Por ejemplo, evitan las actividades de mantenimiento de la sesión asociadas con el mantenimiento de la propiedad de la sesión y la recolección de elementos no utilizados.
- Sesión de larga duración que no requiere solicitudes de mantenimiento de la sesión cuando está inactiva.
- Las bibliotecas cliente típicas pueden usar una sesión multiplexada para cada cliente. La cantidad de sesiones normales en uso es menor para los clientes que usan sesiones multiplexadas para algunas operaciones en comparación con los clientes que solo usan sesiones normales.
- No es necesario tener afinidad con un solo canal de gRPC. Los clientes pueden enviar solicitudes a través de varios canales para la misma sesión multiplexada.
Las sesiones multiplexadas admiten lo siguiente:
- Las bibliotecas cliente de Java y Go
- Herramientas del ecosistema de Spanner que dependen de las bibliotecas cliente de Java y Go, como PGAdapter, JDBC, Hibernate, el controlador de base de datos/SQL y GORM
- APIs de Spanner para transacciones de solo lectura
Usas las métricas de OpenTelemetry para ver cómo se divide el tráfico entre el grupo de sesiones existente y la sesión multiplexada. OpenTelemetry tiene un filtro de métricas, is_multiplexed
, que muestra sesiones multiplexadas cuando se configura como true
.
Las sesiones multiplexadas están habilitadas de forma predeterminada para el adaptador JDBC y PG. En el caso de las bibliotecas cliente de Java y Go, está inhabilitada de forma predeterminada. Usa la biblioteca cliente de Java o la biblioteca cliente de Go para habilitar las sesiones multiplexadas. Para habilitar una sesión multiplexada con Java o Go, consulta Habilita sesiones multiplexadas.
Habilita sesiones multiplexadas
Para habilitar sesiones multiplexadas con el cliente Java o Go, establece GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS
en true
.
export GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS=TRUE
Consulta el tráfico de las sesiones regulares y multiplexadas
Opentelemetry tiene el filtro is_multiplexed
para mostrar el tráfico de las sesiones multiplexadas. Estableces este filtro en true to view multiplexed sessions
and
false` para ver las sesiones normales.
- Configura OpenTelemetry para Spanner con los procedimientos que se indican en la sección Antes de comenzar de OpenTelemetry de Spanner.
Navega al Explorador de métricas.
En el menú desplegable Métrica, filtra por
generic
.Haz clic en Tarea genérica y navega a Spanner > Spanner/num_acquired_sessions.
En el campo Filtro, selecciona una de las siguientes opciones:
a.
is_multiplexed = false
para ver las sesiones normales. b.is_multiplexed = true
para ver las sesiones multiplexadas.En la siguiente imagen, se muestra la opción Filtrar con las sesiones multiplexadas seleccionadas.
Para obtener más información sobre el uso de OpenTelemetry con Spanner, consulta Cómo aprovechar OpenTelemetry para democratizar la observabilidad de Spanner y Cómo examinar la latencia en un componente de Spanner con OpenTelemetry.