Рекомендации по использованию пакета SDK .NET для Azure Cosmos DB

ОБЛАСТЬ ПРИМЕНЕНИЯ: NoSQL

В этой статье рассматриваются рекомендации по использованию пакета SDK .NET для Azure Cosmos DB. С их помощью можно уменьшить задержку, повысить доступность и общую производительность.

Просмотрите видео ниже, чтобы узнать больше об использовании пакета SDK для .NET от инженера Azure Cosmos DB.

Контрольный список

Флажок установлен Тема Сведения/ссылки
Версия пакета SDK Всегда используйте последнюю версию пакета SDK для Azure Cosmos DB для оптимальной производительности.
Отдельный клиент Для оптимальной производительности используйте один экземплярCosmosClient на протяжении времени существования приложения.
Регионы Чтобы сократить задержку, запускайте приложение в том же регионе Azure, что и учетная запись Azure Cosmos DB, если это возможно. Для повышения доступности включите 2–4 региона и репликацию учетных записей в нескольких регионах. Для рабочих нагрузок включите отработку отказа, управляемую службой. В отсутствие этой конфигурации учетная запись будет терять доступность для записи на все время сбоя региона записи, так как переход на другой ресурс вручную не удастся из-за отсутствия подключения к региону. Дополнительные сведения о добавлении нескольких регионов с помощью пакета SDK .NET см. здесь
Доступность и отработка отказа Задайте ApplicationPreferredRegions или ApplicationRegion в версии 3 пакета SDK и PreferredLocations в версии 2 пакета SDK с помощью списка предпочтительных регионов. Во время отработки отказа операции записи отправляются в текущий регион записи, а все операции чтения — в первый регион в списке предпочтительных регионов. Дополнительные сведения о региональных механизмах отработки отказа см. в руководстве по устранению неполадок с доступностью.
ЦП Вы можете столкнуться с проблемами подключения или доступности из-за недостатка ресурсов на клиентском компьютере. Отслеживайте загрузку ЦП на узлах, на которых работает клиент Azure Cosmos DB, и увеличивайте масштаб, если уровень использования ресурсов высок.
Hosting Для повышения производительности рекомендуется вести обработку на узлах 64-разрядной версии Windows. Для рабочих нагрузок с учетом задержки в режиме direct настоятельно рекомендуется по возможности использовать по крайней мере 4 ядра и 8 ГБ памяти виртуальных машин.
Режимы подключения Для оптимальной производительности используйте режим прямого подключения. Соответствующие инструкции см. в документации по пакету SDK версии 3 или версии 2.
Сеть Если вы используете для запуска приложения виртуальную машину, включите на ней ускорение сети, чтобы устранить узкие места при большом объеме трафика и уменьшить задержку или нагрузку на ЦП. Кроме того, можно использовать конечную виртуальную машину более высокого класса, где максимальная загрузка ЦП будет составлять менее 70 %.
Временная нехватка портов Для редких и периодических соединений мы устанавливаем для параметров IdleConnectionTimeout и PortReuseMode значение PrivatePortPool. Свойство IdleConnectionTimeout помогает управлять временем закрытия неиспользуемых подключений. Это сокращает количество неиспользуемых подключений. По умолчанию неактивные соединения остаются открытыми в течение неограниченного времени. Это значение должно быть не меньше 10 минут. Мы рекомендуем использовать значения от 20 минут до 24 часов. Свойство PortReuseMode позволяет пакету SDK использовать небольшой пул временных портов для разных конечных точек назначения Azure Cosmos DB.
Использование шаблонов async/await Избегайте блокирующих вызовов Task.Result, Task.Wait и Task.GetAwaiter().GetResult(). Весь стек вызовов является асинхронным, чтобы использовать преимущества шаблонов async/await. Множество синхронных вызовов блокировки может привести к истощению ресурсов пула потоков и увеличении времени отклика.
Сквозное время ожидания Чтобы получить сквозное время ожидания, необходимо использовать параметры RequestTimeout и .CancellationToken Дополнительные сведения см. в руководстве по устранению неполадок времени ожидания.
Логика повторных попыток Дополнительные сведения об ошибках, с которыми следует повторить попытку, а также о том, какие ошибки повторяются пакетами SDK, см. в руководстве по проектированию. Для учетных записей, настроенных с несколькими регионами, существует несколько сценариев , в которых пакет SDK автоматически повторяет попытку в других регионах. Сведения о реализации .NET см. в исходном репозитории пакета SDK.
Кэширование имен баз данных и коллекций Извлеките имена ваших баз данных и контейнеров из конфигурации или кэшируйте их при запуске. Вызовы, такие как ReadDatabaseAsync или ReadDocumentCollectionAsync и CreateDatabaseQuery или CreateDocumentCollectionQuery, могут вести к вызовам метаданных службы, которые потребляют зарезервированное системой ограничение. CreateIfNotExist также следует использовать только один раз для настройки базы данных. Не стоит выполнять эти операции слишком часто.
Пакетная поддержка В сценариях, в которых оптимизация задержки может не потребоваться, рекомендуется включить пакетную поддержку для дампа больших объемов данных.
Параллельные запросы Пакет SDK для Azure Cosmos DB поддерживает параллельное выполнение запросов для повышения задержки и пропускной способности запросов. Рекомендуется задавать для свойства MaxConcurrency в QueryRequestsOptions значение, равное числу разделов. Если вы не знаете количество разделов, начните со значения int.MaxValue, что обеспечит оптимальную задержку. Затем уменьшайте это число до тех пор, пока оно не будет соответствовать ограничениям ресурсов среды, чтобы избежать проблем с ЦП. Кроме того, задайте для MaxBufferedItemCount значения ожидаемое число возвращаемых результатов, чтобы ограничить количество предварительно подготовленных результатов.
Задержки при тестировании производительности При тестировании в приложении следует реализовать задержки с интервалом RetryAfter. Соблюдение задержки гарантирует, что вы тратите минимальное количество времени на ожидание между повторными попытками.
Индексация Политика индексирования Azure Cosmos DB также позволяет добавлять пути к документам или исключать их из индексирования. Для этого используется параметр Indexing Paths (IndexingPolicy.IncludedPaths и IndexingPolicy.ExcludedPaths). Исключите из индексирования неиспользуемые пути, чтобы ускорить выполнение операций записи. Дополнительные сведения о создании индексов с помощью пакета SDK см. в разделе Советы по повышению производительности пакета SDK для .NET версии 3.
Размер документа Плата за запрос (т. е. затраты на обработку запросов) указанной операции напрямую зависит от размера документа. Рекомендуется уменьшить размер документов, так как операции с большими документами стоят больше, чем с меньшими.
Увеличение количества потоков или задач Так как вызовы Cosmos DB выполняются по сети, может потребоваться изменить степень параллелизма запросов, чтобы клиентское приложение тратило минимальное количество времени на ожидание между запросами. Например, если вы используете библиотеку параллельных задач .NET, создайте около нескольких сотен задач считывания или записи в Azure Cosmos DB.
Включение метрик запроса Для дополнительного журналирования запросов в серверной части можно включить метрики запросов SQL с помощью нашего пакета SDK для .NET. Дополнительные сведения о сборе метрик SQL-запросов см. в разделе Метрики запросов и производительность запросов.
Ведение журнала для пакета SDK Включите ведение журнала диагностики для пакета SDK для незавершенных сценариев, например, из-за появления исключений или превышения ожидаемой задержки для запросов.
DefaultTraceListener DefaultTraceListener создает проблемы с производительностью в рабочих средах, что приводит к возникновению узких мест из-за высокой загрузки ЦП и большого числа операций ввода-вывода. Убедитесь, что вы используете последние версии пакетов SDK, или удалите DefaultTraceListener из приложения.
Избегайте использования специальных символов в идентификаторах Некоторые символы ограничены и не могут использоваться в некоторых идентификаторах: "/", "\", "?", "#". Общей рекомендацией является не использовать специальные символы в идентификаторах, таких как имя базы данных, имя коллекции, идентификатор элемента или ключ секции, чтобы избежать непредвиденных действий.

