Problembehandlung bei NoHostAvailableException und NoNodeAvailableException

Bei NoHostAvailableException handelt es sich um eine übergeordnete Wrapperausnahme mit zahlreichen möglichen Ursachen und innerer Ausnahmen, von denen viele mit dem Client zusammenhängen können. Diese Ausnahme tritt häufig auf, wenn Probleme mit den Cluster- oder Verbindungseinstellungen bestehen oder wenn ein oder mehrere Cassandra-Knoten nicht verfügbar sind.

In diesem Artikel werden die möglichen Ursachen für diese Ausnahme und spezifische Details zum verwendeten Clienttreiber erläutert.

Treibereinstellungen

Eine der häufigsten Ursachen für NoHostAvailableException sind die Standardtreibereinstellungen. Es wird empfohlen, die am Ende dieses Artikels aufgeführten Einstellungen zu verwenden. Nachfolgend finden Sie einige erläuternde Informationen:

  • Der Standardwert der Verbindungen pro Host ist 1. Dies wird für Azure Cosmos DB nicht empfohlen. Wir empfehlen einen Mindestwert von 10. Obwohl mehr aggregierte Anforderungseinheiten (Request Units, RU) bereitgestellt werden, erhöhen Sie die Anzahl der Verbindungen. Die allgemeine Richtlinie ist 10 Verbindungen pro 200.000 RU.
  • Verwenden Sie die Azure Cosmos DB-Wiederholungsrichtlinie zur Handhabung zeitweiliger Drosselungsantworten. Weitere Informationen finden Sie in den Azure Cosmos DB-Erweiterungsbibliotheken:
  • Verwenden Sie für Konten mit mehreren Regionen die Azure Cosmos DB-Lastenausgleichsrichtlinie in der Erweiterung.
  • Das Timeout für Leseanforderungen sollte auf einen höheren Wert als 1 Minute festgelegt sein. Wir empfehlen 90 Sekunden.

Ausnahmemeldungen

Wenn die Ausnahme nach Durchführung der empfohlenen Änderungen weiterhin besteht, sehen Sie sich die Ausnahmemeldungen in den folgenden drei Abschnitten an. Wenn Ihr Fehlerprotokoll eine dieser Ausnahmemeldungen enthält, folgen Sie der Empfehlung für die jeweilige Ausnahme.

BusyPoolException

Dieser clientseitige Fehler zeigt an, dass die maximale Anzahl von Anforderungsverbindungen für einen Host erreicht wurde. Wenn Sie die Anforderung nicht aus der Warteschlange entfernen können, wird möglicherweise dieser Fehler angezeigt. Wenn die Verbindungen pro Host auf mindestens 10 eingestellt wurden, könnte die Ausnahme durch eine hohe serverseitige Latenz verursacht werden.

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

Empfehlung

Anstatt max requests per connection zu optimieren, vergewissern Sie sich, dass connections per host auf mindestens 10 festgelegt ist. Siehe Abschnitt Codebeispiele.

TooManyRequest(429)

OverloadException wird ausgelöst, wenn die Anforderungsrate zu hoch ist. Dies kann geschehen, wenn für die Tabelle ein unzureichender Durchsatz bereitgestellt und das RU-Budget überschritten wird. Weitere Informationen finden Sie unter hoher Anforderungsrate und serverseitiger Wiederholung.

Empfehlung

Wenden Sie eine der folgenden Optionen an:

  • Wenn die Drosselung anhaltend ist, erhöhen Sie die bereitgestellte RU.
  • Wenn die Drosselung zeitweilig auftritt, verwenden Sie die Azure Cosmos DB-Wiederholungsrichtlinie.
  • Wenn nicht auf die Erweiterungsbibliothek verwiesen werden kann, aktivieren Sie die serverseitige Wiederholung.

Alle Hosts, die für die Abfrage versucht wurden, schlugen fehl

Wenn der Client so eingestellt ist, dass eine Verbindung mit einer anderen Region als der primären Kontaktpunktregion hergestellt wird, erhalten Sie während der ersten Sekunden beim Start eine der folgenden Ausnahmemeldungen:

  • Für Java-Treiber 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)

  • Für Java-Treiber 4: No node was available to execute the query

  • Für C#-Treiber 3: System.ArgumentException: Datacenter West US does not match any of the nodes, available datacenters: West US 2

Empfehlung

Verwenden Sie „CosmosLoadBalancingPolicy“ in Java-Treiber 3 und Java-Treiber 4. Diese Richtlinie führt einen Fallback auf den Kontaktpunkt der primären Schreibregion aus, an dem die angegebenen lokalen Daten nicht verfügbar sind.

Hinweis

Wenn die oben genannten Empfehlungen nicht zur Behebung Ihres Problems beitragen, wenden Sie sich an den Azure Cosmos DB-Support. Stellen Sie die folgenden Details bereit: Ausnahmemeldung, StackTrace der Ausnahme, DataStax-Treiberprotokoll, Universalzeit des Fehlers, konsistente oder zeitweilige Fehler, Keyspace- und Tabellenfehler, Anforderungstyp, bei dem ein Fehler auftrat, und SDK-Version.

Codebeispiel

Einstellungen für Java-Treiber 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();

Einstellungen für Java-Treiber 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();

Einstellungen für C#-v3-Treiber

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

Nächste Schritte