Partilhar via


Solucionar problemas de NoHostAvailableException e NoNodeAvailableException

NoHostAvailableException é uma exceção de wrapper de nível superior com muitas causas possíveis e exceções internas, muitas das quais podem estar relacionadas ao cliente. Essa exceção tende a ocorrer se houver alguns problemas com o cluster ou as configurações de conexão, ou se um ou mais nós Cassandra não estiverem disponíveis.

Este artigo explora possíveis razões para essa exceção e discute detalhes específicos sobre o driver de cliente que está sendo usado.

Configurações do driver

Uma das causas mais comuns de NoHostAvailableException são as configurações de driver padrão. Recomendamos que você use as configurações listadas no final deste artigo. Aqui estão algumas informações explicativas:

  • O valor padrão das conexões por host é 1, o que não recomendamos para o Azure Cosmos DB. Recomendamos um valor mínimo de 10. Embora sejam fornecidas Unidades de Solicitação (RU) mais agregadas, aumente a contagem de conexões. A orientação geral é de 10 conexões por 200.000 RU.
  • Use a política de repetição do Azure Cosmos DB para lidar com respostas de limitação intermitentes. Para obter mais informações, consulte as bibliotecas de extensão do Azure Cosmos DB:
  • Para contas de várias regiões, use a política de balanceamento de carga do Azure Cosmos DB na extensão.
  • O tempo limite da solicitação de leitura deve ser definido em mais de 1 minuto. Recomendamos 90 segundos.

Mensagens de exceção

Se a exceção persistir depois de fazer as alterações recomendadas, revise as mensagens de exceção nas próximas três seções. Se o log de erros contiver alguma dessas mensagens de exceção, siga a recomendação para essa exceção.

BusyPoolException

Esse erro do lado do cliente indica que o número máximo de conexões de solicitação para um host foi atingido. Se não conseguir remover o pedido da fila, poderá ver este erro. Se a conexão por host tiver sido definida como um mínimo de 10, a exceção poderá ser causada por alta latência do lado do servidor.

Java driver v3 exception:
All host(s) tried for query failed (tried: :10350 (com.datastax.driver.core.exceptions.BusyPoolException: [:10350] Pool is busy (no available connection and the queue has reached its max size 256)))
All host(s) tried for query failed (tried: :10350 (com.datastax.driver.core.exceptions.BusyPoolException: [:10350] Pool is busy (no available connection and timed out after 5000 MILLISECONDS)))
C# driver 3:
All hosts tried for query failed (tried :10350: BusyPoolException 'All connections to host :10350 are busy, 2048 requests are in-flight on each 10 connection(s)')

Recomendação

Em vez de ajustar max requests per connection, certifique-se de que connections per host está definido para um mínimo de 10. Consulte a seção de exemplo de código.

MuitosPedido(429)

OverloadException é lançado quando a taxa de solicitação é muito grande, o que pode acontecer quando uma taxa de transferência insuficiente é provisionada para a tabela e o orçamento de RU é excedido. Para obter mais informações, consulte solicitação grande e repetição do lado do servidor.

Recomendação

Aplique uma das seguintes opções:

  • Se a limitação for persistente, aumente a RU provisionada.
  • Se a limitação for intermitente, use a política de repetição do Azure Cosmos DB.
  • Se a biblioteca de extensões não puder ser referenciada, habilite a repetição do lado do servidor.

Todos os hosts tentados para consulta falharam

Quando o cliente estiver configurado para se conectar a uma região diferente da região do ponto de contato principal, durante os segundos iniciais na inicialização, você receberá uma das seguintes mensagens de exceção:

  • Para o driver Java 3: Exception in thread "main" com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (no host was tried)at cassandra.driver.core@3.10.2/com.datastax.driver.core.exceptions.NoHostAvailableException.copy(NoHostAvailableException.java:83)

  • Para o driver Java 4: No node was available to execute the query

  • Para o driver C# 3: System.ArgumentException: Datacenter West US does not match any of the nodes, available datacenters: West US 2

Recomendação

Use CosmosLoadBalancingPolicy no driver Java 3 e no driver Java 4. Essa política retorna ao ponto de contato da região de gravação primária onde os dados locais especificados não estão disponíveis.

Nota

Se as recomendações anteriores não ajudarem a resolver o problema, entre em contato com o suporte do Azure Cosmos DB. Certifique-se de fornecer os seguintes detalhes: mensagem de exceção, stacktrace de exceção, log de driver datastax, tempo universal de falha, falhas consistentes ou intermitentes, espaço de chave e tabela com falha, tipo de solicitação que falhou e versão do SDK.

Exemplo de código

