Неожиданный токен продолжения CosmosDb

Обратите внимание:

  • Я полагаю, что этот вопрос отличается от того, который здесь говорит о том, почему токен продолжения равен нулю . Перечисленная здесь проблема связана с обсуждением этого неожиданного поведения и поиском решения.
  • Я также сообщил об этом в проблемах github с cosmosdb, потому что На этом этапе я думаю, что это вполне может быть ошибкой SDK или Cosmos API.

Вот оно:

Обычно я не получаю результата с токеном продолжения в неожиданной ситуации.

Единственный подобный опыт (без результата, но с токеном продолжения), который у меня был с CosmosDb, - это когда RU недостаточно, а запросу требуется больше RU для завершения своей работы. Например, при подсчете всех документов вам нужно продолжить несколько раз.

Как воспроизвести проблему?

Это очень сложно воспроизвести, поскольку потребитель не контролирует распределение сегментов (физических разделов). Но вам нужна comosdb с несколькими логическими разделами и как минимум двумя осколками, и ваш запрос должен быть сформирован с учетом данных во втором общем доступе. Не указывайте ключ раздела и сделайте запрос перекрестным.

Ожидаемое поведение

Когда:

  • запрос является перекрестным
  • хватит RU
  • запрос стоит очень маленький RU

Ожидаю результат уже при первом звонке.

Фактическое поведение

Результат запроса пуст. В ответе есть необычный токен продолжения. Токен выглядит следующим образом:

{"token": null, "range": {"min": "05C1DFFFFFFFFC", "max": "FF"}}

Ниже приведен пример кода, в котором я могу воспроизводить проблему каждый раз. В этом случае у меня есть документ, расположенный в разделе 2 (индекс 1), который, как я полагаю, является вторым осколком.

var client = new DocumentClient(ServiceEndpoint, AuthKey);
const string query = "select * from c where c.title='JACK CALLAGHAN'";
var collection = UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId);
var cQuery = client.CreateDocumentQuery<dynamic>(collection, query, new FeedOptions
{
    EnableCrossPartitionQuery = true,
    PopulateQueryMetrics = true
}).AsDocumentQuery();

var response = cQuery.ExecuteNextAsync().GetAwaiter().GetResult();

Console.WriteLine($"response.AsEnumerable().Count()= {response.AsEnumerable().Count()}");

foreach (string headerKey in response.ResponseHeaders.Keys)
{
    Console.WriteLine($"{headerKey}");
    var keyValues = response.ResponseHeaders[headerKey].Split(";");
    foreach (var keyValue in keyValues)
    {
        Console.WriteLine($"{keyValue}");
    }
    Console.WriteLine();
}

И вывод, включая все заголовки:

response.AsEnumerable().Count()= 0
Cache-Control
no-store, no-cache

Pragma
no-cache

Transfer-Encoding
chunked

Server
Microsoft-HTTPAPI/2.0

Strict-Transport-Security
max-age=31536000

x-ms-last-state-change-utc
Wed, 03 Apr 2019 00:50:35.469 GMT

x-ms-resource-quota
documentSize=51200
documentsSize=52428800
documentsCount=-1
collectionSize=52428800

x-ms-resource-usage
documentSize=184
documentsSize=164076
documentsCount=94186
collectionSize=188910

lsn
118852

x-ms-item-count
0

x-ms-schemaversion
1.7

x-ms-alt-content-path
dbs/bettingedge/colls/fixtures

x-ms-content-path
S8sXAPPiCdc=

x-ms-xp-role
1

x-ms-documentdb-query-metrics
totalExecutionTimeInMs=0.27
queryCompileTimeInMs=0.04
queryLogicalPlanBuildTimeInMs=0.02
queryPhysicalPlanBuildTimeInMs=0.03
queryOptimizationTimeInMs=0.00
VMExecutionTimeInMs=0.06
indexLookupTimeInMs=0.05
documentLoadTimeInMs=0.00
systemFunctionExecuteTimeInMs=0.00
userFunctionExecuteTimeInMs=0.00
retrievedDocumentCount=0
retrievedDocumentSize=0
outputDocumentCount=0
outputDocumentSize=49
writeOutputTimeInMs=0.00
indexUtilizationRatio=0.00

