Solução de problemas de NoHostAvailableException e NoNodeAvailableException
NoHostAvailableException é uma exceção de wrapper de nível superior com muitas causas possíveis e exceções internas, e muitas delas podem estar relacionadas ao cliente. Essa exceção tende a ocorrer quando há problemas com o cluster ou as configurações de conexão ou quando um ou mais nós do Cassandra não estão disponíveis.
Este artigo explora os possíveis motivos para essa exceção e aborda detalhes específicos sobre o driver do cliente que está sendo usado.
Configurações do driver
Uma das causas mais comuns de um 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. Ainda que sejam fornecidas RUs (unidades de solicitação) mais agregadas, aumente a contagem de conexão. A diretriz geral consiste em 10 conexões por 200 mil RU.
- Use a política de repetição do Azure Cosmos DB para manipular respostas intermitentes de limitação. Para mais informações, confira 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 para mais de um minuto. Recomendamos 90 segundos.
Mensagens de exceção
Se a exceção persistir depois de fazer as alterações recomendadas, examine as mensagens de exceção nas próximas três seções. Se o log de erros contiver qualquer uma 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 for possível remover a solicitação da fila, esse erro poderá ser exibido. Se a conexão por host foi definida, no mínimo, como 10, a exceção pode 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 como um mínimo de 10. Confira a seção de exemplo de código.
TooManyRequest(429)
OverloadException é lançado quando a taxa de solicitação é muito grande, o que pode acontecer quando a 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 tentativa 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.
Falha em todos os hosts que tentaram realizar consultas
Quando o cliente estiver definido para se conectar a uma região diferente da região do ponto de contato principal, durante os segundos iniciais na inicialização, você obterá uma das seguintes mensagens de exceção:
Para 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 driver Java 4:
No node was available to execute the query
Para driver C# 3:
System.ArgumentException: Datacenter West US does not match any of the nodes, available datacenters: West US 2
Recomendação
Use o CosmosLoadBalancingPolicy no driver Java 3 e no driver Java 4. Essa política realiza fallback para o ponto de contato da região de gravação principal no qual os dados locais especificados estão não disponíveis.
Observação
Se as recomendações anteriores não ajudarem a resolver seu problema, contate o suporte do Azure Cosmos DB. Certifique-se de fornecer os seguintes detalhes: mensagem de exceção, rastreamento de pilha de exceção, log de driver de datastax, tempo universal de falha, falhas consistentes ou intermitentes, keyspace 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óximas etapas
- Para entender os vários códigos de erro e os significados deles, consulte Diagnósticos do lado do servidor.
- Confira Diagnosticar e solucionar problemas com o SDK do .NET para o Azure Cosmos DB.
- Saiba mais sobre as diretrizes de desempenho para o .NET v3 e o .NET v2.
- Confira Solução de problemas com o SDK do Java v4 do Azure Cosmos DB com contas de API para NoSQL.
- Confira Dicas de desempenho para o SDK do Java v4 do Azure Cosmos DB.