Sessões

Nesta página, descrevemos o conceito avançado de sessões no Spanner, incluindo as práticas recomendadas para sessões ao criar uma biblioteca de cliente, usar as APIs REST ou RPC ou usar as bibliotecas de cliente do Google.

Uma sessão fornece um contexto para operações de banco de dados com o serviço de banco de dados do Spanner. Uma sessão é usada para executar transações que leem, gravam ou modificam dados em um banco de dados do Spanner. Cada sessão aplica-se a um único banco de dados.

As sessões podem executar uma ou várias transações por vez. Ao realizar várias transações, a sessão é chamada de sessão multiplexada. Leituras, gravações e consultas independentes usam uma transação internamente.

Gerenciar o desempenho da sessão

As sessões são o contexto de uma operação de banco de dados. Portanto, a forma como você as gerencia afeta diretamente a latência e o uso de recursos do aplicativo. É possível gerenciar o desempenho da sessão de três maneiras:

Usar um pool de sessões

A criação de uma sessão adiciona latência porque cada nova sessão requer uma ida e volta ao serviço de banco de dados do Spanner. Para reduzir essa latência, use um pool de sessões: uma coleção de sessões disponíveis que estão prontas para uso. Em vez de criar uma sessão para cada operação, o pool retorna uma sessão existente e a recupera para reutilização posterior. Isso distribui a latência de criação de sessões entre muitas operações, em vez de eliminá-la completamente. O pool armazena as sessões atuais, retorna o tipo apropriado de sessão quando solicitado e limpa as sessões não utilizadas.

As sessões são destinadas a serem de longa duração. Portanto, depois que uma sessão é usada para uma operação de banco de dados, o cliente precisa retornar a sessão ao pool para reutilização.

Usar sessões multiplexadas

As sessões multiplexadas permitem fazer várias solicitações simultâneas em uma única sessão, o que reduz a sobrecarga do back-end e o consumo de recursos. Para mais informações, consulte Sessões multiplexadas.

Otimizar a configuração do canal gRPC

Reduza a latência de cauda alta (p95/p99) causada pelo congestionamento do canal gRPC durante o tráfego intenso ajustando o pool de canais gRPC. Nas bibliotecas de cliente compatíveis, o pool de canais dinâmicos redimensiona automaticamente o pool de canais conforme a carga muda. Isso ajuda a reduzir a latência de cauda relacionada ao congestionamento e a evitar o subprovisionamento ou o superprovisionamento de canais.

Visão geral dos canais gRPC

Os canais gRPC são usados pelo cliente do Spanner para comunicação. Um canal gRPC é aproximadamente equivalente a uma conexão TCP. Um canal gRPC pode processar até 100 solicitações simultâneas. Isso significa que um aplicativo precisará de pelo menos tantos canais gRPC quanto o número de solicitações simultâneas que o aplicativo executará, dividido por 100.

O cliente do Spanner cria um pool de canais gRPC quando você o cria.

Práticas recomendadas ao usar bibliotecas de cliente do Google

Veja a seguir as práticas recomendadas ao usar as bibliotecas de cliente do Google para o Spanner.

Configurar o número de sessões e canais gRPC nos pools

A maneira como você gerencia sessões e canais gRPC depende da biblioteca de cliente. As bibliotecas de cliente que dão suporte a sessões multiplexadas, como as bibliotecas de cliente Go e Java, não exigem que você configure um pool de sessões e podem gerenciar o pool de canais gRPC para você por meio do pool de canais dinâmico. As outras bibliotecas de cliente usam um pool de sessões com um número mínimo e máximo padrão de sessões e um número padrão de canais gRPC. Os padrões são adequados para a maioria dos casos. As seções a seguir descrevem os padrões e as opções de configuração para cada linguagem de programação.

C++

MinSessions: 100
MaxSessions: 400
NumChannels: 4

C#

MinSessions: 100
MaxSessions: 400
NumChannels: 4

Go

As sessões multiplexadas são ativadas por padrão e não exigem configuração.

O agrupamento dinâmico de canais é um recurso de ativação. Se você não o ativar, o cliente usará quatro canais gRPC. Para usar um número fixo diferente de canais gRPC, use a opção option.WithGRPCConnectionPool ao criar o cliente:

// Use 16 gRPC channels instead of the default of four.
client, err := spanner.NewClient(ctx,
    "projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
    option.WithGRPCConnectionPool(16),
)

Este exemplo requer o pacote google.golang.org/api/option.

Para ativar o pool de canais dinâmico, defina a opção DCPEnabled como true em DynamicChannelPoolConfig:

client, err := spanner.NewClientWithConfig(ctx,
    "projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
    spanner.ClientConfig{
        DynamicChannelPoolConfig: spanner.DynamicChannelPoolConfig{
            DCPEnabled: true,
        },
    })

Quando você ativa o pool de canais dinâmicos sem definir opções personalizadas, a biblioteca de cliente do Go aplica os seguintes padrões:

  • Tamanho inicial do pool: 4 canais
  • Tamanho mínimo do pool: 2 canais
  • Tamanho máximo do pool: 10 canais
  • Limite de escalonamento vertical: 25 RPCs simultâneas por canal
  • Limite de redução de escala vertical: 15 RPCs simultâneas por canal
  • Intervalo de verificação de redução de escala vertical: 3 minutos

Para personalizar o pool, defina os campos do struct DynamicChannelPoolConfig, como DCPInitialChannels, DCPMinChannels, DCPMaxChannels, DCPMaxRPCPerChannel e DCPMinRPCPerChannel.

Java

As sessões multiplexadas são ativadas por padrão na versão 6.98.0 ou posterior da biblioteca de cliente Java e não exigem configuração. Para mais informações, consulte Sessões multiplexadas.

O pool de canais dinâmico está desativado por padrão para a biblioteca de cliente Java e precisa ser ativado usando SpannerOptions. Se o pool de canais dinâmicos não estiver ativado, a biblioteca de cliente Java usará quatro canais gRPC (oito canais quando a extensão gRPC-GCP estiver ativada). Quando o pool de canais dinâmicos está ativado, a biblioteca de cliente redimensiona o pool de canais gRPC para se adaptar às mudanças nas cargas de trabalho, o que ajuda a evitar problemas de desempenho de canais subprovisionados ou superprovisionados.

Para ativar o pool de canais dinâmicos, inclua enableDynamicChannelPool em SpannerOptions:

SpannerOptions options =
    SpannerOptions.newBuilder()
        .setProjectId("PROJECT_ID")
        .enableDynamicChannelPool()
        .build();

Se você configurar o número de canais usando setNumChannels, o Spanner vai desativar o pool de canais dinâmico e usar um número estático de canais.

Quando você ativa o pool de canais dinâmico sem definir opções personalizadas com setGcpChannelPoolOptions, a biblioteca de cliente para Java aplica os seguintes padrões, que são otimizados para cargas de trabalho típicas:

  • Tamanho inicial do pool: 4 canais
  • Tamanho mínimo do pool: 2 canais
  • Tamanho máximo do pool: 10 canais (limite máximo: 256 canais)
  • Limite de escalonamento vertical: 25 RPCs simultâneas por canal
  • Limite de redução de escala vertical: 15 RPCs simultâneas por canal
  • Intervalo de redução de escala vertical: 3 minutos

Para personalizar o pool de canais dinâmicos, use setGcpChannelPoolOptions. Exemplo:

SpannerOptions options =
    SpannerOptions.newBuilder()
        .setProjectId("PROJECT_ID")
        .enableDynamicChannelPool()
        .setGcpChannelPoolOptions(
            GcpChannelPoolOptions.newBuilder()
                .setMaxSize(15)
                .setMinSize(3)
                .setInitSize(5)
                // setDynamicScaling(minRpcPerChannel, maxRpcPerChannel,
                // scaleDownInterval): scale up as soon as a channel's load
                // exceeds 30 concurrent RPCs. Scale-up is event-driven, so
                // the pool grows immediately as load rises. Scale-down is
                // periodic: a channel is removed only after it stays under
                // 10 concurrent RPCs across the check that runs every 5
                // minutes.
                .setDynamicScaling(10, 30, Duration.ofMinutes(5))
                .build())
        .build();

