Рекомендации и ограничения

При использовании BatchJobService учитывайте следующие рекомендации:

Улучшение пропускной способности

  • Лучше использовать несколько крупных заданий, чем много мелких.

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

  • Для повышения эффективности операции одного типа можно сгруппировать по родительскому ресурсу. Например, если у вас есть несколько объектов AdGroupCriterionOperation, эффективнее будет сгруппировать операции по группам объявлений, а не смешивать операции, которые влияют на критерии в разных группах объявлений.

Атомарность при разделении пакетов

Google Ads API разбивает операции в отправленном пакетном задании на более мелкие подпакеты для обработки. Стандартные подпакеты выполняются с включенной частичной ошибкой, а подпакеты для определенных взаимозависимых операций обрабатываются атомарно как одна транзакция:

Для AssetGroup и кампаний с максимальной эффективностью Campaign создаются подпакеты (до 1000 операций в каждом; все дочерние операции create, начиная с 1000-й, переносятся в следующий неатомарный подпакет):

  • Родительская операция create (resource_name в AssetGroup или Campaign) и ее последовательные дочерние операции create (asset_group в AssetGroupAsset или campaign в CampaignAsset) должны иметь один и тот же отрицательный временный идентификатор.
  • Перед родительскими операциями AssetGroupOperation или CampaignOperation (create) разместите все необходимые операции AssetOperation (create) для новых ресурсов Asset. Не размещайте их между родительскими операциями create и операциями связывания дочерних ресурсов create, иначе атомарный подпакет будет сразу закрыт, а создание родительского ресурса будет отделено от связанных с ним объектов.

Если атомарный подпакет не выполняется, то в поле BatchJobResult.status для операции, вызвавшей ошибку, указывается ошибка проверки, а остальные операции в этом подпакете отменяются с соответствующей ошибкой транзакции. Проверьте соседние записи BatchJobResult с тем же идентификатором AdGroup, AssetGroup или Campaign, чтобы определить основную причину ошибки.

Если связанные операции в любой из этих групп не добавляются последовательно, Google Ads API разделяет их на отдельные подпакеты, в результате чего модификация не соответствует минимальным требованиям к объектам или оставляет деревья групп предложений неполными. Подробную информацию вы найдете в статьях Использование фильтров групп товаров в пакетных заданиях и Пакетная обработка в кампаниях с максимальной эффективностью.

Логическая группировка

Если вы изменяете иерархию таргетинга на товары (AssetGroupListingGroupFilterOperation в кампаниях с максимальной эффективностью или AdGroupCriterionOperation в торговых кампаниях) или создаете новую группу товаров (AssetGroup) или группу объектов для кампании с максимальной эффективностью (Campaign), сгруппируйте все операции, направленные на один и тот же родительский ресурс (AssetGroup, AdGroup или Campaign), последовательно. Это снижает конкуренцию за блокировку на сервере и позволяет хранить взаимозависимые деревья вместе.

Согласованность данных

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

Как избежать проблем с параллельным выполнением

  • Если вы отправляете несколько заданий одновременно для одного аккаунта, снизьте вероятность того, что они будут работать с одними и теми же объектами в одно и то же время, сохраняя при этом большие размеры заданий. Если у вас много незавершенных заданий со статусом RUNNING, которые пытаются изменить один и тот же набор объектов, это может привести к взаимоблокировке, что значительно замедлит работу и даже может вызвать сбои.

  • Не отправляйте несколько операций, изменяющих один и тот же объект в одном задании, так как результат может быть непредсказуемым.

Оптимальное получение результатов

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

  • При вызове ListBatchJobResults не задавайте значение page_size (или задайте максимальное значение 1000), чтобы минимизировать количество запросов на разбиение по страницам. Задавайте для response_content_type значение MUTABLE_RESOURCE, только если ваше приложение проверяет возвращенные поля ресурсов, кроме resource_name.

  • Результаты будут представлены в том же порядке, в котором вы загрузили файлы.

Дополнительные рекомендации по использованию

  • Вы можете задать приблизительную верхнюю границу времени, в течение которого пакетное задание может выполняться до отмены. При создании нового пакетного задания задайте в поле metadata.execution_limit_seconds положительное целое число, соответствующее желаемому ограничению по времени в секундах. Если параметр metadata.execution_limit_seconds не задан, ограничение по времени по умолчанию не применяется.

  • Хотя протокол позволяет выполнять до 10 000 операций за запрос, мы рекомендуем добавлять не более 1000 операций на AddBatchJobOperationsRequest и использовать sequence_token для загрузки остальных операций в то же задание. Если в одном запросе AddBatchJobOperationsRequest отправлено слишком много операций, может возникнуть ошибка BatchJobError.REQUEST_TOO_LARGE. Чтобы устранить эту ошибку, уменьшите количество операций и повторите AddBatchJobOperationsRequest.

