NoHostAvailableException 和 NoNodeAvailableException 疑难解答
NoHostAvailableException 是一个顶级包装器异常,有许多可能的原因和内部异常,其中许多可能与客户端相关。 如果群集或连接设置存在一些问题,或者一个或多个 Cassandra 节点不可用,则往往会发生此异常。
本文探讨了此异常的可能原因,并讨论了有关所使用的客户端驱动程序的具体详细信息。
驱动程序设置
NoHostAvailableException 最常见的一个原因是默认驱动程序设置。 建议使用本文末尾列出的设置。 以下是一些说明性信息:
- 每个主机的连接数的默认值为 1,不建议将其用于 Azure Cosmos DB。 建议的最小值为 10。 尽管提供了更多聚合请求单元 (RU),但请增加连接数。 一般准则是每 200,000 RU 10 个连接。
- 使用 Azure Cosmos DB 重试策略来处理间歇性限制响应。 有关详细信息,请参阅 Azure Cosmos DB 扩展库:
- 对于多区域帐户,请在扩展中使用 Azure Cosmos DB 负载均衡策略。
- 读取请求超时应设置为大于 1 分钟。 建议设置为 90 秒。
异常消息
如果在进行建议的更改后异常仍然存在,请查看接下来的三个部分中的异常消息。 如果错误日志包含这些异常消息中的任意一条,请按照该异常的建议操作。
BusyPoolException
此客户端错误指示已达到主机的最大请求连接数。 如果无法从队列中删除请求,可能会看到此错误。 如果每个主机的连接数已设置为最小值 10,则异常可能是由服务器端延迟较高导致。
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)')
建议
请确保将 max requests per connection
设置为最小值 10,而不是优化 connections per host
。 请参阅代码示例部分。
TooManyRequest(429)
如果请求速率过大,则会引发 OverloadException,当为表预配的吞吐量不足并且超出 RU 预算时,可能会发生此情况。 有关详细信息,请参阅大型请求和服务器端重试。
建议
应用以下选项之一:
- 如果限制是永久性的,请增加预配的 RU。
- 如果限制是间歇性的,请使用 Azure Cosmos DB 重试策略。
- 如果无法引用扩展库,请启用服务器端重试。
尝试查询的所有主机均失败
当客户端设置为连接到主要联系点区域以外的区域时,在启动的最初几秒钟内,你将收到以下异常消息之一:
对于 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)
对于 Java 驱动程序 4:
No node was available to execute the query
对于 C# 驱动程序 3:
System.ArgumentException: Datacenter China North does not match any of the nodes, available datacenters: China North 2
建议
在 Java 驱动程序 3 和 Java 驱动程序 4 中使用 CosmosLoadBalancingPolicy。 此策略回退到指定本地数据不可用的主要写入区域的联系点。
注意
如果上述建议不能帮助解决你的问题,请联系 Azure Cosmos DB 支持。 请务必提供以下详细信息:异常消息、异常堆栈跟踪、datastax 驱动程序日志、通用故障时间、一致或间歇性故障、失败的键空间和表、失败的请求类型和 SDK 版本。
代码示例
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 = "China North";
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();
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 = "China North";
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();
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);
后续步骤
- 若要了解各种错误代码及其含义,请参阅服务器端诊断。
- 请参阅使用 Azure Cosmos DB .NET SDK 诊断和解决问题。
- 了解 .NET v3 和 .NET v2 的性能准则。
- 请参阅排查将 Azure Cosmos DB Java SDK v4 与 API for NoSQL 帐户结合使用时出现的问题。
- 请参阅 Azure Cosmos DB Java SDK v4 性能提示。