Considere as seguintes vantagens e desvantagens do pool de canais dinâmico:

  • Sobrecarga de escalonamento: o escalonamento do pool envolve a sobrecarga da criação e destruição de canais gRPC e conexões TCP. Para cargas de trabalho sensíveis à latência com picos acentuados, um pool estático grande pode ser uma opção melhor para evitar a latência de escalonamento.
  • Substituições de configuração: definir o número base de canais desativa o pooling dinâmico de canais. Para mais informações, consulte setNumChannels.
  • Uso de recursos: um pool de canais estático usa uma quantidade fixa de memória e conexões, enquanto o uso de recursos de um pool dinâmico varia de acordo com a carga.

Node.js

Sessões regulares

As sessões multiplexadas são ativadas por padrão na versão 8.3.0 ou mais recente e não exigem configuração. As versões anteriores usam sessões regulares por padrão, com as seguintes configurações:

MinSessions: 25
MaxSessions: 100

Pooling de canais

O pool de canais dinâmicos é ativado por padrão com as seguintes configurações:

MaxChannels: 10
ConcurrentRequestsPerChannel: 25

É possível substituir as configurações de maneira programática ao criar uma instância de cliente do Spanner.

Se você usa sessões multiplexadas (padrão)

Copie a configuração channelPool da configuração do gRPC do Spanner para o aplicativo. Não é necessário copiar definições de método e configurações de afinidade, porque as sessões multiplexadas não exigem vinculação de sessão a canal.

Exemplo:

const {Spanner} = require('@google-cloud/spanner');
    // Note: Ensure grpcGcp is initialized
const customGcpApiConfig = {
  channelPool: {
    maxSize: 20, // Overriding default 10
    maxConcurrentStreamsLowWatermark: 50 // Overriding default 25
  }
};
const spanner = new Spanner({
  'grpc.gcpApiConfig': grpcGcp.createGcpApiConfig(customGcpApiConfig)
});

Se você usa sessões normais

Copie a configuração completa (channelPool e afinidades de método) da configuração do gRPC do Spanner para o aplicativo. Omitir as afinidades de método pode prejudicar o desempenho, porque as solicitações perdem a vinculação de sessão para canal.

PHP

O cliente PHP não é compatível com um número configurável de canais gRPC.

MinSessions: 1
MaxSessions: 500

Python

O Python é compatível com quatro tipos de pool de sessões diferentes que podem ser usados para gerenciar sessões.

Ruby

O cliente Ruby não é compatível com vários canais gRPC. Portanto, é recomendável criar vários clientes em vez de aumentar o tamanho do pool de sessões para mais de 100 sessões para um único cliente.

MinSessions: 10
MaxSessions: 100

Use sessões multiplexadas se a biblioteca de cliente da sua linguagem de programação for compatível com elas. As sessões multiplexadas não exigem nenhuma configuração, e uma única sessão multiplexada pode executar qualquer número de transações simultâneas.

O número de sessões que seu aplicativo usa é igual ao número de transações simultâneas que ele executa. Modifique as configurações padrão do pool de sessões somente se você espera que uma única instância de aplicativo execute mais transações simultâneas do que o pool de sessões padrão pode processar.

Para aplicativos de alta simultaneidade, recomendamos o seguinte:

  1. Defina MinSessions como o número esperado de transações simultâneas que um único cliente vai executar.
  2. Defina MaxSessions como o número máximo de transações simultâneas que um único cliente pode executar.
  3. Defina MinSessions=MaxSessions se a simultaneidade esperada não mudar muito durante o ciclo de vida do aplicativo. Isso impede que o pool de sessões seja escalonado verticalmente ou horizontalmente. O escalonamento vertical ou horizontal do pool de sessões também consome alguns recursos.
  4. Defina NumChannels como MaxSessions / 100. Um canal gRPC pode processar até 100 solicitações simultaneamente. Aumente esse valor se você observar uma latência de cauda alta (latência p95/p99), porque isso pode ser uma indicação de congestionamento do canal gRPC.

Aumentar o número de sessões ativas usa recursos adicionais no serviço de banco de dados do Spanner e na biblioteca de cliente. Aumentar o número de sessões além da necessidade real do aplicativo pode prejudicar o desempenho do sistema.

Aumentar o pool de sessões em vez de aumentar o número de clientes

