Рекомендации по использованию пакета 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, и увеличивайте масштаб, если уровень использования ресурсов высок.
Размещение на компьютере Для повышения производительности рекомендуется вести обработку на узлах 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 Query см. в разделе метрики запросов и производительность.
Ведение журнала для пакета 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-запросов независимо от настроенного режима подключения. В режиме Direct 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, необходимо создать отдельный экземпляр клиента для каждой учетной записи. Шаблон singleton по-прежнему применяется для каждого клиента (один клиент для каждой учетной записи для каждой учетной записи в течение времени существования приложения), но если объем клиентов высок, количество клиентов может быть трудно управлять. Подключения могут увеличиваться за пределы вычислительной среды и вызывать проблемы с подключением.

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

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

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

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

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

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