Поделиться через


Советы по повышению производительности для пакета Java SDK Sync версии 2 для Azure Cosmos DB

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

Внимание

Это не последняя версия пакета SDK для Java для Azure Cosmos DB! Необходимо обновить проект до Azure Cosmos DB с пакетом SDK для Java версии 4, а затем ознакомиться с руководством по повышению производительности Azure Cosmos DB с пакетом SDK для Java версии 4. Следуйте инструкциям в руководстве по переходу на Azure Cosmos DB с пакетом SDK для Java версии 4 и руководстве Reactor и RxJava.

Эти советы по повышению производительности предназначены только для Azure Cosmos DB с пакетом SDK для Sync Java версии 2. Дополнительные сведения см. в репозитории Maven.

Внимание

С 29 февраля 2024 г. будет прекращена поддержка Azure Cosmos DB с пакетом SDK для Sync Java версии 2.x. Пакет SDK и все использующие его приложения продолжат работать, просто Azure Cosmos DB прекратит обслуживание и поддержку этого пакета. Для перехода на Azure Cosmos DB с пакетом SDK для Java версии 4 рекомендуется следовать инструкциям, приведенным выше.

Azure Cosmos DB — быстрая и гибкая распределенная база данных, которая легко масштабируется с гарантированной задержкой и пропускной способностью. Для масштабирования базы данных с помощью Azure Cosmos DB не нужно вносить в архитектуру существенные изменения или писать сложный код. Для увеличения или уменьшения масштаба достаточно выполнить один вызов API. Дополнительные сведения см. в разделах о подготовке пропускной способности контейнера и о подготовке пропускной способности базы данных. Но так как для доступа к Azure Cosmos DB выполняются сетевые вызовы, то некоторая оптимизация на стороне клиента поможет повысить производительность при работе с Azure Cosmos DB с пакетом SDK для Sync Java версии 2.

Поэтому, если вы хотите повысить производительность базы данных, рассмотрите следующие варианты:

Сеть

  1. Режим подключения: использование DirectHttps

    Режим подключения к Azure Cosmos DB серьезно влияет на производительность, в частности на задержку на стороне клиента. Важнейший параметр для настройки политики подключения (ConnectionPolicy) на стороне клиента — это ConnectionMode. Доступны два режима подключения:

    1. Шлюз (по умолчанию)

    2. DirectHttps ("Прямое подключение через HTTPS").

      Режим шлюза поддерживается на всех платформах SDK, поэтому он установлен по умолчанию. Если ваше приложение работает в корпоративной сети с жесткими ограничениями брандмауэра, шлюз — лучший выбор, так как он использует стандартный порт HTTPS и одну конечную точку. Но режим шлюза не обеспечивает максимальную производительность, поскольку задействует дополнительный сетевой узел при каждой операции чтения или записи данных в Azure Cosmos DB. Благодаря этому, режим DirectHttps предлагает лучшую производительность за счет уменьшения количества переходов в сети.

      Версия 2 пакета Java SDK для синхронизации в Azure Cosmos DB использует HTTPS в качестве транспортного протокола. HTTPS использует TLS для первоначальной аутентификации и шифрования трафика. При использовании Azure Cosmos DB Sync Java SDK v2 необходимо открыть только HTTPS порт 443.

      Параметр ConnectionMode настраивается при создании экземпляра DocumentClient с использованием параметра ConnectionPolicy.

    Пакет SDK синхронизации для Java версии 2 (Maven com.microsoft.azure::azure-documentdb)

    public ConnectionPolicy getConnectionPolicy() {
      ConnectionPolicy policy = new ConnectionPolicy();
      policy.setConnectionMode(ConnectionMode.DirectHttps);
      policy.setMaxPoolSize(1000);
      return policy;
    }
    
    ConnectionPolicy connectionPolicy = new ConnectionPolicy();
    DocumentClient client = new DocumentClient(HOST, MASTER_KEY, connectionPolicy, null);
    

    Схема с политикой подключения Azure Cosmos DB.

  2. Повышение производительности за счет размещения клиентов в одном регионе Azure

    Если это возможно, размещайте приложения, выполняющие вызовы к Azure Cosmos DB, в том же регионе, в котором находится база данных Azure Cosmos DB. Для приблизительного сравнения: вызовы к Azure Cosmos DB в пределах региона выполняются в течение 1–2 мс, но задержка между Восточным и Западным побережьем США превышает 50 мс. Значение задержки может отличаться в зависимости от выбранного маршрута при передаче запроса от клиента к границе центра обработки данных Azure. Минимальная возможная задержка достигается при размещении клиентского приложения в том же регионе Azure, в котором предоставляется конечная точка Azure Cosmos DB. Список доступных регионов см. на странице Регионы Azure.

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

