使用 BatchJobService 时,请遵循以下准则。
提高吞吐量
少量的大型作业优于大量的小型作业。
按操作类型对上传的操作进行排序(必须在原子子批次中连续分组的相互依赖的操作除外)。例如,如果您的作业包含添加标准广告系列、广告组和广告组条件的操作,请在上传时对这些操作进行排序,使所有广告系列操作排在最前面,然后是所有广告组操作,最后是所有广告组条件操作。
在同一类型的操作中,按父级资源对操作进行分组可以提高性能。例如,如果您有一系列
AdGroupCriterionOperation对象,那么按广告组对操作进行分组,而不是将影响不同广告组中广告组条件的操作混在一起,会更有效率。
批处理拆分中的原子性
Google Ads API 会将提交的批量作业中的操作拆分为较小的子批次进行处理。虽然标准子批处理在启用部分失败的情况下执行,但某些相互依赖的操作的子批处理会作为单个事务以原子方式处理:
- 针对同一
AdGroup的LISTING_GROUP条件 (AdGroupCriterion.listing_group) 的连续AdGroupCriterionOperation操作(create、update和remove)(如果该组中的任何操作失败,则会失败并显示CriterionError.LISTING_GROUP_ERROR_IN_ANOTHER_OPERATION)。 - 针对同一
AssetGroup的连续AssetGroupListingGroupFilterOperation操作(create、update和remove)(如果组中的任何操作失败,则失败并显示BatchJobError.ASSET_GROUP_LISTING_GROUP_FILTER_TRANSACTION_FAILURE)。 - 一个
AssetGroupOperation(create) 后面紧跟最多 999 个针对同一AssetGroup的AssetGroupAssetOperation(create) 操作(如果组中的任何操作失败,则失败并显示BatchJobError.ASSET_GROUP_AND_ASSET_GROUP_ASSET_TRANSACTION_FAILURE)。每个AssetGroupOperation(update或remove)都在其自己的独立单操作子批次中执行。 - 一个启用了品牌规范(
brand_guidelines_enabled设置为true或未设置,因为除非您明确将其设置为false或制作指定旅行目标的效果最大化广告系列,否则默认设置为true)的效果最大化广告系列CampaignOperation(create),后跟最多 999 个针对同一Campaign的CampaignAssetOperation(create) 操作(如果该组中的任何操作失败,则会失败并显示BatchJobError.CAMPAIGN_AND_CAMPAIGN_ASSET_TRANSACTION_FAILURE)。本地生活服务效果最大化广告系列不支持品牌规范,并会忽略品牌CampaignAsset资源(在制作广告系列时,将brand_guidelines_enabled设置为false)。仅当您制作不含自定义AssetGroupAsset资源(HTML5MEDIA_BUNDLE素材资源除外)的无素材资源广告系列时,或者当brand_guidelines_enabled设置为false时,零售效果最大化广告系列(具有 Merchant Center Feed)才能在同一原子子批次中省略品牌CampaignAsset资源。
对于 AssetGroup 和效果最大化广告系列 Campaign 创建子批次(每个子批次总共最多 1,000 项操作;超过 999 项的任何子 create 操作都会溢出到下一个非原子子批次):
- 父级
create操作(AssetGroup或Campaign上的resource_name)及其连续的子级create操作(AssetGroupAsset上的asset_group或CampaignAsset上的campaign)必须指定相同的负临时 ID。 - 将新
Asset资源的所有前提条件AssetOperation(create) 操作放在父级AssetGroupOperation或CampaignOperation(create) 之前,切勿放在父级create及其子级关联create操作之间(这会立即关闭原子子批处理,并将父级资源创建与其关联的素材资源分开)。
当原子子批处理失败时,违规操作的 BatchJobResult.status 包含底层验证错误,而该子批处理中的其余操作会回滚,并显示该子批处理的相应事务错误。检查共享相同 AdGroup、AssetGroup 或 Campaign ID 的相邻 BatchJobResult 条目,以找出根本原因错误。
如果这些组中的相关操作未连续添加,Google Ads API 会将其拆分到不同的子批次中,导致修改不符合最低素材资源要求或导致产品信息组树不完整。如需了解详情,请参阅在批量作业中使用产品信息组过滤条件和效果最大化广告系列批处理。
逻辑分组
当您修改产品定位层次结构(效果最大化广告系列中的 AssetGroupListingGroupFilterOperation 或购物广告系列中的 AdGroupCriterionOperation)或创建新的 AssetGroup 或效果最大化广告系列 Campaign 时,请将定位到同一父级资源(AssetGroup、AdGroup 或 Campaign)的所有操作连续分组。这样可以减少后端锁争用,并使相互依赖的树保持在一起。
数据一致性
由于系统会在每个原子子批处理事务结束时验证产品信息组过滤条件树和效果最大化广告系列素材资源要求,因此请避免在作业中的不连续范围内或并发作业中拆分对同一父级资源的更新。
避免并发问题
为同一账号提交多个并发作业时,请降低作业同时对同一对象执行操作的可能性,同时保持较大的作业规模。许多状态为
RUNNING的未完成作业尝试更改同一组对象,这可能会导致类似死锁的情况,从而导致严重的速度下降,甚至作业失败。请勿在同一作业中提交多个会改变同一对象的操作,因为结果可能无法预测。
以最佳方式检索结果
请勿过于频繁地轮询作业状态,否则可能会遇到速率限制错误。
调用
ListBatchJobResults时,请将page_size留空(或将其设置为最大值1000),以最大限度地减少分页往返次数;仅当您的应用检查resource_name之外的返回资源字段时,才将response_content_type设置为MUTABLE_RESOURCE。结果顺序与上传顺序相同。
其他使用指南
您可以为批量作业设置一个大致的运行时间上限,超过该上限后作业会被取消。创建新的批量作业时,请将
metadata.execution_limit_seconds字段设置为一个正整数,表示您偏好的时间限制(以秒为单位)。如果未设置metadata.execution_limit_seconds,则没有默认时间限制。虽然协议限制为每个请求 10,000 项操作,但我们建议每个
AddBatchJobOperationsRequest添加的操作不超过 1,000 项,并使用sequence_token将其余操作上传到同一作业。根据操作的大小,在单个AddBatchJobOperationsRequest中发送过多操作可能会导致BatchJobError.REQUEST_TOO_LARGE错误。您可以通过减少操作数量并重试AddBatchJobOperationsRequest来处理此错误。
限制
每个
BatchJob最多支持 100 万次操作。如果您在调用AddBatchJobOperations时超出此限制,系统会返回ResourceCountLimitExceededError.RESOURCE_LIMIT错误(ErrorDetails.resource_count_details中包含ResourceLimitType.BATCH_JOB_OPERATIONS_PER_JOB)。每个账号最多可以同时有 100 个有效或待处理的作业。 如果您在使用
MutateBatchJob创建批量作业时超出此限制,系统会返回ResourceCountLimitExceededError.RESOURCE_LIMIT错误(ErrorDetails.resource_count_details中包含ResourceLimitType.BATCH_JOBS_PER_CUSTOMER)。系统会自动移除保留时长超过 7 天的待处理作业。
每个
AddBatchJobOperationsRequest的硬性限制为每个请求 10,000 个 mutate 操作。如果单个请求中的操作数超过 10,000,则会返回BatchJobError.REQUEST_TOO_LARGE错误。对于
ListBatchJobResultsRequest中的page_size字段:- 如果未设置
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));
单次 mutate 操作的大小
虽然整个请求的大小上限为 41,937,920 字节,但批处理中单个 MutateOperation 的序列化大小上限为 10,484,504 字节(10 MiB 减去 1,256 字节)。如果超出此限制,则系统会返回 BatchJobError.REQUEST_TOO_LARGE 错误。请注意,虽然 BatchJobError.REQUEST_TOO_LARGE 的参考文档引用了 10,484,504 字节阈值,但当超出三个请求阈值(总请求字节数为 41,937,920、单次操作字节数为 10,484,504 或每次调用 10,000 次操作)中的任何一个时,AddBatchJobOperations 都会返回此错误代码,并且错误的 message 字段会指定违反了哪个限制。