Ограничения

  • Каждый объект BatchJob поддерживает до миллиона операций. Если вы превысите это ограничение при вызове AddBatchJobOperations, то получите ошибку ResourceCountLimitExceededError.RESOURCE_LIMIT (с ResourceLimitType.BATCH_JOB_OPERATIONS_PER_JOB в ErrorDetails.resource_count_details).

  • В каждом аккаунте может быть не более 100 активных или ожидающих заданий одновременно. Если при создании пакетного задания с помощью MutateBatchJob вы превысите это ограничение, то получите ошибку ResourceCountLimitExceededError.RESOURCE_LIMIT (с ResourceLimitType.BATCH_JOBS_PER_CUSTOMER в ErrorDetails.resource_count_details).

  • Ожидающие задания старше семи дней удаляются автоматически.

  • Для каждого AddBatchJobOperationsRequest установлено ограничение в 10 000 операций изменения на запрос. Если в одном запросе будет больше 10 000 операций,возвращается ошибка BatchJobError.REQUEST_TOO_LARGE.

  • Для поля page_size в ListBatchJobResultsRequest:

    • Если параметр page_size не задан или имеет значение 0, по умолчанию используется максимальное значение 1000.
    • Если значение page_size превышает 1000 или меньше 0, API возвращает ошибку BatchJobError.INVALID_PAGE_SIZE.
  • Максимальный размер каждого файла AddBatchJobOperationsRequest составляет 41 937 920 байт. Если вы превысите это ограничение, то получите сообщение об ошибке BatchJobError.REQUEST_TOO_LARGE (или INTERNAL_ERROR, если отклонение произошло на транспортном уровне). Вы можете определить сериализованный размер запроса перед отправкой и принять соответствующие меры, если он слишком велик:

    Java

    
    static final int MAX_REQUEST_BYTES = 41_937_920;
    
    // ... (code to get the AddBatchJobOperationsRequest object)
    
    int sizeInBytes = request.getSerializedSize();
    

    C#

    
    const int MAX_REQUEST_BYTES = 41_937_920;
    
    // ... (code to get the AddBatchJobOperationsRequest object)
    
    int sizeInBytes = request.CalculateSize();
    

    PHP

    
    const MAX_REQUEST_BYTES = 41937920;
    
    // ... (code to get the AddBatchJobOperationsRequest object)
    
    $size_in_bytes = $request->byteSize();
    

    Python

    
    MAX_REQUEST_BYTES = 41_937_920
    
    # ... (code to get the AddBatchJobOperationsRequest object)
    
    # Supports both proto-plus (use_proto_plus=True) and native protobuf
    # (use_proto_plus=False) messages.
    pb = type(request).pb(request) if hasattr(type(request), "pb") else request
    size_in_bytes = pb.ByteSize()
    

    Ruby

    
    MAX_REQUEST_BYTES = 41_937_920
    
    # ... (code to get the AddBatchJobOperationsRequest object)
    
    size_in_bytes = request.to_proto.bytesize
    

    Perl

    
    use JSON::XS;
    use constant MAX_REQUEST_BYTES => 41937920;
    
    # ... (code to get the AddBatchJobOperationsRequest object)
    
    # The Perl client library uses REST/JSON; UTF-8 JSON byte length provides a
    # conservative upper-bound estimate of the serialized request size.
    my $json_encoder = JSON::XS->new->utf8->convert_blessed;
    my $size_in_bytes = length($json_encoder->encode($request));
    

Размер одной операции изменения

Хотя общий размер запроса может составлять до 41 937 920 байт, сериализованный размер одного объекта MutateOperation в пакете не может превышать 10 484 504 байт (10 МиБ минус 1256 байт). Если вы превысите это ограничение, то получите ошибку BatchJobError.REQUEST_TOO_LARGE. Обратите внимание, что хотя в справочной документации по BatchJobError.REQUEST_TOO_LARGE указано пороговое значение 10 484 504 байта, AddBatchJobOperations возвращает тот же код ошибки, когда превышено любое из трех пороговых значений запроса (41 937 920 байт для всего запроса, 10 484 504 байта для одной операции или 10 000 операций на вызов). При этом в поле message ошибки указывается, какое ограничение было нарушено.