Сбор диагностических данных

Для всех ответов в пакете SDK, включая CosmosException, доступно свойство Diagnostics. В это свойство записываются все сведения, связанные с одним запросом, в том числе сведения о повторных попытках и временных сбоях.

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

try
{
    ItemResponse<Book> response = await this.Container.CreateItemAsync<Book>(item: testItem);
    if (response.Diagnostics.GetClientElapsedTime() > ConfigurableSlowRequestTimeSpan)
    {
        // Log the response.Diagnostics.ToString() and add any additional info necessary to correlate to other logs 
    }
}
catch (CosmosException cosmosException)
{
    // Log the full exception including the stack trace with: cosmosException.ToString()
    
    // The Diagnostics can be logged separately if required with: cosmosException.Diagnostics.ToString()
}

// When using Stream APIs
ResponseMessage response = await this.Container.CreateItemStreamAsync(partitionKey, stream);
if (response.Diagnostics.GetClientElapsedTime() > ConfigurableSlowRequestTimeSpan || !response.IsSuccessStatusCode)
{
    // Log the diagnostics and add any additional info necessary to correlate to other logs with: response.Diagnostics.ToString()
}

Рекомендации по HTTP-подключениям

Пакет SDK для .NET использует HttpClient для выполнения HTTP-запросов независимо от настроенного режима подключения. В режиме прямого подключения HTTP используется для операций с метаданными, а в режиме шлюза — для операций с плоскостью данных и с метаданными. Одно из основных принципов HttpClient заключается в том, чтобы убедиться, HttpClient что может реагировать на изменения DNS в вашей учетной записи, настроив время существования подключения в пуле. Пока соединения в пуле хранятся открытыми, они не реагируют на изменения DNS. Этот параметр заставляет периодически закрывать соединения в пуле, гарантируя, что приложение реагирует на изменения DNS. Мы рекомендуем настроить это значение в соответствии с режимом подключения и рабочей нагрузкой, чтобы сбалансировать влияние на производительность частого создания новых подключений с необходимостью реагировать на изменения DNS (доступность). 5-минутное значение будет хорошим началом, которое можно увеличить, если это влияет на производительность, особенно для режима шлюза.

