중요합니다
여러 지역에서 99.999% 가용성 서비스 수준 계약, 즉각적인 자동 크기 조정 및 자동 장애 조치(failover)가 있는 대규모 시나리오에 대한 데이터베이스 솔루션을 찾고 있나요? NoSQL용 Azure Cosmos DB를 고려합니다.
OLAP(온라인 분석 처리) 그래프를 구현하거나 기존 Apache Gremlin 애플리케이션을 마이그레이션하시겠습니까? Microsoft Fabric에서 그래프를 고려합니다.
이 문서에서는 요청 실행 시 Azure Cosmos DB for Gremlin 서버가 호출자에게 반환하는 헤더에 대해 설명합니다. 이러한 헤더는 요청 성능 문제를 해결하고, 기본적으로 Azure Cosmos DB 서비스와 통합되는 애플리케이션을 빌드하고, 고객 지원을 간소화하는 데 유용합니다.
이러한 헤더에 대한 종속성을 사용하면 애플리케이션의 이식성을 다른 Gremlin 구현으로 제한할 수 있습니다. 그 대가로 Gremlin용 Azure Cosmos DB와 더욱 긴밀한 통합을 얻고 있습니다. 이러한 헤더는 TinkerPop 표준이 아닙니다.
Headers
| Header | 유형 | 샘플 값 | 포함된 경우 | Explanation |
|---|---|---|---|---|
| x-ms-request-charge | 더블 | 11.3243 | 성공 및 실패 | 부분 응답 메시지에 대한 요청 단위(RU/s 또는 RU) 에서 사용되는 컬렉션 또는 데이터베이스 처리량입니다. 이 헤더는 여러 청크가 있는 요청에 대한 모든 연속 작업에 있습니다. 특정 응답 청크의 요금을 반영합니다. 단일 응답 청크로 구성된 요청에 대해서만 이 헤더는 총 순회 비용과 일치합니다. 그러나 대부분의 복잡한 순회에서 이 값은 부분 비용을 나타냅니다. |
| x-ms-total-request-charge | 더블 | 423.987 | 성공 및 실패 | 전체 요청에 대한 요청 단위(RU/s 또는 RU) 에서 사용되는 컬렉션 또는 데이터베이스 처리량입니다. 이 헤더는 여러 청크가 있는 요청에 대한 모든 연속 작업에 있습니다. 요청이 시작된 이후 누적 요금을 나타냅니다. 마지막 청크에서 이 헤더의 값은 전체 요청 요금을 나타냅니다. |
| x-ms-server-time-ms | 더블 | 13.75 | 성공 및 실패 | 이 헤더는 대기 시간 문제 해결을 위해 포함됩니다. Gremlin용 Azure Cosmos DB 서버가 부분 응답 메시지를 실행하고 생성하는 데 걸린 시간(밀리초)을 나타냅니다. 이 헤더의 값을 사용하여 전체 요청 대기 시간 애플리케이션과 비교하면 네트워크 대기 시간 오버헤드를 계산할 수 있습니다. |
| x-ms-total-server-time-ms | 더블 | 130.512 | 성공 및 실패 | Azure Cosmos DB for Gremlin 서버가 전체 순회를 실행하는 데 걸린 총 시간(밀리초)입니다. 이 헤더는 모든 부분 응답에 포함됩니다. 요청이 시작된 이후의 누적 실행 시간을 나타냅니다. 마지막 응답은 총 실행 시간을 나타냅니다. 이 헤더는 클라이언트와 서버를 대기 시간의 원본으로 구분하는 데 유용합니다. 클라이언트의 순회 실행 시간을 이 헤더의 값과 비교할 수 있습니다. |
| x-ms-status-code | long | 200 | 성공 및 실패 | 헤더는 요청 완료 또는 종료에 대한 내부 이유를 나타냅니다. 애플리케이션은 이 헤더의 값을 확인하고 수정 작업을 수행하는 것이 좋습니다. |
| x-ms-substatus-code | long | 1003 | 실패만 | Azure Cosmos DB는 통합 스토리지 계층을 기반으로 빌드된 다중 모델 데이터베이스입니다. 이 헤더에는 고가용성 스택의 하위 계층 내에서 오류가 발생할 때 발생하는 실패 이유에 대한 추가 인사이트가 포함되어 있습니다. 애플리케이션은 이 헤더를 저장하고 Azure Cosmos DB 고객 지원에 문의할 때 사용하는 것이 좋습니다. 이 헤더의 값은 빠른 문제 해결을 위해 Azure Cosmos DB 엔지니어에게 유용합니다. |
| x-ms-retry-after-ms | string(TimeSpan) | "00:00:03.9500000" | 실패만 | 이 헤더는 .NET TimeSpan 형식의 문자열 표현입니다. 이 값은 프로비전된 처리량 고갈로 인해 실패한 요청에만 포함됩니다. 애플리케이션은 지시된 기간 후에 순회를 다시 제출해야 합니다. |
| x-ms-activity-id | string(Guid) | "A9218E01-3A3A-4716-9636-5BD86B056613" | 성공 및 실패 | 헤더에는 요청의 고유한 서버 쪽 식별자가 포함됩니다. 각 요청에는 추적을 위해 서버에서 고유 식별자가 할당됩니다. 애플리케이션은 고객이 고객 지원에 문의할 수 있는 요청에 대해 서버에서 반환한 활동 식별자를 기록해야 합니다. Azure Cosmos DB 지원 담당자는 Azure Cosmos DB 서비스 원격 분석에서 이러한 식별자에 의해 특정 요청을 찾을 수 있습니다. |
상태 코드
서버에서 상태 특성에 대해 x-ms-status-code 반환되는 가장 일반적인 코드는 다음과 같습니다.
| 상태 | Explanation |
|---|---|
| 401 | 인증 암호가 Azure Cosmos DB 계정 키와 일치하지 않으면 오류 메시지가 "Unauthorized: Invalid credentials provided" 반환됩니다. Azure Portal에서 Azure Cosmos DB for Gremlin 계정으로 이동하여 키가 올바른지 확인합니다. |
| 404 | 동일한 에지 또는 꼭짓점을 동시에 삭제하고 업데이트하려는 동시 작업입니다. 오류 메시지는 "Owner resource does not exist" 지정된 데이터베이스 또는 컬렉션이 연결 매개 변수 형식에서 올바르지 않음을 /dbs/<database name>/colls/<collection or graph name> 나타냅니다. |
| 409 |
"Conflicting request to resource has been attempted. Retry to avoid conflicts." 이는 일반적으로 그래프에 식별자가 있는 꼭짓점 또는 에지가 이미 있는 경우에 발생합니다. |
| 412 | 상태 코드는 오류 메시지 "PreconditionFailedException": One of the specified pre-condition is not met로 보완됩니다. 이 오류는 에지 또는 꼭짓점을 읽고 수정 후 저장소에 다시 쓰는 것 사이의 낙관적 동시성 제어 위반을 나타냅니다. 이 오류가 발생하는 가장 일반적인 상황은 예를 들어 g.V('identifier').property('name','value')속성 수정입니다. Gremlin 엔진은 꼭짓점을 읽고 수정한 다음 다시 작성합니다. 동일한 꼭짓점 또는 에지를 작성하려고 병렬로 실행되는 다른 순회가 있는 경우 그 중 하나가 이 오류를 수신합니다. 애플리케이션은 서버에 통과를 다시 제출해야 합니다. |
| 429 | 요청이 제한되었으며 x-ms-retry-after-ms의 값 이후에 다시 시도해야 합니다. |
| 500 | 포함된 "NotFoundException: Entity with the specified id does not exist in the system." 오류 메시지는 데이터베이스 및/또는 컬렉션이 동일한 이름으로 다시 생성되었음을 나타냅니다. 이 오류는 변경 내용이 전파되고 다른 Azure Cosmos DB 구성 요소의 캐시를 무효화함에 따라 5분 이내에 사라집니다. 이 문제를 방지하려면 매번 고유한 데이터베이스 및 컬렉션 이름을 사용합니다. |
| 1000 | 서버에서 메시지를 성공적으로 구문 분석했지만 실행할 수 없는 경우 이 상태 코드가 반환됩니다. 일반적으로 쿼리에 문제가 있음을 나타냅니다. |
| 1001 | 이 코드는 서버가 순회 실행을 완료하지만 클라이언트에 대한 응답을 다시 직렬화하지 못할 때 반환됩니다. 이 오류는 순회에서 너무 크거나 TinkerPop 프로토콜 사양을 준수하지 않는 복잡한 결과를 생성할 때 발생할 수 있습니다. 애플리케이션은 이 오류가 발생할 때 통과를 간소화해야 합니다. |
| 1003 |
"Query exceeded memory limit. Bytes Consumed: XXX, Max: YYY" 는 통과가 허용된 메모리 제한을 초과할 때 반환됩니다. 메모리 제한은 순회당 2GB 입니다. |
| 1004 | 이 상태 코드는 잘못된 형식의 그래프 요청을 나타냅니다. 역직렬화에 실패하거나, 값이 아닌 형식이 값 형식 또는 지원되지 않는 gremlin 작업 요청으로 역직렬화되는 경우 요청의 형식이 잘못될 수 있습니다. 애플리케이션은 성공하지 못하므로 요청을 다시 시도하면 안 됩니다. |
| 1007 | 일반적으로 이 상태 코드는 오류 메시지 "Could not process request. Underlying connection has been closed."와 함께 반환됩니다. 이 상황은 클라이언트 드라이버가 서버에서 닫히고 있는 연결을 사용하려고 할 때 발생할 수 있습니다. 애플리케이션은 다른 연결에서 순회를 다시 시도해야 합니다. |
| 1008 | Gremlin용 Azure Cosmos DB 서버는 연결을 종료하여 클러스터의 트래픽 균형을 조정할 수 있습니다. 클라이언트 드라이버는 이 상황을 처리하고 라이브 연결만 사용하여 서버에 요청을 보내야 합니다. 경우에 따라 클라이언트 드라이버가 연결이 닫힌 것을 감지하지 못할 수 있습니다. 애플리케이션에 오류가 "Connection is too busy. Please retry after sometime or open more connections." 발생하면 다른 연결에서 순회를 다시 시도해야 합니다. |
| 1009 | 할당된 시간에 작업이 완료되지 않았고 서버에서 취소되었습니다. 순회의 모든 홉에서 꼭짓점 또는 가장자리를 필터링하여 검색 범위를 좁혀 빠르게 실행되도록 순회를 최적화합니다. 요청 시간 제한 기본값은 60초입니다. |
Samples
하나의 상태 특성을 읽는 Gremlin.Net 기반으로 하는 샘플 클라이언트 애플리케이션:
// Following example reads a status code and total request charge from server response attributes.
// Variable "server" is assumed to be assigned to an instance of a GremlinServer that is connected to Azure Cosmos DB account.
using (GremlinClient client = new GremlinClient(server, new GraphSON2Reader(), new GraphSON2Writer(), GremlinClient.GraphSON2MimeType))
{
ResultSet<dynamic> responseResultSet = await GremlinClientExtensions.SubmitAsync<dynamic>(client, requestScript: "g.V().count()");
long statusCode = (long)responseResultSet.StatusAttributes["x-ms-status-code"];
double totalRequestCharge = (double)responseResultSet.StatusAttributes["x-ms-total-request-charge"];
// Status code and request charge are logged into application telemetry.
}
Gremlin Java 클라이언트에서 상태 특성을 읽는 방법을 보여 주는 예제:
try {
ResultSet resultSet = this.client.submit("g.addV().property('id', '13')");
List<Result> results = resultSet.all().get();
// Process and consume results
} catch (ResponseException re) {
// Check for known errors that need to be retried or skipped
if (re.getStatusAttributes().isPresent()) {
Map<String, Object> attributes = re.getStatusAttributes().get();
int statusCode = (int) attributes.getOrDefault("x-ms-status-code", -1);
// Now we can check for specific conditions
if (statusCode == 409) {
// Handle conflicting writes
}
}
// Check if we need to delay retry
if (attributes.containsKey("x-ms-retry-after-ms")) {
// Read the value of the attribute as is
String retryAfterTimeSpan = (String) attributes.get("x-ms-retry-after-ms"));
// Convert the value into actionable duration
LocalTime locaTime = LocalTime.parse(retryAfterTimeSpan);
Duration duration = Duration.between(LocalTime.MIN, locaTime);
// Perform a retry after "duration" interval of time has elapsed
}
}
}