При использовании BatchJobService учитывайте следующие рекомендации:
Улучшение пропускной способности
Лучше использовать несколько крупных заданий, чем много мелких.
Упорядочивайте загружаемые операции по типу (за исключением взаимозависимых операций, которые должны быть последовательно сгруппированы в атомарные подпакеты). Например, если задание содержит операции по добавлению стандартных кампаний, групп объявлений и критериев групп объявлений, упорядочите операции в загружаемом файле так, чтобы сначала шли все операции кампании, затем все операции группы объявлений и, наконец, все операции критерия группы объявлений.
Для повышения эффективности операции одного типа можно сгруппировать по родительскому ресурсу. Например, если у вас есть несколько объектов
AdGroupCriterionOperation, эффективнее будет сгруппировать операции по группам объявлений, а не смешивать операции, которые влияют на критерии в разных группах объявлений.
Атомарность при разделении пакетов
Google Ads API разбивает операции в отправленном пакетном задании на более мелкие подпакеты для обработки. Стандартные подпакеты выполняются с включенной частичной ошибкой, а подпакеты для определенных взаимозависимых операций обрабатываются атомарно как одна транзакция:
- Последовательные операции
AdGroupCriterionOperation(create,updateиremove) для критериевLISTING_GROUP(AdGroupCriterion.listing_group) с таргетингом на один и тот же объектAdGroup. Если любая операция в группе не будет выполнена, произойдет ошибкаCriterionError.LISTING_GROUP_ERROR_IN_ANOTHER_OPERATION. - Последовательные операции
AssetGroupListingGroupFilterOperation(create,updateиremove) с таргетингом на один и тот же объектAssetGroup(если любая операция в группе завершается ошибкой, возвращается ошибкаBatchJobError.ASSET_GROUP_LISTING_GROUP_FILTER_TRANSACTION_FAILURE). - За операцией
AssetGroupOperation(create) сразу же следует до 999 операцийAssetGroupAssetOperation(create), нацеленных на один и тот же объектAssetGroup(если любая операция в группе завершается ошибкой, то возвращается ошибкаBatchJobError.ASSET_GROUP_AND_ASSET_GROUP_ASSET_TRANSACTION_FAILURE). Каждый запросAssetGroupOperation(updateилиremove) выполняется в отдельном пакете, содержащем одну операцию. CampaignOperation(create) кампании с максимальной эффективностью с включенными правилами фирменного оформления (дляbrand_guidelines_enabledзадано значениеtrueили не задано никакое значение, поскольку по умолчанию используетсяtrue, если вы не задалиfalseили не создали кампанию с максимальной эффективностью для целей туризма), за которой сразу следует до 999 операцийCampaignAssetOperation(create) с таргетингом на ту жеCampaign(если любая операция в группе завершается ошибкой, возвращаетсяBatchJobError.CAMPAIGN_AND_CAMPAIGN_ASSET_TRANSACTION_FAILURE). Кампании с максимальной эффективностью для местных услуг не поддерживают правила фирменного оформления и не используют ресурсы брендаCampaignAsset(при создании кампании задайте дляbrand_guidelines_enabledзначениеfalse). В кампаниях с максимальной эффективностью для розничной торговли (с фидом Merchant Center) можно не указывать ресурсыCampaignAssetбренда в одном атомарном подпакете, только если вы создаете кампанию без объектов и без пользовательских ресурсовAssetGroupAsset(кроме объектовMEDIA_BUNDLEHTML5) или если дляbrand_guidelines_enabledзадано значениеfalse.
Для 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.bytesizePerl
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 ошибки указывается, какое ограничение было нарушено.