Использование пакета SDK

  1. Установка последней версии пакета SDK

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

  2. Использование одного и того же клиента Azure Cosmos DB в течение всего жизненного цикла приложения

    Каждый экземпляр DocumentClient является потокобезопасным и при работе в режиме прямого подключения эффективно управляет подключениями и кэширует адреса. Чтобы реализовать возможность управления подключениями и оптимизировать производительность, рекомендуется использовать один экземпляр DocumentClient для каждого домена в течение жизненного цикла приложения.

  3. При использовании режима шлюза увеличьте MaxPoolSize для каждого хоста.

    В режиме шлюза Azure Cosmos DB выполняет запросы через HTTPS или REST, а значит на них распространяется стандартное ограничение на количество подключений к одному имени узла или IP-адресу. Возможно, стоит увеличить это значение (до 200–1000), чтобы клиентская библиотека могла использовать несколько одновременных подключений к Azure Cosmos DB. В Azure Cosmos DB SDK версии 2 для Java Sync значение параметра ConnectionPolicy.getMaxPoolSize по умолчанию составляет 100. Используйте setMaxPoolSize, чтобы изменить это значение.

  4. Настройка параллельных запросов для секционированных коллекций

    В Azure Cosmos DB с пакетом SDK для Sync Java версии 1.9.0 и выше поддерживаются параллельные запросы, позволяющие обращаться к секционированным коллекциям в параллельном режиме. Дополнительные сведения см. в примерах кода для работы с пакетами SDK. Параллельные запросы предназначены для сокращения времени задержки и повышения пропускной способности по сравнению с их последовательными аналогами.

    (а) Применение setMaxDegreeOfParallelism. Параллельный режим запросов позволяет одновременно обращаться к нескольким секциям. Однако данные из каждой секционированной коллекции извлекаются в рамках запроса последовательно. С помощью setMaxDegreeOfParallelism установите значение, соответствующее количеству секций, что обеспечит максимальную вероятность высокой производительности запроса при сохранении всех остальных параметров системы. Если вы не знаете количество разделов, вы можете установить высокое значение для setMaxDegreeOfParallelism, и система выберет наименьшее из двух значений: количество разделов или число, указанное пользователем, чтобы установить максимальную степень параллелизма.

    Следует отметить, что параллельные запросы обеспечивают больше преимуществ, если данные равномерно распределены во всех секциях по отношению к запросу. Если секционированная коллекция поделена таким образом, что все или большинство данных, возвращаемых запросом, сосредоточены в нескольких секциях (в одном разделе в худшем случае), то производительность запроса будет ограничена этими секциями.

    (b) Настройка setMaxBufferedItemCount: параллельный запрос предназначен для предварительного получения результатов, пока текущий пакет результатов обрабатывается клиентом. Предварительная выборка помогает снизить общую задержку запроса. setMaxBufferedItemCount ограничивает количество предварительно подготовленных результатов. Задав параметр setMaxBufferedItemCount ожидаемому количеству возвращаемых результатов (или более высокому числу), это позволяет запросу получить максимальное преимущество от предварительной выборки.

    Предварительная выборка работает одинаково независимо от MaxDegreeOfParallelism, и существует один буфер для данных из всех разделов.

  5. Реализовать задержку с интервалами getRetryAfterInMilliseconds.

    Во время тестирования производительности следует увеличивать нагрузку до тех пор, пока небольшая часть запросов не начнет ограничиваться. Если установлено ограничение, клиентское приложение должно уменьшить интенсивность запросов в соответствии с интервалом повтора, указанным сервером. Это гарантирует, что время ожидания между повторными попытками будет минимальным. Поддержка политики повторов включена в версии 1.8.0 и выше Azure Cosmos DB Sync Java SDK. Дополнительные сведения см. в статье о методе getRetryAfterInMilliseconds.

  6. Масштабирование клиентской рабочей нагрузки

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

  7. Адресация на основе имен

    Используйте адресацию на основе имен, где ссылки имеют формат dbs/MyDatabaseId/colls/MyCollectionId/docs/MyDocumentId, вместо SelfLinks (_self), которые имеют формат dbs/<database_rid>/colls/<collection_rid>/docs/<document_rid>, чтобы избежать получения ResourceIds всех ресурсов, использованных для создания ссылки. Кэширование этих данных не увеличит производительность, поскольку ресурсы могут создаваться заново (иногда с теми же именами).

  8. Настройка размера страницы для улучшения производительности запросов и чтения лент

    Если при массовом чтении документов с помощью функциональности чтения канала (например, readDocuments) или обработке запроса SQL будет получен слишком большой набор результатов, результаты возвращаются сегментированно. По умолчанию результаты возвращаются порциями по 100 элементов или 1 МБ, в зависимости от того, какой лимит достигнут первым.

    Чтобы уменьшить количество сетевых запросов, необходимых для получения всех нужных результатов, увеличьте размер страницы до 1000 с помощью заголовка запроса x-ms-max-item-count. Чтобы отобразить только некоторые результаты, например, когда пользовательский интерфейс или приложение API возвращает только десять результатов за раз, размер страницы можно уменьшить до 10. Это позволит снизить пропускную способность, используемую на операции чтения и на выполнение запросов.

    Размер страницы также можно изменить с помощью метода setPageSize.

