Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Это важно
Это не последняя версия пакета SDK для Java для Azure Cosmos DB! Вы должны обновить проект до пакета SDK Java для Azure Cosmos DB версии 4 , а затем ознакомиться с руководством по производительности пакета SDK java для Azure Cosmos DB версии 4. Следуйте инструкциям, приведенным в руководстве по миграции на Azure Cosmos DB Java SDK v4 и в руководстве по Reactor vs RxJava, для обновления.
Советы по производительности в этой статье предназначены только для пакета SDK Async Java для Azure Cosmos DB версии 2. Дополнительные сведения см. в заметках о релизе SDK Async Java для Azure Cosmos DB версии 2, репозитории Maven и руководстве по устранению неполадок для Azure Cosmos DB Async Java SDK версии 2.
Это важно
31 августа 2024 г. пакет SDK Async Java для Azure Cosmos DB версии 2.x будет прекращен; пакет SDK и все приложения, использующие пакет SDK, будут продолжать функционировать; Azure Cosmos DB просто перестанет предоставлять дальнейшее обслуживание и поддержку этого пакета SDK. Для перехода на Azure Cosmos DB с пакетом SDK для Java версии 4 рекомендуется следовать инструкциям, приведенным выше.
Azure Cosmos DB — быстрая и гибкая распределенная база данных, которая легко масштабируется с гарантированной задержкой и пропускной способностью. Для масштабирования базы данных с помощью Azure Cosmos DB не нужно вносить в архитектуру существенные изменения или писать сложный код. Для увеличения или уменьшения масштаба достаточно вызвать один метод интерфейса API или пакета SDK. Однако, так как Доступ к Azure Cosmos DB осуществляется через сетевые вызовы, существуют клиентские оптимизации, которые можно сделать для достижения пиковой производительности при использовании пакета SDK Async Java для Azure Cosmos DB версии 2.
Поэтому, если вы хотите повысить производительность базы данных, рассмотрите следующие варианты:
Нетворкинг
Режим подключения: использование режима прямого подключения
Как клиент подключается к Azure Cosmos DB, имеет важные последствия для производительности, особенно с точки зрения задержки на стороне клиента. ConnectionMode — это ключевой параметр конфигурации, доступный для настройки клиентской ConnectionPolicy. Для SDK Async Java для Azure Cosmos DB версии 2 доступны два режима подключения:
Режим шлюза поддерживается на всех платформах SDK и по умолчанию настроен. Если приложения выполняются в корпоративной сети с строгими ограничениями брандмауэра, режим шлюза является лучшим выбором, так как он использует стандартный порт HTTPS и одну конечную точку. Однако компромисс производительности заключается в том, что режим шлюза включает дополнительный сетевой прыжок каждый раз, когда данные считываются или записываются в Azure Cosmos DB. Поскольку режим Direct сокращает количество сетевых переходов, он обеспечивает лучшую производительность.
ConnectionMode настраивается во время построения экземпляра DocumentClient с параметром ConnectionPolicy.
Async Java SDK версии 2 (Maven com.microsoft.azure::azure-cosmosdb)
public ConnectionPolicy getConnectionPolicy() {
ConnectionPolicy policy = new ConnectionPolicy();
policy.setConnectionMode(ConnectionMode.Direct);
policy.setMaxPoolSize(1000);
return policy;
}
ConnectionPolicy connectionPolicy = new ConnectionPolicy();
DocumentClient client = new DocumentClient(HOST, MASTER_KEY, connectionPolicy, null);
Повышение производительности за счет размещения клиентов в одном регионе Azure
Если это возможно, размещайте приложения, выполняющие вызовы к Azure Cosmos DB, в том же регионе, в котором находится база данных Azure Cosmos DB. Для приблизительного сравнения: вызовы к Azure Cosmos DB в пределах региона выполняются в течение 1–2 мс, но задержка между Восточным и Западным побережьем США превышает 50 мс. Значение задержки может отличаться в зависимости от выбранного маршрута при передаче запроса от клиента к границе центра обработки данных Azure. Минимальная возможная задержка достигается при размещении клиентского приложения в том же регионе Azure, в котором предоставляется конечная точка Azure Cosmos DB. Список доступных регионов см. на странице Регионы Azure.
Использование пакета SDK
Установка последней версии пакета SDK
Пакеты SDK для Azure Cosmos DB постоянно улучшаются, чтобы обеспечивать самую высокую производительность. Ознакомьтесь со страницей Заметок о выпуске версии 2 пакета SDK для Async Java для Azure Cosmos DB, чтобы определить наиболее недавно выпущенный SDK и просмотреть улучшения.
Использование одного и того же клиента Azure Cosmos DB в течение всего жизненного цикла приложения
Каждый экземпляр AsyncDocumentClient является потокобезопасным и выполняет эффективное управление подключениями и кэширование адресов. Чтобы обеспечить эффективное управление подключениями и повысить производительность asyncDocumentClient, рекомендуется использовать один экземпляр AsyncDocumentClient для каждого домена приложения.
Настройка политики подключения
По умолчанию запросы Azure Cosmos DB в режиме direct выполняются по протоколу TCP при использовании пакета SDK Async Java для Azure Cosmos DB версии 2. В пакете SDK используется специальная архитектура режима Direct для динамического управления сетевыми ресурсами и повышения производительности.
В azure Cosmos DB Async Java SDK версии 2 режим Direct подходит для повышения производительности базы данных с большинством рабочих нагрузок.
- Обзор режима Direct
Архитектура на стороне клиента, которая используется в режиме Direct, обеспечивает прогнозируемое использование сети и мультиплексируемый доступ к репликам Azure Cosmos DB. На схеме выше показано, как прямой режим направляет клиентские запросы на реплики в серверной части Azure Cosmos DB. Архитектура режима Direct выделяет до 10 каналов на стороне клиента для каждой реплики базы данных. Канал является TCP-подключением с предшествующим буфером запроса, глубиной в 30 запросов. Каналы, принадлежащие реплике, динамически выделяются по мере необходимости конечной точкой службы реплики. Когда пользователь выдает запрос в режиме Direct, TransportClient направляет запрос в соответствующую конечную точку службы на основе ключа секции. Очередь запросов буферизует запросы перед конечной точкой службы.
Параметры конфигурации ConnectionPolicy для режима Direct
В качестве первого шага используйте приведенные ниже рекомендуемые параметры конфигурации. Обратитесь к команде Azure Cosmos DB , если у вас возникли проблемы с этим конкретным разделом.
Если вы используете Azure Cosmos DB в качестве эталонной базы данных (т. е. база данных используется для многих операций чтения точек и нескольких операций записи), она может быть приемлемой, чтобы задать значение idleEndpointTimeout равным 0 (т. е. нет времени ожидания).
Параметр конфигурации По умолчанию размер страницы буфера 8192 connectionTimeout "PT1M" тайм-аут неактивного канала "PT0S" idleEndpointTimeout "PT1M10S" maxBufferCapacity 8388608 maxChannelsPerEndpoint 10 максимальное количество запросов на канал 30 время обнаружения зависания при получении "PT1M5S" requestExpiryInterval "PT5S" requestTimeout "PT1M" requestTimerResolution "PT0.5S" sendHangDetectionTime "PT10S" shutdownTimeout "PT15S"
Советы по программированию для режима Direct
Ознакомьтесь со статьей Устранение неполадок пакета SDK Async Java версии 2 для Azure Cosmos DB в качестве основы для решения любых проблем с пакетом SDK.
Некоторые важные советы по программированию при использовании режима Direct:
Используйте многопоточность в приложении для эффективной передачи данных TCP . После выполнения запроса приложение должно подписаться на получение данных в другом потоке. Пренебрежение этим вынуждает к непреднамеренной полудуплексной операции, и последующие запросы блокируются в ожидании ответа на предыдущий запрос.
Выполняйте рабочие нагрузки с интенсивным вычислением в выделенном потоке . По аналогичным причинам, описанным в предыдущем совете, такие операции, как сложная обработка данных, лучше всего помещаются в отдельный поток. Запрос, который извлекает данные из другого хранилища данных (например, если поток использует одновременно хранилища данных Azure Cosmos DB и Spark) может столкнуться с повышенной задержкой и рекомендуется создать дополнительный поток, ожидающий ответа от другого хранилища данных.
- Базовые сетевые операции ввода-вывода в Azure Cosmos DB Async Java SDK v2 управляются Netty. Ознакомьтесь с этими советами по предотвращению шаблонов кодирования, которые блокируют потоки ввода-вывода Netty.
Моделирование данных . Соглашение об уровне обслуживания Azure Cosmos DB предполагает, что размер документа меньше 1 КБ. Оптимизация модели данных и программирования для уменьшения размера документа обычно приводит к уменьшению задержки. Если вам необходимо хранить и извлекать документы размером более 1 КБ, рекомендуется, чтобы документы ссылались на данные в Azure Blob Storage.
Настройка параллельных запросов для секционированных коллекций
Пакет SDK Async Java для Azure Cosmos DB версии 2 поддерживает параллельные запросы, которые позволяют запрашивать секционированную коллекцию параллельно. Дополнительные сведения см. в примерах кода , связанных с работой с пакетами SDK. Параллельные запросы предназначены для повышения задержки запросов и пропускной способности по сравнению с их последовательным аналогом.
Настройка setMaxDegreeOfParallelism:
Параллельные запросы позволяют одновременно обращаться к нескольким секциям. Однако данные из коллекции с разделением извлекаются последовательно по отношению к запросу. Таким образом, используйте setMaxDegreeOfParallelism, чтобы задать количество секций с максимальной вероятностью достижения наиболее эффективного запроса, если все остальные системные условия остаются неизменными. Если вы не знаете количество секций, можно использовать setMaxDegreeOfParallelism для задания большого числа, а система выбирает минимальное (число секций, предоставленных пользователем входных данных) в качестве максимальной степени параллелизма.
Важно отметить, что параллельные запросы обеспечивают наилучшие преимущества, если данные равномерно распределяются по всем секциям в отношении запроса. Если разделенная коллекция разделена таким образом, что все или большинство данных, возвращаемых запросом, сосредоточены в нескольких разделах (в худшем случае в одном разделе), то производительность запроса будет ограничена этими разделами.
Настройка параметра setMaxBufferedItemCount:
Параллельный запрос предназначен для предварительного получения результатов, пока текущий пакет результатов обрабатывается клиентом. Предварительная выборка помогает уменьшить общую задержку запроса. setMaxBufferedItemCount ограничивает количество предварительно подготовленных результатов. Установка setMaxBufferedItemCount на ожидаемое количество возвращаемых результатов (или более высокое число) позволяет запросу получить максимальное преимущество от предварительной выборки.
Предварительная выборка работает одинаково, независимо от MaxDegreeOfParallelism, и существует один буфер для данных из всех разделов.
Реализация отката в интервалах getRetryAfterInMilliseconds
Во время тестирования производительности необходимо увеличивать нагрузку до тех пор, пока небольшая часть запросов не начнет ограничиваться. При ограничении в скорости клиентское приложение должно прекратить попытки на интервал повторных попыток, заданного сервером. Учитывая обратный выход, вы гарантируете, что вы тратите минимальное время ожидания между повторными попытками.
Горизонтальное увеличение масштаба рабочей нагрузки клиента
Если вы тестируете на высоком уровне пропускной способности (>50 000 ЕЗ/с), клиентское приложение может стать узким местом из-за ограничения компьютера на загрузку ЦП или сети. Если вы достигли этой точки, то можете повысить производительность Azure Cosmos DB, развернув клиентские приложения на нескольких серверах.
Использование адресации на основе имен
Используйте адресацию на основе имен, где ссылки имеют формат
dbs/MyDatabaseId/colls/MyCollectionId/docs/MyDocumentId, а не SelfLinks (_self), которые имеют форматdbs/<database_rid>/colls/<collection_rid>/docs/<document_rid>, чтобы избежать извлечения ResourceId всех ресурсов, используемых для создания ссылки. Кроме того, так как эти ресурсы повторно создаются (возможно, с тем же именем), кэширование их может не помочь.Настройка размера страницы для повышения производительности запросов и лент чтения
При выполнении массового чтения документов с помощью функциональности чтения данных (например, readDocuments) или при выполнении SQL-запроса результаты возвращаются в сегментированном виде, если результирующий набор слишком велик. По умолчанию результаты возвращаются в блоках из 100 элементов или 1 МБ, в зависимости от того, какой предел будет достигнут в первую очередь.
Чтобы уменьшить количество сетевых обходов, необходимых для получения всех применимых результатов, можно увеличить размер страницы с помощью заголовка запроса x-ms-max-item-count до 1000. В случаях, когда необходимо отобразить только несколько результатов, например, если пользовательский интерфейс или API приложения возвращает только 10 результатов за раз, можно также уменьшить размер страницы до 10, чтобы уменьшить пропускную способность, потребляемую для операций чтения и запросов.
Вы также можете задать размер страницы с помощью метода setMaxItemCount.
Использование надлежащего планировщика (избегайте перехвата потоков цикла обработки событий ввода-вывода netty)
Пакет SDK Async Java для Azure Cosmos DB версии 2 использует netty для неблокирования операций ввода-вывода. В пакете SDK используется фиксированное число потоков цикла обработки событий ввода-вывода netty (это число соответствует числу ядер ЦП на компьютере) для выполнения операций ввода-вывода. Наблюдаемый объект, возвращаемый API, выдает результат в одном из общих потоков событий ввода-вывода. Поэтому важно не блокировать общие потоки цикла обработки событий ввода-вывода Netty. Выполнение интенсивной работы ЦП или блокировки операций в потоке netty цикла событий ввода-вывода может привести к взаимоблокировке или значительно снижению пропускной способности пакета SDK.
Например, следующий код выполняет интенсивную нагрузку на ЦП в потоке ввода-вывода на Netty в цикле событий.
Async Java SDK версии 2 (Maven com.microsoft.azure::azure-cosmosdb)
Observable<ResourceResponse<Document>> createDocObs = asyncDocumentClient.createDocument( collectionLink, document, null, true); createDocObs.subscribe( resourceResponse -> { //this is executed on eventloop IO netty thread. //the eventloop thread is shared and is meant to return back quickly. // // DON'T do this on eventloop IO netty thread. veryCpuIntensiveWork(); });После получения результата, если вы хотите выполнить интенсивные вычисления на ЦП с этим результатом, следует избежать выполнения их в потоке ввода-вывода Netty в цикле обработки событий. Вместо этого вы можете указать собственный планировщик, чтобы использовать ваш собственный поток для выполнения работы.
Async Java SDK версии 2 (Maven com.microsoft.azure::azure-cosmosdb)
import rx.schedulers; Observable<ResourceResponse<Document>> createDocObs = asyncDocumentClient.createDocument( collectionLink, document, null, true); createDocObs.subscribeOn(Schedulers.computation()) subscribe( resourceResponse -> { // this is executed on threads provided by Scheduler.computation() // Schedulers.computation() should be used only when: // 1. The work is cpu intensive // 2. You are not doing blocking IO, thread sleep, etc. in this thread against other resources. veryCpuIntensiveWork(); });В зависимости от типа вашей работы следует использовать соответствующий существующий планировщик RxJava для вашей работы. См. здесь
Schedulers.Дополнительные сведения см. на странице GitHub для пакета SDK Async Java для Azure Cosmos DB версии 2.
Отключите ведение журнала Netty
Ведение журнала библиотеки Netty является слишком подробным и необходимо отключить (отключение ведения журнала в конфигурации может быть недостаточно), чтобы избежать дополнительных затрат процессора. Если вы не используете режим отладки, полностью отключите ведение журналов netty. Поэтому если вы используете log4j для удаления дополнительных затрат на ЦП, вызванных
org.apache.log4j.Category.callAppenders()netty, добавьте следующую строку в базу кода:org.apache.log4j.Logger.getLogger("io.netty").setLevel(org.apache.log4j.Level.OFF);Лимит на ресурсы открытых файлов ОС
Некоторые дистрибутивы Linux (например, RedHat) ограничивают максимальное число открытых файлов и общее число подключений. Чтобы узнать текущие ограничения, выполните следующую команду:
ulimit -aКоличество открытых файлов (nofile) должно быть достаточно большим, чтобы иметь достаточно места для настроенного размера пула подключений и других открытых файлов ОС. Можно изменить параметры, чтобы увеличить размер пула соединений.
Откройте файл limits.conf:
vim /etc/security/limits.confДобавьте или измените следующие строки:
* - nofile 100000
Политика индексирования
Исключите неиспользуемые пути из индексирования, чтобы ускорить выполнение операций записи
Политика индексирования Azure Cosmos DB позволяет указать пути к документам для включения или исключения из индексирования с помощью путей индексирования (setIncludedPaths и setExcludedPaths). Возможность управления путями индексирования позволяет оптимизировать производительность записи и снизить затраты на хранение индекса для сценариев с заранее определенными шаблонами запросов. Это связано с тем, что затраты на индексирование непосредственно зависят от количества уникальных путей индексирования. Например, в следующем коде показано, как исключить весь раздел документов (также известный как поддерев) из индексирования с помощью подстановочного знака "*".
Async Java SDK версии 2 (Maven com.microsoft.azure::azure-cosmosdb)
Index numberIndex = Index.Range(DataType.Number); numberIndex.set("precision", -1); indexes.add(numberIndex); includedPath.setIndexes(indexes); includedPaths.add(includedPath); indexingPolicy.setIncludedPaths(includedPaths); collectionDefinition.setIndexingPolicy(indexingPolicy);Дополнительные сведения см. в статье Политики индексации Azure Cosmos DB.
Пропускная способность
Измерение и настройка для снижения использования единиц запроса в секунду
Azure Cosmos DB предоставляет обширный набор операций с документами в коллекции базы данных, в том числе реляционные и иерархические запросы с использованием UDF, хранимых процедур и триггеров. Затраты, связанные с каждой из этих операций, зависят от типа процессора, операций ввода-вывода и памяти, необходимой для завершения операции. Вместо того чтобы думать о закупке и управлении аппаратными ресурсами, вы можете думать о единице запроса (RU) как единой меры для ресурсов, необходимых для выполнения различных операций с базами данных и обслуживания запросов приложений.
Пропускная способность выделяется на основе количества единиц запроса, заданного для каждого контейнера. Удельный расход единиц запросов оценивается в расчете на одну секунду. Частота запросов для приложений, у которых она превышает подготовленные единицы запросов для контейнера, будет ограничена, пока она не упадет ниже зарезервированного для контейнера уровня. Если приложению требуется более высокий уровень пропускной способности, можно увеличить ее путем выделения дополнительных единиц запросов.
Сложность запроса влияет на количество единиц запроса, потребляемых операцией. Количество и характер предикатов, количество UDF, размер набора исходных данных — все это влияет на затраты на операции запроса.
Чтобы оценить расходы на любую операцию (создание, обновление или удаление), проверьте значение заголовка x-ms-request-charge. Это значение содержит число единиц запроса, потребляемых соответствующей операцией. Также можно проверить аналогичное свойство RequestCharge в ResourceResponse<T> или FeedResponse<T>.
Async Java SDK версии 2 (Maven com.microsoft.azure::azure-cosmosdb)
ResourceResponse<Document> response = asyncClient.createDocument(collectionLink, documentDefinition, null, false).toBlocking.single(); response.getRequestCharge();Стоимость запроса, указанная в этом заголовке, составляет долю от вашей выделенной пропускной способности. Например, если у вас подготовлено 2000 ЕЗ/с, и предыдущий запрос возвращает 1000 документов по 1 КБ, стоимость операции составляет 1000. Таким образом, перед ограничением частоты выполнения последующих запросов сервер за одну секунду выполняет только два таких запроса. Чтобы узнать больше, ознакомьтесь с единицами запроса и калькулятором единиц запроса.
Обработка ограничения скорости / слишком высокая частота запросов
Выполнение запроса, который превышает лимит зарезервированной пропускной способности для учетной записи, не приводит к снижению производительности сервера, так как пользователь не сможет превысить это зарезервированное значение. Сервер заранее завершит запрос с ошибкой RequestRateTooLarge (код состояния HTTP: 429) и вернет заголовок x-ms-retry-after-ms, индиицирующий время (в миллисекундах), которое пользователь должен подождать, прежде чем повторно попытаться выполнить этот запрос.
HTTP Status 429, Status Line: RequestRateTooLarge x-ms-retry-after-ms :100Все пакеты SDK автоматически перехватывают этот ответ, соблюдают указанный сервером заголовок retry-after и повторяют запрос. Если к вашей учетной записи параллельно имеет доступ только один клиент, следующая попытка будет успешной.
Если у вас более одного клиента, постоянно превышающего скорость запросов, количество повторных попыток, установленное клиентом по умолчанию на 9, может быть недостаточным; в этом случае клиент генерирует DocumentClientException с кодом состояния 429 для приложения. Число повторных попыток по умолчанию можно изменить с помощью setRetryOptions в экземпляре ConnectionPolicy. По умолчанию, DocumentClientException с кодом состояния 429 возвращается после суммарного времени ожидания в 30 секунд, если запрос продолжает превышать установленную квоту запросов. Это происходит, даже если текущее значение количества повторных попыток (по умолчанию (9) или определенное пользователем) меньше максимального значения.
Хотя автоматическое повторное выполнение запроса помогает улучшить устойчивость и удобство использования большинства приложений, оно может встать в противоречие при проведении тестов производительности, особенно при измерении задержек. Если эксперимент достигает ограничения сервера и заставляет клиентский SDK повторять попытки в тихом режиме, на стороне клиента могут возникать пиковые задержки. Чтобы избежать скачков латентности во время экспериментов с производительностью, измерьте затраты каждой операции и убедитесь, что запросы работают ниже зарезервированной скорости запросов. Дополнительные сведения см. в статье Единицы запросов.
Использование меньших документов для более высокой пропускной способности
Стоимость запроса (плата за обработку запроса) для каждой операции напрямую зависит от размера документа. Операции с большими документами стоят больше, чем операции с маленькими документами.
Дальнейшие шаги
Дополнительные сведения о создании приложения с высокой масштабируемостью и производительностью см. в статье Partitioning and scaling in Azure Cosmos DB (Секционирование и масштабирование в Azure Cosmos DB).