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
- Para comprender los distintos códigos de error y su significado, consulte Diagnósticos de servidor para Cassandra API de Azure Cosmos DB.
- Consulte Diagnóstico y solución de problemas al usar el SDK de .NET de Azure Cosmos DB.
- Más información sobre las directrices de rendimiento de .NET v3 y .NET v2.
- Consulte Solución de problemas con el SDK de Azure Cosmos DB para Java v4 con cuentas de la API para NoSQL.
- Consulte Sugerencias de rendimiento para la versión 4 del SDK de Java de Azure Cosmos DB.