x-ms-global-Committed-lsn
118851

x-ms-number-of-read-regions
0

x-ms-transport-request-id
12

x-ms-cosmos-llsn
118852

x-ms-session-token
0:-1#118852

x-ms-request-charge
2.86

x-ms-serviceversion
version=2.2.0.0

x-ms-activity-id
c4bc4b76-47c2-42e9-868a-9ecfe0936b1e

x-ms-continuation
{"token":null,"range":{"min":"05C1DFFFFFFFFC","max":"FF"}}

x-ms-gatewayversion
version=2.2.0.0

Date
Fri, 05 Apr 2019 05:40:21 GMT

Content-Type
application/json

Если мы продолжим запрос с составным токеном продолжения, мы увидим результат.

Это нормальное поведение или ошибка?


person Aboo    schedule 05.04.2019    source источник


Ответы (2)


Использование .NET Framework будет обрабатывать токен продолжения изначально:

`var query = Client.CreateDocumentQuery (UriFactory.CreateDocumentCollectionUri (databaseId, collectionI, sqlQuery, feedOptions) .AsDocumentQuery ();

в то время как (query.HasMoreResults)

{var response = ожидание запроса.ExecuteNextAsync (); results.AddRange (ответ);} `

Добавление отзывов, предоставленных через связанную проблему GitHub:

Что касается ваших проблем, мы сталкивались с такими же ситуациями. У меня есть комментарии.

мы не знали об этом поведении, и наш клиент получил пустой список с токеном продолжения и в значительной степени нарушил наш поток.

Теперь на стороне сервера мы обрабатываем эту ситуацию и продолжаем, пока не получим результат. Вопрос в том, что если разделов 1000. Надо ли продолжать 100 раз? Это то, как ComosDB защищает свои SLA и время отклика менее 10 мс. $ ThinkingLoud

Да, это тоже прервало наш поток в первый раз. Но мы обрабатываем это и на стороне сервера (вместе с MaxNumberOfObjects мы продолжаем обслуживать запрос до тех пор, пока не получим номер, который хочет клиент), и шаблон, который вы видите, обусловлен базовой архитектурой CosmosDB, состоящей из физических + логических элементов. перегородки. Похоже, вы реализуете пейджинг во взаимодействии со своим клиентом, и это нормально. Однако я не думаю, что это то, что CosmosDB ссылается на свое время SLA.

Какие еще недокументированные неожиданные поведения могут застать нас врасплох в производственной среде? #ThinkingLoudAgain

Это немного расплывчато, но я бы посоветовал вам прочитать все FeedOptions вместе с советами по производительности CosmosDB и убедиться, что вы понимаете их, а также области их применения.

РЕДАКТИРОВАТЬ: Также еще одно предупреждение. В настоящее время у меня проблема с токеном продолжения и ключевым словом DISTINCT в запросе SQL. Это не работает должным образом без ORDER BY.

person Mike Ubezzi MSFT    schedule 25.04.2019

Это нормальное поведение для CosmosDb. Есть несколько вещей, которые могут вызвать внутренний тайм-аут запроса и привести к ответу с небольшим количеством результатов или даже с пустой коллекцией.

Из документации CosmosDb:

Количество элементов, возвращаемых при выполнении запроса, всегда будет меньше или равно MaxItemCount. Однако возможно, что другие критерии могли ограничить количество результатов, которые может вернуть запрос. Если вы выполните один и тот же запрос несколько раз, количество страниц может быть непостоянным. Например, если запрос регулируется, на каждой странице может быть меньше доступных результатов, что означает, что в запросе будут дополнительные страницы. В некоторых случаях также возможно, что ваш запрос может вернуть пустую страницу результатов.

person eNaught    schedule 27.04.2021