Вы можете внедрить пользовательский HttpClient с помощью CosmosClientOptions.HttpClientFactory, например:

// Use a Singleton instance of the SocketsHttpHandler, which you can share across any HttpClient in your application
SocketsHttpHandler socketsHttpHandler = new SocketsHttpHandler();
// Customize this value based on desired DNS refresh timer
socketsHttpHandler.PooledConnectionLifetime = TimeSpan.FromMinutes(5);

CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
{
    // Pass your customized SocketHttpHandler to be used by the CosmosClient
    // Make sure `disposeHandler` is `false`
    HttpClientFactory = () => new HttpClient(socketsHttpHandler, disposeHandler: false)
};

// Use a Singleton instance of the CosmosClient
return new CosmosClient("<connection-string>", cosmosClientOptions);

При использовании внедрения зависимостей .NET можно упростить процесс singleton:

SocketsHttpHandler socketsHttpHandler = new SocketsHttpHandler();
// Customize this value based on desired DNS refresh timer
socketsHttpHandler.PooledConnectionLifetime = TimeSpan.FromMinutes(5);
// Registering the Singleton SocketsHttpHandler lets you reuse it across any HttpClient in your application
services.AddSingleton<SocketsHttpHandler>(socketsHttpHandler);

// Use a Singleton instance of the CosmosClient
services.AddSingleton<CosmosClient>(serviceProvider =>
{
    SocketsHttpHandler socketsHttpHandler = serviceProvider.GetRequiredService<SocketsHttpHandler>();
    CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
    {
        HttpClientFactory = () => new HttpClient(socketsHttpHandler, disposeHandler: false)
    };

    return new CosmosClient("<connection-string>", cosmosClientOptions);
});

Рекомендации по использованию режима шлюза