O tamanho do pool de sessões de um aplicativo determina quantas transações simultâneas uma única instância de aplicativo pode executar. Não é recomendável aumentar o tamanho do pool de sessões além da simultaneidade máxima que uma única instância de aplicativo pode processar. Se o aplicativo receber um aumento repentino de solicitações que ultrapasse o número de sessões no pool, as solicitações serão colocadas em fila enquanto aguardam uma sessão ficar disponível.

Os recursos consumidos pela biblioteca de cliente são os seguintes:

  1. Cada canal gRPC usa uma conexão TCP.
  2. Cada invocação do gRPC requer uma linha de execução. O número máximo de linhas de execução usadas pela biblioteca de cliente é igual ao número máximo de consultas simultâneas que o aplicativo executa. Essas linhas de execução vêm além de todas as linhas de execução que o aplicativo usa para a própria lógica de negócios.

Não é recomendável aumentar o tamanho do pool de sessões além do número máximo de linhas de execução que uma única instância de aplicativo pode processar. Em vez disso, aumente o número de instâncias do aplicativo.

Gerenciar a fração de sessões de gravação

Para algumas bibliotecas de cliente, o Spanner reserva uma parte das sessões para transações de leitura e gravação, chamada de fração de sessões de gravação. Se o app usar todas as sessões de leitura, o Spanner vai usar as sessões de leitura e gravação, mesmo para transações somente leitura. As sessões de leitura e gravação exigem spanner.databases.beginOrRollbackReadWriteTransaction. Se o usuário estiver no papel do IAM spanner.databaseReader, a chamada vai falhar e o Spanner vai retornar esta mensagem de erro:

generic::permission_denied: Resource %resource% is missing IAM permission:
spanner.databases.beginOrRollbackReadWriteTransaction

É possível definir a fração de sessões de gravação para as bibliotecas de cliente que mantêm uma fração de sessões de gravação.

C++

Todas as sessões em C ++ são iguais. Não há sessões somente de leitura ou sessões de leitura e gravação.

C#

A fração padrão de sessões de gravação para C# é 0,2. É possível alterar a fração usando o campo WriteSessionsFraction de SessionPoolOptions.

Go

Todas as sessões do Go são iguais. Não há sessões somente de leitura ou sessões de leitura e gravação.

Java

Todas as sessões do Java são iguais. Não há sessões somente de leitura ou sessões de leitura e gravação.

Node.js

Todas as sessões do Node.js são iguais. Não há sessões somente de leitura ou sessões de leitura e gravação.

PHP

Todas as sessões do PHP são as mesmas. Não há sessões somente de leitura ou sessões de leitura e gravação.

Python

O Python é compatível com quatro tipos diferentes de tipos de pool de sessões, que podem ser usados para gerenciar sessões de leitura e sessões de leitura e gravação.

Ruby

A fração padrão de sessões de gravação para Ruby é 0.3. Para alterar a fração, use o método de inicialização do cliente.

Práticas recomendadas ao criar uma biblioteca de cliente ou usar REST/RPC

Veja a seguir as práticas recomendadas para implementar sessões em uma biblioteca de cliente para o Spanner ou para usar sessões com as APIs REST ou RPC.

Essas práticas recomendadas se aplicam somente se você estiver desenvolvendo uma biblioteca de cliente ou se estiver usando APIs REST/RPC. Se você estiver usando uma das bibliotecas de cliente do Google para o Spanner, consulte Práticas recomendadas ao usar bibliotecas de cliente do Google.

Criar e dimensionar o pool de sessões

Para determinar o tamanho ideal do pool de sessões para um processo de cliente, defina o limite inferior como o número de transações simultâneas esperadas e o limite superior como um número de teste inicial, como 100. Se o limite superior não for adequado, aumente-o. Aumentar o número de sessões ativas usa mais recursos no serviço de banco de dados do Spanner. Portanto, não limpar as sessões não utilizadas pode prejudicar o desempenho. Para usuários que trabalham com a API RPC, recomendamos não ter mais de 100 sessões por canal gRPC.

Lidar com sessões excluídas

Há três maneiras de excluir uma sessão:

  • Um cliente pode excluir uma sessão.
  • O serviço de banco de dados do Spanner pode excluir uma sessão quando ela fica inativa por mais de uma hora.
  • O serviço de banco de dados do Spanner poderá excluir uma sessão se ela tiver mais de 28 dias.