Политика индексирования

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

    Политика индексирования Azure Cosmos DB позволяет указать пути к документам для включения или исключения из индексирования с помощью путей индексирования (setIncludedPaths и setExcludedPaths). Возможность управления путями индексирования позволяет оптимизировать производительность записи и снизить затраты на хранение индекса для сценариев с заранее определенными шаблонами запросов. Это связано с тем, что затраты на индексирование непосредственно зависят от количества уникальных путей индексирования. Например, следующий код показывает, как исключить из индексации весь раздел документов (поддерево) с помощью символа подстановки "*".

    Пакет SDK для синхронизации Java V2 (Maven com.microsoft.azure::azure-documentdb)

    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.

Пропускная способность

  1. Измерение и настройка расхода единиц запроса/повторного использования

    Azure Cosmos DB предоставляет обширный набор операций с документами в коллекции базы данных, в том числе реляционные и иерархические запросы с использованием UDF, хранимых процедур и триггеров. Затраты, связанные с каждой из этих операций, зависят от типа процессора, операций ввода-вывода и памяти, необходимой для завершения операции. Вместо того чтобы думать о закупке и управлении аппаратными ресурсами, вы можете думать о единице запроса (RU) как единой меры для ресурсов, необходимых для выполнения различных операций с базами данных и обслуживания запросов приложений.

    Пропускная способность выделяется на основе количества единиц запроса, заданного для каждого контейнера. Удельный расход единиц запросов оценивается в расчете на одну секунду. Частота запросов для приложений, у которых она превышает подготовленные единицы запросов для контейнера, будет ограничена, пока она не упадет ниже зарезервированного для контейнера уровня. Если приложению требуется более высокий уровень пропускной способности, можно увеличить ее путем выделения дополнительных единиц запросов.

    Сложность запроса влияет на количество единиц запроса, потребляемых операцией. Количество предикатов и их характер, количество определяемых пользователем функций и размер набора исходных данных — все это влияет на плату за операции запроса.

    Чтобы оценить расходы на любую операцию (создание, обновление или удаление), проверьте значение заголовка x-ms-request-charge (или аналогичного свойства RequestCharge на вкладке ResourceResponse<T> или FeedResponse<T>). Это значение содержит число единиц запроса, потребляемых соответствующей операцией.

    Пакет SDK синхронизации для Java версии 2 (Maven com.microsoft.azure::azure-documentdb)

    ResourceResponse<Document> response = client.createDocument(collectionLink, documentDefinition, null, false);
    
    response.getRequestCharge();
    

    Стоимость запроса, указанная в этом заголовке, учитывается как часть подготовленной пропускной способности. Например, если у вас подготовлено 2000 ЕЗ/с, а если предыдущий запрос возвращает 1000 1 КБ-документов, стоимость операции составляет 1000. Таким образом, перед ограничением частоты выполнения последующих запросов сервер за одну секунду выполняет только два таких запроса. Чтобы узнать больше, ознакомьтесь с единицами запроса и калькулятором единиц запроса.

  2. Управление ограничением скорости или слишком высокой частотой запросов

    Выполнение запроса, который превышает лимит зарезервированной пропускной способности для учетной записи, не приводит к снижению производительности сервера, так как пользователь не сможет превысить это зарезервированное значение. Сервер досрочно завершит запрос с состоянием 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. Число повторных попыток по умолчанию можно переопределить в свойстве RetryOptions экземпляра ConnectionPolicy. По умолчанию, если запрос продолжает превышать установленный лимит скорости запросов, DocumentClientException с кодом состояния 429 возвращается после совокупного времени ожидания в 30 секунд. Это происходит, даже если текущее значение количества повторных попыток (по умолчанию (9) или определенное пользователем) меньше максимального значения.

    Хотя автоматическая процедура повторной попытки помогает улучшить устойчивость и удобство использования большинства приложений, она может привести к противоречиям при выполнении тестов производительности, особенно при измерении задержки. Если эксперимент столкнется с ограничением сервера и заставит клиентский SDK беззвучно повторить попытку, это приведет к резкому увеличению задержки, наблюдаемой клиентом. Чтобы избежать пиков задержек во время экспериментов с производительностью, измеряйте заряд, возвращаемый каждой операцией, и убедитесь, что запросы выполняются ниже уровня зарезервированной скорости запросов. Для получения дополнительной информации см. Единицы запросов.

  3. Использование меньших документов для более высокой пропускной способности

    Стоимость запроса (плата за обработку запроса) для каждой операции напрямую зависит от размера документа. Операции с большими документами обходятся дороже, чем операции с маленькими документами.

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

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