Compartir a través de


Solución de problemas de las excepciones NoHostAvailableException y NoNodeAvailableException

NoHostAvailableException es una excepción contenedora de nivel superior con muchas causas posibles y excepciones internas, muchas de las cuales pueden estar relacionadas con el cliente. Esta excepción suele producirse si hay algunos problemas con el clúster o la configuración de conexión, o si uno o varios nodos de Cassandra no están disponibles.

En este artículo, se exploran los posibles motivos de esta excepción y se explican detalles específicos sobre el controlador de cliente que se está utilizando.

Configuración del controlador

Una de las causas más comunes de una excepción NoHostAvailableException es la configuración predeterminada del controlador. Se recomienda que utilice la configuración que aparece al final de este artículo. Esta es una información explicativa:

  • El valor predeterminado de las conexiones por host es 1, lo que no se recomienda para Azure Cosmos DB. Se recomienda un valor mínimo de 10. Aunque se proporcionan más unidades de solicitud (RU) agregadas, aumente el número de conexiones. La directriz general es 10 conexiones por cada 200 000 RU.
  • Use la directiva de reintentos de Azure Cosmos DB para controlar las respuestas con limitación intermitentes. Para más información, consulte las bibliotecas de extensiones de Azure Cosmos DB:
  • Para cuentas de varias regiones, use la directiva de equilibrio de carga de Azure Cosmos DB en la extensión.
  • El tiempo de espera de la solicitud de lectura se debe establecer en un valor superior a 1 minuto. Se recomienda 90 segundos.

Mensajes de excepción

Si la excepción persiste después de realizar los cambios recomendados, revise los mensajes de excepción de las tres secciones siguientes. Si el registro de errores contiene alguno de estos mensajes de excepción, siga la recomendación de esa excepción.

BusyPoolException

Este error del cliente indica que se ha alcanzado el número máximo de conexiones de solicitud para un host. Si no se puede quitar la solicitud de la cola, es posible que aparezca este error. Si la conexión por host se ha establecido en un mínimo de 10, la excepción podría deberse a una latencia elevada del 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)')

Recomendación

En lugar de ajustar max requests per connection, asegúrese de que connections per host esté establecido en un mínimo de 10. Véase la sección de ejemplos de código.

TooManyRequest(429)

La excepción OverloadException se produce cuando la velocidad de las solicitudes es demasiado grande, lo que puede ocurrir cuando se aprovisiona un rendimiento insuficiente para la tabla y se supera el presupuesto de RU. Para más información, consulte La tasa de solicitudes es grande y Prevención de errores de limitación de velocidad de operaciones de Azure Cosmos DB API para Cassandra.

Recomendación

Aplique una de las siguientes opciones:

  • Si la limitación es persistente, aumente las RU aprovisionadas.
  • Si la limitación es intermitente, use la directiva de reintentos de Azure Cosmos DB.
  • Si no se puede hacer referencia a la biblioteca de extensiones, habilite el reintento del lado del servidor.

Error en todos los hosts probados para la consulta

Cuando el cliente está configurado para conectarse a una región que no sea la región del punto de contacto principal, durante los primeros segundos del inicio, verá uno de los siguientes mensajes de excepción:

  • Para el controlador de 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 el controlador de Java 4: No node was available to execute the query

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

Recomendación

Utilice CosmosLoadBalancingPolicy en el controlador de Java 3 y el controlador de Java 4. Esta directiva vuelve al punto de contacto de la región de escritura principal donde los datos locales especificados no están disponibles.

Nota:

Si las recomendaciones anteriores no ayudan a resolver el problema, póngase en contacto con el equipo de soporte técnico de Azure Cosmos DB. Asegúrese de proporcionar los siguientes detalles: mensaje de excepción, seguimiento de la pila de excepciones, registro del controlador de datastax, hora universal de error, errores constantes o intermitentes, espacios de claves y tabla con errores, tipo de solicitud que no se pudo realizar y versión del SDK.

Ejemplo de código

Configuración del controlador de 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();

Configuración del controlador de 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();

Configuración del controlador de 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);

Pasos siguientes