As tentativas de usar uma sessão excluída resultam em NOT_FOUND. Se você encontrar esse erro, crie e use uma nova sessão, adicione-a ao pool e remova a sessão excluída do pool.

Manter uma sessão inativa operante

O serviço de banco de dados do Spanner se reserva o direito de descartar uma sessão não utilizada. É possível impedir que a sessão seja encerrada, se você precisar mesmo manter uma sessão inativa operante, por exemplo, se for esperado um aumento significativo de curto prazo no uso do banco de dados. Realizar uma operação de baixo custo, como executar a consulta SQL SELECT 1 para manter a sessão ativa. Se você tiver uma sessão inativa que não seja necessária para uso em curto prazo, deixe o Spanner descartar a sessão e, em seguida, crie uma nova sessão na próxima vez que uma sessão for necessária.

Um cenário para manter as sessões ativas é lidar com a demanda de pico regular no banco de dados. Se ocorre um uso intenso do banco de dados diariamente das 9h às 18h, mantenha algumas sessões inativas disponíveis durante esse período, uma vez que elas provavelmente serão necessárias para o uso no horário de pico. Depois das 18h, você pode permitir que o Spanner encerre as sessões inativas. Todos os dias, antes das 9h, crie algumas sessões novas para que elas estejam prontas para a demanda esperada.

Outro cenário é se você tiver um aplicativo que usa o Spanner, mas precisa evitar a sobrecarga de conexão ao fazer isso. Mantenha um conjunto de sessões ativas para evitar que a sobrecarga de conexão aconteça.

Ocultar detalhes da sessão do usuário da biblioteca de cliente

Se você estiver criando uma biblioteca de cliente, não exponha as sessões ao consumidor da biblioteca de cliente. Permita que o cliente faça chamadas de banco de dados sem a complexidade de criar e manter sessões. Para ver um exemplo de uma biblioteca de cliente que oculta os detalhes da sessão do consumidor da biblioteca de cliente, consulte a biblioteca de cliente do Spanner para Java.

Lidar com erros de transações de gravação que não sejam idempotentes

As transações de gravação sem proteção de repetição podem aplicar mutações mais de uma vez. Se uma mutação não é idempotente, uma mutação que é aplicada mais de uma vez pode resultar em uma falha. Por exemplo, uma inserção pode apresentar falha com ALREADY_EXISTS mesmo que a linha não exista antes da tentativa de gravação. Isso pode ocorrer se o servidor de back-end confirmou a mutação, mas não conseguiu comunicar o sucesso ao cliente. Nesse caso, a mutação poderia ser tentada novamente, resultando na falha ALREADY_EXISTS.

Estas são as formas possíveis de abordar esse cenário quando você implementa sua própria biblioteca de cliente ou usa a API REST:

  • Estruturar suas gravações para que sejam idempotentes.
  • Usar gravações com proteção contra repetição.
  • Implementar um método que execute a lógica "upsert": inserir se for novo ou atualizar se existir.
  • Lidar com o erro em nome do cliente.

Manter conexões estáveis

Para melhor desempenho, a conexão utilizada para hospedar uma sessão deve permanecer estável. Quando a conexão que hospeda uma sessão muda, o Spanner pode cancelar a transação ativa na sessão e causar uma pequena quantidade de carga extra no banco de dados enquanto atualiza os metadados de sessão. Não há problema se algumas conexões mudarem esporadicamente, mas devem ser evitadas situações em que um grande número de conexões mudam ao mesmo tempo. Se você usar um proxy entre o cliente e o Spanner, mantenha a estabilidade da conexão para cada sessão.

Monitorar sessões ativas

Use o comando ListSessions para monitorar sessões ativas no banco de dados pela linha de comando, com a API REST ou com a API RPC. ListSessions mostra as sessões ativas de um determinado banco de dados. Isso é útil se você precisar encontrar a causa de um vazamento de sessão. Um vazamento de sessão é um incidente em que as sessões são criadas, mas não retornadas a um pool de sessões para reutilização.

