Partager via


Résolution des exceptions NoHostAvailableException et NoNodeAvailableException

NoHostAvailableException est une exception de wrapper de niveau supérieur associée à de nombreuses causes et exceptions internes possibles, dont la plupart sont liées au client. Elle se produit généralement en cas de problèmes de cluster ou de paramètres de connexion, ainsi qu’en cas d’indisponibilité d’un ou plusieurs nœuds Cassandra.

Cet article explore les raisons possibles de cette exception et aborde des aspects spécifiques du pilote client utilisé.

Paramètres de pilote

L’une des causes les plus courantes d’une exception NoHostAvailableException réside dans les paramètres de pilote par défaut. Nous vous recommandons d’utiliser les paramètres indiqués à la fin de cet article. Voici quelques éléments d’explication :

  • La valeur par défaut des connexions par hôte est 1, ce qui n’est pas recommandé pour Azure Cosmos DB. Nous vous conseillons une valeur minimale de 10. Bien qu’il soit fourni davantage d’unités de requête (RU, Request Unit) agrégées, augmentez le nombre de connexions. Les recommandations générales sont de 10 connexions pour 200 000 RU.
  • Utilisez la stratégie de nouvelles tentatives d’Azure Cosmos DB pour gérer les réponses de limitation intermittentes. Pour plus d’informations, consultez les bibliothèques d’extensions d’Azure Cosmos DB :
  • Pour les comptes multirégions, utilisez la stratégie d’équilibrage de charge d’Azure Cosmos DB dans l’extension.
  • Le délai des demandes de lecture doit être supérieur à 1 minute. Nous recommandons 90 secondes.

Messages d’exception

Si l’exception persiste une fois les modifications recommandées effectuées, examinez les messages d’exception des trois sections suivantes. Si votre journal des erreurs contient l’un de ces messages d’exception, suivez la recommandation associée.

BusyPoolException

Cette erreur côté client indique que le nombre maximal de connexions de requête pour un hôte a été atteint. Si vous ne parvenez pas à supprimer une demande de la file d’attente, il se peut que cette erreur s’affiche. Si la connexion par hôte a été définie sur 10 au minimum, l’exception peut être due à une latence élevée côté serveur.

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

Recommandation

Au lieu d’ajuster max requests per connection, faites en sorte que la valeur connections per host soit définie sur 10 au minimum. Consultez la section d’exemple de code.

TooManyRequest(429)

L’exception OverloadException est lancée lorsque le taux de demande est trop élevé, ce qui peut se produire lorsque le débit alloué pour la table est insuffisant et que le budget d’unités RU est dépassé. Pour plus d’informations, consultez Demandes importantes et Nouvelle tentative côté serveur.

Recommandation

Appliquez l’une des options suivantes :

  • Si la limitation est permanente, augmentez les unités RU approvisionnées.
  • Si la limitation est intermittente, utilisez la stratégie de nouvelles tentatives d’Azure Cosmos DB.
  • Si vous ne pouvez pas faire référence à la bibliothèque d’extensions, activez la nouvelle tentative côté serveur.

Tous les hôtes joints pour la requête ont échoué

Lorsque le client est prêt à se connecter à une région autre que celle du point de contact principal, l’un des messages d’exception suivants s’affiche les premières secondes au démarrage :

  • Pour le pilote 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)

  • Pour le pilote Java 4 : No node was available to execute the query

  • Pour le pilote C# 3 : System.ArgumentException: Datacenter West US does not match any of the nodes, available datacenters: West US 2

Recommandation

Utilisez CosmosLoadBalancingPolicy dans le pilote Java 3 et le pilote Java 4. Cette stratégie se rabat sur le point de contact de la région d’écriture principale lorsque les données locales spécifiées ne sont pas disponibles.

Notes

Si les recommandations précédentes ne vous aident pas à résoudre votre problème, contactez le support Azure Cosmos DB. N’oubliez pas de fournir les informations suivantes : message d’exception, rapport des appels de procédure, journal du pilote DataStax, heure universelle de l’échec, caractère permanent ou intermittent de l’échec, keyspace et table concernés par l’échec, type de la demande ayant abouti à un échec et version du kit SDK.

Exemple de code

Paramètres du pilote 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();

Paramètres du pilote 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();

Paramètres du pilote 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);

Étapes suivantes