Condividi tramite


Risolvere i problemi relativi a NoHostAvailableException e NoNodeAvailableException

NoHostAvailableException è un'eccezione wrapper di primo livello con molte possibili cause ed eccezioni interne, molte delle quali possono essere correlate al client. Questa eccezione tende a verificarsi se ci sono problemi con le impostazioni di connessione o cluster o se uno o più nodi Cassandra non sono disponibili.

Questo articolo illustra i possibili motivi per questa eccezione e fornisce dettagli specifici sul driver client in uso.

Impostazioni driver

Una delle cause più comuni di NoHostAvailableException sono le impostazioni predefinite del driver. È consigliabile usare le impostazioni elencate alla fine di questo articolo. Ecco alcune informazioni esplicative:

  • Il valore predefinito delle connessioni per host è 1, che non è consigliabile per Azure Cosmos DB. È consigliabile un valore minimo pari a 10. Anche se vengono fornite più unità richiesta (UR) aggregate, aumentare il numero di connessioni. Le linee guida generali sono 10 connessioni per 200.000 UR.
  • Usare i criteri di retry di Azure Cosmos DB per gestire risposte di limitazione intermittenti. Per altre informazioni, vedere le librerie delle estensioni di Azure Cosmos DB:
  • Per gli account in più aree, usare i criteri di bilanciamento del carico di Azure Cosmos DB nell'estensione.
  • Il timeout della richiesta di lettura deve essere impostato su un valore maggiore di 1 minuto. Il valore consigliato è 90 secondi.

Messaggi di eccezione

Se l'eccezione persiste dopo aver apportato le modifiche consigliate, esaminare i messaggi di eccezione nelle tre sezioni successive. Se il log degli errori contiene uno di questi messaggi di eccezione, seguire la raccomandazione per tale eccezione.

BusyPoolException

Questo errore sul lato client indica che è stato raggiunto il numero massimo di connessioni di richiesta per un host. Se non è possibile rimuovere la richiesta dalla coda, si potrebbe riscontrare questo errore. Se la connessione per host è stata impostata su un valore minimo di 10, l'eccezione potrebbe essere causata da una latenza lato server elevata.

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)')

Elemento consigliato

Invece di ottimizzare max requests per connection, assicurarsi che connections per host sia impostato su un valore minimo di 10. Vedere la sezione degli esempi di codice.

TooManyRequest(429)

OverloadException viene generato quando la frequenza delle richieste è troppo elevata, cosa che può verificarsi quando viene effettuato un provisioning della velocità effettiva insufficiente per la tabella e viene superato il budget delle UR. Per altre informazioni, vedere richieste di grandi dimensioni e retry lato server.

Elemento consigliato

Scegliere una delle opzioni seguenti:

  • Se la limitazione è persistente, aumentare le UR di cui è stato effettuato il provisioning.
  • Se la limitazione è intermittente, usare i criteri di retry di Azure Cosmos DB.
  • Se non è possibile fare riferimento alla libreria di estensioni, abilitare il retryl lato server.

Tutti gli host tentati per la query hanno avuto esito negativo

Quando il client è impostato per connettersi a un'area diversa da quella del punto di contatto principale, durante i pochi secondi iniziali all'avvio si riceverà uno dei messaggi di eccezione seguenti:

  • Per il 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)

  • Per il driver Java 4: No node was available to execute the query

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

Elemento consigliato

Usare CosmosLoadBalancingPolicy in driver Java 3 e driver Java 4. Questo criterio esegue il fallback al punto di contatto dell'area di scrittura primaria in cui i dati locali specificati non sono disponibili.

Nota

Se le raccomandazioni precedenti non consentono di risolvere il problema, contattare il supporto tecnico di Azure Cosmos DB. Assicurarsi di fornire i dettagli seguenti: messaggio di eccezione, stacktrace di eccezione, log del driver datastax, ora universale dell'errore, errori coerenti o intermittenti, keyspace e tabella non riusciti, tipo di richiesta non riuscito e versione dell'SDK.

Esempio di codice

Impostazioni del 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();

Impostazioni del 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();

Impostazioni 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);

Passaggi successivi