Com ListSessions, é possível visualizar metadados sobre suas sessões de atividade ativas, incluindo quando uma sessão foi criada e quando foi usada pela última vez. A análise desses dados vai ajudar você a solucionar problemas de sessões. Se a maioria das sessões ativas não tiver um approximate_last_use_time recente, isso pode indicar que as sessões não estão sendo reutilizadas corretamente pelo aplicativo. Consulte a referência da API RPC para mais informações sobre o campo approximate_last_use_time.

Consulte a referência da API REST, a referência da API RPC ou a referência da ferramenta de linha de comando gcloud para mais informações sobre como usar ListSessions.

Limpeza automática de vazamentos de sessão

Quando você usa todas as sessões no pool, cada nova transação aguarda até que uma sessão seja retornada ao pool. Quando as sessões são criadas, mas não retornam ao pool de sessões para reutilização, isso é chamado de vazamento de sessão. Quando há um vazamento de sessão, as transações que aguardam uma sessão aberta ficam travadas indefinidamente e bloqueiam o aplicativo. Os vazamentos de sessão geralmente são causados por transações problemáticas que estão em execução há muito tempo e não foram confirmadas.

É possível configurar o pool de sessões para resolver automaticamente essas transações inativas. Quando você ativa a biblioteca de cliente para resolver automaticamente a transição inativa, ela identifica transações problemáticas que podem causar um vazamento de sessão, as remove do pool de sessões e as substitui por uma nova sessão.

Os registros também podem ajudar a identificar essas transações problemáticas. Se a geração de registros estiver ativada, os registros de aviso serão compartilhados por padrão quando mais de 95% do pool de sessões estiver em uso. Se o uso da sessão for maior que 95%, será necessário aumentar o número máximo de sessões permitidas no pool de sessões ou talvez haja um vazamento de sessão. Os registros de aviso contêm stack traces de transações que são executadas por mais tempo do que o esperado e podem ajudar a identificar a causa do alto uso do pool de sessões. Os registros de aviso são enviados dependendo da configuração do exportador de registros.

Ativar a biblioteca de cliente para resolver automaticamente transações inativas

É possível ativar a biblioteca de cliente para enviar registros de aviso e resolver automaticamente transações inativas ou ativar a biblioteca de cliente para receber apenas registros de aviso.

Java

Para receber registros de aviso e remover transações inativas, use setWarnAndCloseIfInactiveTransactions.

 final SessionPoolOptions sessionPoolOptions = SessionPoolOptions.newBuilder().setWarnAndCloseIfInactiveTransactions().build()

 final Spanner spanner =
         SpannerOptions.newBuilder()
             .setSessionPoolOption(sessionPoolOptions)
             .build()
             .getService();
 final DatabaseClient client = spanner.getDatabaseClient(databaseId);

Para receber apenas registros de aviso, use 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 receber registros de aviso e remover transações inativas, use SessionPoolConfig com 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 receber apenas registros de aviso, use 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)

Sessões multiplexadas

As sessões multiplexadas permitem criar um grande número de solicitações simultâneas em uma única sessão. Uma sessão multiplexada é um identificador usado em vários canais gRPC. Ele não introduz outros gargalos. As sessões multiplexadas têm as seguintes vantagens:

  • Redução do consumo de recursos de back-end devido a um protocolo de gerenciamento de sessão mais simples. Por exemplo, elas evitam atividades de manutenção de sessão associadas à manutenção de propriedade de sessão e à coleta de lixo.
  • Sessão de longa duração que não exige solicitações de keep-alive quando inativa.

As sessões multiplexadas são compatíveis com:

  • As bibliotecas de cliente em C++, Go, Java, Node.js, PHP, Python, Ruby e Rust.
  • Ferramentas do ecossistema do Spanner que dependem das bibliotecas de cliente mencionadas, como PGAdapter, JDBC, Hibernate, driver de banco de dados/SQL, driver dbAPI e GORM.

  • Ferramentas do ecossistema do Spanner que dependem das bibliotecas de cliente Java e Go, como PGAdapter, JDBC, Hibernate, banco de dados ou driver sql e GORM. Use as métricas do OpenTelemetry para ver como o tráfego é dividido entre o pool de sessões atual e a sessão multiplexada. O OpenTelemetry tem um filtro de métricas, is_multiplexed, que mostra sessões multiplexadas quando definido como true.