Configurações do driver Java 3

   // socket options with default values
    // https://docs.datastax.com/en/developer/java-driver/3.6/manual/socket_options/
    SocketOptions socketOptions = new SocketOptions()
        .setReadTimeoutMillis(90000); // default 12000

    // connection pooling options (default values are 1s)
    // https://docs.datastax.com/en/developer/java-driver/3.6/manual/pooling/
    PoolingOptions poolingOptions = new PoolingOptions()
        .setCoreConnectionsPerHost(HostDistance.LOCAL, 10) // default 1
        .setMaxConnectionsPerHost(HostDistance.LOCAL, 10) // default 1
        .setCoreConnectionsPerHost(HostDistance.REMOTE, 10) // default 1
        .setMaxConnectionsPerHost(HostDistance.REMOTE, 10); //default 1

    // Azure Cosmos DB load balancing policy
    String Region = "West US";
    CosmosLoadBalancingPolicy cosmosLoadBalancingPolicy = CosmosLoadBalancingPolicy.builder()
        .withWriteDC(Region)
        .withReadDC(Region)
        .build();

    // Azure Cosmos DB retry policy
    CosmosRetryPolicy retryPolicy = CosmosRetryPolicy.builder()
        .withFixedBackOffTimeInMillis(5000)
        .withGrowingBackOffTimeInMillis(1000)
        .withMaxRetryCount(5)
        .build();

    Cluster cluster = Cluster.builder()
        .addContactPoint(EndPoint).withPort(10350)
        .withCredentials(UserName, Password)
        .withSSL(sslOptions)
        .withSocketOptions(socketOptions)
        .withPoolingOptions(poolingOptions)
        .withLoadBalancingPolicy(cosmosLoadBalancingPolicy)
        .withRetryPolicy(retryPolicy)
        .build();

Configurações do driver Java 4

    // driver configurations
    // https://docs.datastax.com/en/developer/java-driver/4.6/manual/core/configuration/
    ProgrammaticDriverConfigLoaderBuilder configBuilder = DriverConfigLoader.programmaticBuilder();

    // connection settings
    // https://docs.datastax.com/en/developer/java-driver/4.6/manual/core/pooling/
    configBuilder
        .withInt(DefaultDriverOption.CONNECTION_POOL_LOCAL_SIZE, 10) // default 1
        .withInt(DefaultDriverOption.CONNECTION_POOL_REMOTE_SIZE, 10) // default 1
        .withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(90)) // default 2
        .withClass(DefaultDriverOption.RECONNECTION_POLICY_CLASS, ConstantReconnectionPolicy.class) // default ExponentialReconnectionPolicy
        .withBoolean(DefaultDriverOption.METADATA_TOKEN_MAP_ENABLED, false); // default true

    // load balancing settings
    // https://docs.datastax.com/en/developer/java-driver/4.6/manual/core/load_balancing/
    String Region = "West US";
    List<String> preferredRegions = new ArrayList<String>();
    preferredRegions.add(Region);
    configBuilder
        .withClass(DefaultDriverOption.LOAD_BALANCING_POLICY_CLASS, CosmosLoadBalancingPolicy.class)
        .withBoolean(CosmosLoadBalancingPolicyOption.MULTI_REGION_WRITES, false)
        .withStringList(CosmosLoadBalancingPolicyOption.PREFERRED_REGIONS, preferredRegions);

    // retry policy
    // https://docs.datastax.com/en/developer/java-driver/4.6/manual/core/retries/
    configBuilder
        .withClass(DefaultDriverOption.RETRY_POLICY_CLASS, CosmosRetryPolicy.class)
        .withInt(CosmosRetryPolicyOption.FIXED_BACKOFF_TIME, 5000)
        .withInt(CosmosRetryPolicyOption.GROWING_BACKOFF_TIME, 1000)
        .withInt(CosmosRetryPolicyOption.MAX_RETRIES, 5);

    CqlSession session = CqlSession.builder()
        .withSslContext(sc)
        .addContactPoint(new InetSocketAddress(EndPoint, Port))
        .withAuthCredentials(UserName, Password)
        .withLocalDatacenter(Region)
        .withConfigLoader(configBuilder.build())
        .build();

Configurações do driver C# v3

    PoolingOptions poolingOptions = PoolingOptions.Create()
        .SetCoreConnectionsPerHost(HostDistance.Local, 10) // default 2
        .SetMaxConnectionsPerHost(HostDistance.Local, 10) // default 8
        .SetCoreConnectionsPerHost(HostDistance.Remote, 10) // default 1
        .SetMaxConnectionsPerHost(HostDistance.Remote, 10); // default 2

    SocketOptions socketOptions = new SocketOptions()
        .SetReadTimeoutMillis(90000); // default 12000

    buildCluster = Cluster.Builder()
        .AddContactPoint(Program.ContactPoint)
        .WithPort(Program.CosmosCassandraPort)
        .WithCredentials(Program.UserName, Program.Password)
        .WithPoolingOptions(poolingOptions)
        .WithSocketOptions(socketOptions)
        .WithReconnectionPolicy(new ConstantReconnectionPolicy(1000)) // default ExponentialReconnectionPolicy
        .WithSSL(sslOptions);

Próximos passos