Cosmos DB Continuation Token은 어떻게 작동하나요?
처음에는 Cosmos DB에서 연속 토큰이 수행하는 작업이 분명합니다. 다음 쿼리에 연결하면 다음 결과 집합이 제공됩니다. 그러나 "다음 결과 집합"은 정확히 무엇을 의미합니까?
의미 :
- 첫 번째 쿼리 (적절한 수의 문서 건너 뛰기)시 페이징없이 원래 쿼리가 완전히 실행 된 것처럼 다음 결과 집합?
- 원래 쿼리가 지금 실행 된 것처럼 다음 결과 집합 (적절한 수의 문서 건너 뛰기)?
- 완전히 다른 것?
답변 1은 바람직해 보이지만 서버가 무제한의 상태를 저장해야한다는 점을 감안할 때 가능성이 낮습니다. 그러나 답변 2는 또한 불일치를 초래할 수 있기 때문에 문제가됩니다. 예를 들어 페이지 쿼리간에 기본 데이터가 변경된 경우 동일한 문서가 여러 페이지에 걸쳐 제공 될 수 있습니다.
답변
Cosmos DB 쿼리 실행은 서버 측에서 상태 비 저장입니다. 연속 토큰은 인덱스 상태를 다시 만들고 실행 진행률을 추적하는 데 사용됩니다.
"다음 결과 집합"은 이전 실행의 "책갈피"에서 쿼리가 다시 실행됨을 의미합니다. 이 책갈피는 연속 토큰에 의해 제공됩니다.
- 연속 중에 생성 된 문서
삽입 위치 및 실행중인 쿼리에 따라 반환되거나 반환되지 않을 수 있습니다.
예:
SELECT * FROM c ORDER BY c.someValue ASC
북마크에 someValue = 10이 있다고 가정하면 쿼리 엔진은 someValue = 10 인 연속 토큰을 사용하여 처리를 다시 시작합니다.
쿼리 실행 사이에 someValue = 5 인 새 문서를 삽입 하면 다음 결과 집합에 표시되지 않습니다 .
새 문서가있는 "페이지"에 삽입되어있는 경우> 북마크, 그것은 표시됩니다 결과의 다음 세트에
- 계속되는 동안 업데이트 된 문서
위와 동일한 논리가 업데이트에도 적용됩니다 (# 4 참조).
- 계속하는 동안 삭제 된 문서
그들은 표시되지 않습니다 결과의 다음 세트에.
- 중복 가능성
아래 쿼리의 경우
SELECT * FROM c ORDER BY c.remainingInventory ASC
남은 인벤토리가 첫 번째 결과 집합 이후에 업데이트되었고 이제 두 번째 페이지에 대한 ORDER BY 기준을 충족하면 문서 가 다시 표시 됩니다.
Cosmos DB는 쿼리 페이지간에 스냅 숏 격리를 제공하지 않습니다. 그러나 제품 팀에 따르면 이것은 연속에 대한 쿼리가 매우 빠르고 대부분의 경우 모든 쿼리 결과가 첫 페이지에 반환되기 때문에 매우 드문 시나리오입니다.
예비 실험에 따르면 답은 옵션 # 2 또는 더 정확하게는 다음과 같습니다.
- 첫 페이지를 게재 한 후 생성 된 문서는 후속 페이지에서 볼 수 있습니다.
- 첫 페이지를 게재 한 후 업데이트 된 문서는 후속 페이지에서 볼 수 있습니다.
- 첫 페이지 게재 후 삭제 된 문서는 다음 페이지에서 생략됩니다.
- 문서는 두 번 제공되지 않습니다.
위의 첫 번째 진술은 MSFT의 정보와 모순됩니다 ( 참조 : Kalyan의 답변). 페이지 검색의 의미를 정확하게 지정하는 Cosmos DB 팀으로부터보다 자격있는 답변을 얻는 것이 좋을 것입니다. 이것은 UI에 데이터를 표시하는 데 그다지 중요하지 않을 수 있지만 쿼리를 수행 할 때 페이징 을 비활성화 하는 방법이없는 것처럼 보이기 때문에 백엔드에서 데이터 처리에 필수적 일 수 있습니다 ( 참조 . 코스모스 DB? ).
실험 방법
이 도구를 사용하면 페이지 크기 및 기타 요청 옵션을 조작 할 수 있기 때문에 Sacha Bruttin의 Cosmos DB Explorer 를 사용하여 5 개의 문서가있는 컬렉션을 쿼리했습니다.
페이지 크기는 1로 설정되었고 교차 파티션 쿼리가 활성화되었습니다. 다른 쿼리 (예 : SELECT * FROM c
또는) 가 시도되었습니다 SELECT * FROM c ORDER BY c.name
.
페이지 1을 검색 한 후 새 문서가 삽입되고 일부 기존 문서 (다음 페이지에 표시되어야하는 문서 포함)가 업데이트 및 삭제되었습니다. 그런 다음 모든 후속 페이지가 순서대로 검색되었습니다.
(도구의 소스 코드를 간략히 살펴보면 ResponseContinuationTokenLimitInKb
설정되지 않은 것으로 확인되었습니다 .)