NoHostAvailableException 및 NoNodeAvailableException 문제 해결
NoHostAvailableException은 가능한 원인 및 내부 예외를 많이 포함하는 최상위 래퍼 예외이며, 대부분은 클라이언트와 관련이 있을 수 있습니다. 이 예외는 클러스터 또는 연결 설정에 문제가 있거나 하나 이상의 Cassandra 노드를 사용할 수 없는 경우에 발생합니다.
이 문서에서는 이 예외가 발생할 수 있는 원인을 살펴보고 사용 중인 클라이언트 드라이버에 대한 특정 세부 정보를 설명합니다.
드라이버 설정
NoHostAvailableException의 가장 일반적인 원인 중 하나는 기본 드라이버 설정입니다. 이 문서의 끝에 나온 설정을 사용하는 것이 좋습니다. 다음은 몇 가지 유용한 정보입니다.
- 호스트당 연결의 기본값은 1이며, Azure Cosmos DB에 대해 권장되지 않습니다. 최솟값은 10이 권장됩니다. 더 많은 집계 RU(요청 단위)가 제공되어도 연결 개수를 늘리면 됩니다. 일반 지침은 200,000RU당 10개의 연결입니다.
- 일시적인 제한 응답을 처리하려면 Azure Cosmos DB 재시도 정책을 사용합니다. 자세한 내용은 Azure Cosmos DB 확장 라이브러리를 참조하세요.
- 다중 지역 계정의 경우 확장의 Azure Cosmos DB 부하 분산 정책을 사용하세요.
- 읽기 요청 시간 제한은 1분보다 크게 설정해야 합니다. 90초가 적당합니다.
예외 메시지
권장된 변경을 수행한 후에도 예외가 지속되는 경우 다음 3개 섹션에서 예외 메시지를 검토하세요. 오류 로그에 이러한 예외 메시지가 포함된 경우 해당 예외에 대한 권장 사항을 따릅니다.
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
을 조정하는 대신 connections per host
가 최소 10으로 설정되어 있는지 확인하세요. 코드 샘플 섹션을 참조하세요.
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 West US does not match any of the nodes, available datacenters: West US 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 = "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();
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();
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의 성능 지침에 대해 알아봅니다.
- API for NoSQL 계정을 사용하는 Azure Cosmos DB Java SDK v4 문제 해결을 참조하세요.
- Azure Cosmos DB Java SDK v4에 대한 성능 팁을 참조합니다.