As sessões multiplexadas são compatíveis com todos os tipos de transações.

As bibliotecas de cliente alternam as sessões multiplexadas a cada sete dias para evitar o envio de transações em sessões desatualizadas.

As sessões multiplexadas são ativadas por padrão em algumas bibliotecas de cliente. Para outros, é preciso usar variáveis de ambiente para ativá-los. Para mais detalhes, consulte Ativar sessões multiplexadas.

Considerações

Se você estiver tentando confirmar um corpo de transação de leitura ou gravação vazio ou uma transação em que todas as consultas ou instrução DML falharam, há alguns cenários a serem considerados com sessões multiplexadas. As sessões multiplexadas exigem que você inclua um token de pré-commit gerado pelo servidor em cada solicitação de commit. Para transações que contêm consultas ou DML, é necessário que haja pelo menos uma transação de consulta ou DML anterior bem-sucedida para que o servidor envie um token válido de volta para a biblioteca de cliente. Se não houver consultas ou transações de DML bem-sucedidas, a biblioteca de cliente adicionará implicitamente SELECT 1 antes de uma confirmação.

Para uma transação de leitura ou gravação em uma sessão multiplexada que só tem mutações, se uma das mutações for para uma tabela ou uma coluna que NÃO existe no esquema, o cliente poderá retornar um erro INVALID_ARGUMENT em vez de um erro NOT_FOUND.

Ativar sessões multiplexadas

As sessões multiplexadas são ativadas por padrão nas seguintes bibliotecas de cliente:

  • C++ na versão 2.41.0 e mais recentes.
  • Go na versão 1.85.0 e mais recentes.
  • Java na versão 6.98.0 e posteriores.
  • Node.js na versão 8.3.0 e mais recentes.
  • PHP na versão 2.0.0 e posteriores.
  • Python na versão 3.57.0 e posteriores.
  • Ruby na versão 2.30.0 e posteriores.

Para usar sessões multiplexadas em versões anteriores das bibliotecas de cliente do Node.js, Java e Go, primeiro é preciso definir uma variável de ambiente para ativá-las.

Para ativar as sessões multiplexadas, defina a variável de ambiente GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS como TRUE. Essa flag também ativa o suporte a sessões multiplexadas para transações ReadOnly.

export GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS=TRUE

Para ativar o suporte a operações particionadas para sessões multiplexadas, defina a variável de ambiente GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_PARTITIONED_OPS como TRUE.

export GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_PARTITIONED_OPS=TRUE

Para ativar o suporte a transações de leitura e gravação para sessões multiplexadas, defina a variável de ambiente GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_FOR_RW como TRUE.

export GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_FOR_RW=True

É preciso definir GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS como TRUE como pré-requisito para oferecer suporte a uma transação em uma sessão multiplexada.

Ver o tráfego de sessões normais e multiplexadas

O OpenTelemetry inclui o filtro is_multiplexed para mostrar o tráfego de sessões multiplexadas. Defina esse filtro como true para ver sessões multiplexadas ou false para ver sessões regulares.

  1. Configure o OpenTelemetry para o Spanner usando os procedimentos na seção Antes de começar do OpenTelemetry do Spanner.
  2. Acesse o Metrics Explorer.

    Acessar o Metrics Explorer

  3. No menu suspenso Métrica, filtre por generic.

  4. Clique em Tarefa genérica e navegue até Spanner > Spanner/num_acquired_sessions.

  5. No campo Filtro, selecione uma das seguintes opções:

    a. is_multiplexed = false para ver as sessões regulares. b. is_multiplexed = true para ver as sessões multiplexadas.

    A imagem a seguir mostra a opção Filtro com sessões multiplexadas selecionadas.

Para mais informações sobre como usar o OpenTelemetry com o Spanner, consulte Como usar o OpenTelemetry para democratizar a observabilidade do Spanner e Analisar a latência em um componente do Spanner com o OpenTelemetry.

Painel do Opentelemetry mostrando o filtro is-multiplexed.

Resolver problemas

Os erros comuns relacionados à sessão que seu aplicativo pode encontrar incluem:

  • Session not found
  • RESOURCE_EXHAUSTED

Para mais informações, consulte Erros de sessão.