При использовании режима шлюза увеличивайте System.Net MaxConnections на узел. При использовании режима шлюза запросы Azure Cosmos DB выполняются по протоколу HTTPS/RESTFUL. К ним применяются ограничения на количество подключений по умолчанию для каждого имени узла или IP-адреса. Может потребоваться задать для параметра MaxConnections более высокое значение (от 100 до 1000), чтобы клиентская библиотека могла использовать несколько одновременных подключений к Azure Cosmos DB. В SDK версии 1.8.0 для .NET и более поздних версий значение по умолчанию для параметра ServicePointManager.DefaultConnectionLimit равно 50. Чтобы изменить значение, можно задать для CosmosClientOptions.GatewayModeMaxConnectionLimit более высокое значение.

Рекомендации для интенсивных по записи рабочих нагрузок

Для рабочих нагрузок, имеющих большое количество полезных данных, установите для параметра запроса EnableContentResponseOnWrite значение false . Служба больше не будет возвращать созданный или обновленный ресурс пакету SDK. Как правило, поскольку приложение имеет создаваемый объект, служба не должна его возвращать. Значения заголовков по-прежнему доступны, например плата за запрос. Отключение реагирования на содержимое может помочь повысить производительность, поскольку пакету SDK больше не требуется выделять память или сериализовать текст ответа. Это также сокращает использование пропускной способности сети для еще большего повышения производительности.

Важно!

При установке значения EnableContentResponseOnWrite также false отключается ответ от операции триггера.

Рекомендации для мультитенантных приложений

Приложения, которые распределяют использование между несколькими клиентами, где каждый клиент представлен разными базами данных, контейнерами или ключами секции в одной учетной записи Azure Cosmos DB , должны использовать один экземпляр клиента. Один экземпляр клиента может взаимодействовать со всеми базами данных, контейнерами и ключами секций в учетной записи, и рекомендуется использовать одноэлементный шаблон.

Однако если каждый клиент представлен отдельной учетной записью Azure Cosmos DB, необходимо создать отдельный экземпляр клиента для каждой учетной записи. Одноэлементный шаблон по-прежнему применяется к каждому клиенту (по одному клиенту для каждой учетной записи в течение всего времени существования приложения), но если количество клиентов велико, управление числом клиентов может быть трудно. Подключения могут увеличиваться за пределы вычислительной среды и вызывать проблемы с подключением.

В таких случаях рекомендуется:

  • Изучите ограничения вычислительной среды (ресурсы ЦП и подключения). По возможности рекомендуется использовать виртуальные машины с 4 ядрами и 8 ГБ памяти.
  • На основе ограничений вычислительной среды определите количество экземпляров клиента (и, следовательно, количество клиентов), которые может обрабатывать один вычислительный экземпляр. Количество открытых подключений для каждого клиента можно оценить в зависимости от выбранного режима подключения.
  • Оцените распределение клиентов между экземплярами. Если каждый вычислительный экземпляр может успешно обрабатывать определенное ограниченное количество клиентов, балансировка нагрузки и маршрутизация клиентов в разные вычислительные экземпляры позволят масштабироваться по мере роста числа клиентов.
  • Для разреженных рабочих нагрузок рекомендуется использовать наименее часто используемый кэш в качестве структуры для хранения экземпляров клиентов и удаления клиентов, к которым не был предоставлен доступ в течение определенного периода времени. Одним из вариантов в .NET является MemoryCacheEntryOptions, где registerPostEvictionCallback можно использовать для удаления неактивных клиентов , а SetSlidingExpiration — для определения максимального времени хранения неактивных подключений.
  • Оцените использование режима шлюза , чтобы уменьшить количество сетевых подключений.
  • При использовании режима Direct рекомендуется настроить CosmosClientOptions.IdleTcpConnectionTimeout и CosmosClientOptions.PortReuseMode в конфигурации прямого режима , чтобы закрыть неиспользуемые подключения и контролировать объем подключений .

Следующие шаги

Пример приложения, используемого в сценариях оценки производительности Azure Cosmos DB на нескольких клиентских компьютерах, см. в статье Проверка производительности и масштабирования с помощью Azure Cosmos DB.

Дополнительные сведения о создании приложения с высокой масштабируемостью и производительностью см. в статье Partitioning and scaling in Azure Cosmos DB (Секционирование и масштабирование в Azure Cosmos DB).

Пытаетесь выполнить планирование ресурсов для миграции в Azure Cosmos DB? Можете использовать для этого сведения о существующем кластере базы данных.