Google advertiser api开发概述——批量处理
批处理
大多数服务都提供同步 API,要求您发出请求然后等待响应,但 BatchJobService 允许您对多项服务执行批量操作,而无需等待操作完成。
与各服务的特定 mutate 操作不同,BatchJobService 中的单个作业可以处理由广告系列、广告组、广告、条件、标签和 Feed 项组成的混合集合。已提交的作业会并行运行,且 BatchJobService 会自动重试由于 RateExceededError
等瞬态错误而失败的操作。
此外,BatchJobService 允许您在请求中使用临时 ID,以便可以在单个作业中提交非独立操作。
BatchJobService 并不是适合所有情况的解决方案。使用 BatchJobService 可以减少发送的请求数量,但必须要评估它的使用情况,以确定它是否适合您的需求。
使用批处理的主要原因是尽量减少 API 请求的数量和重试由于瞬态错误而失败的操作的次数。这并不能保证性能得到提升,从而提高吞吐量或加快作业完成的速度。
您需要尝试不同的批处理和非批处理组合,以便确定适合您情况的最佳解决方案。
支持的操作
BatchJobService 支持以下操作:
架构
虽然每个客户端库都包含相应的实用工具,用于处理已上传操作的 XML 序列化和已下载结果的 XML 反序列化,但以下链接提供了关于批量作业请求与响应的完整架构:
https://adwords.google.com/api/adwords/cm/v201802/BatchJobOpsService?wsdl
注意:https://adwords.google.com/api/adwords/cm/v201802/BatchJobOpsService 不代表实际的服务端点,它仅提供 BatchJobOpsService 的架构。
批量作业流程
使用批量作业的步骤如下:
- 创建
BatchJob
,然后从mutate()
响应中获取uploadUrl
。 - 将您想要执行的操作列表上传到
uploadUrl
。 - 定期轮询批量作业的
status
,直到状态变为CANCELED
或DONE
。 - 从作业的
downloadUrl
下载作业结果,并检查是否存在processingErrors
。
此外,您可以取消状态为 AWAITING_FILE
或 ACTIVE
的 BatchJob
,方法是将其 status
设为 CANCELING
。
创建批量作业
创建批量作业的方法是发送 ADD
操作,其中包含新的 BatchJob
对象。
此时,作业的 status
会是 AWAITING_FILE
。
为批量作业创建操作
在这一步,您为批量作业创建操作的方式与您使用同步 API 服务的方式相同。例如,以下代码段创建了 CampaignOperation
对象,用于添加新的广告系列。
如果您要创建非独立对象(例如一个包含新广告系列和相应广告组、广告及关键字的完整广告系列),那么您可以在 ADD
操作中使用临时 ID。
重要提示:您的操作顺序会对作业的效率产生重大影响。有关详细信息,请参阅下文最佳做法部分中有关操作顺序的提示。
将操作上传到上传网址
在您收集完作业的操作组合后,下一步就是将它们发送到上传网址。
注意:批量作业的 uploadUrl
在作业创建后的一周内有效。
如果您使用某个客户端库中的实用工具,则无需操心所有的底层细节。实用工具会为您构建并发送请求,并且为以下两种选择都提供了方法:
- 一次性上传所有操作。
- 通过多次调用实用工具来上传操作。
轮询批量作业状态
在您上传完操作后,系统会将批量作业提交到作业队列,因此您需要定期检查作业状态,直到状态变为 CANCELED
或 DONE
。可使用指数退避策略来避免过于频繁的轮询。以下代码段将在首次尝试后等待 30 秒,在第二次尝试后等待 60 秒,在第三次尝试后等待 120 秒,以此类推。
提示:如果您想要跟踪大量操作的进度,可以记录在作业运行期间返回的 progressStats
。
下载批量作业结果和检查是否存在错误
在这个阶段,您的作业应该处于以下两种状态之一。
状态 | 说明 | 要采取的行动 |
---|---|---|
DONE |
BatchJobService 已成功解析并尝试了每一项上传的操作。 |
|
CANCELED |
作业已按照要求取消,BatchJobService 无法解析已上传的操作,或者在作业执行期间出现意外错误。 注意:在这种情况下,系统可能已经尝试了部分操作,因此,即便作业的最终状态是 CANCELED ,也最好在 downloadUrl 中查看一下结果。 |
|
对于每个已上传的操作,下载网址将返回一个 mutateResult
元素。每个结果都具有在 BatchJobOpsService.wsdl 中定义的以下属性:
属性 | 类型 | 说明 |
---|---|---|
result |
Operand |
如果操作成功,结果中有且只有以下子元素之一:
index 所代表的操作的类型。例如,如果该操作是一个成功的 CampaignOperation ,则会在此处返回一个 Campaign 元素。 |
errorList |
ErrorList |
如果操作失败,则包含一个或多个 errors 元素,每个元素都是 ApiError 或它的某个子类的实例。 |
index |
long |
从 0 开始的操作编号。此编号用来将结果与您上传的相应操作进行关联。 |
注意:mutateResult
将收到 result
或 errorList
,但不会同时收到两者。
批量作业的 processingErrors
将包含在预处理您上传的操作时发生的所有错误,比如输入文件损坏错误。
注意:processingErrors
属性不会包含在该服务尝试执行已成功解析的操作时发生的错误,这些错误将显示在从下载网址提取而来的 mutateResult
中。
使用临时 ID
BatchJobService 的一个强大功能是它支持使用临时 ID。临时 ID 是一个负数 (long
),让批量作业中的操作可以引用同一批量作业中的上一个操作的 ADD
操作结果。只需在 ADD
操作中指定父对象的负数 ID,然后就可以在后续的 mutate()
操作中将该 ID 重复用于同一批量作业中的其他非独立对象。
临时 ID 的一种常见使用情形是在单个批量作业中制作完整广告系列。例如,您可以创建一个包含 ADD
操作的作业,并为每个 operand
指定以下 ID:
顺序如下:
- 添加一个(临时)ID 为
-1
的广告系列- 为广告系列
-1
添加一个临时 ID 为-2
的广告组- 为广告组
-2
添加一个广告组广告 - 为广告组
-2
添加多个广告组条件(关键字)
- 为广告组
- 为广告系列
- 向广告系列
-1
应用一个标签 - 为广告系列
-1
添加一个广告系列否定条件(关键字)
注意:非独立操作按照它们出现在您上传的操作中的次序来应用。
因此,在使用临时 ID 时,请确保创建父对象的操作早于创建其子对象的操作。
创建新对象时使用新的临时 ID。如果您没有这样做,则将收到 TaskExecutionError.TEMP_ID_ALREADY_USED
错误。
取消批量作业
如果 BatchJob
的 status
是 AWAITING_FILE
或 ACTIVE
,则可以取消。只需发出 BatchJobService.mutate()
请求并传递具有以下属性的 BatchJobOperation
即可:
如果 BatchJob
的 status
在上述请求发出时既不是 AWAITING_FILE
,也不是 ACTIVE
,请求将会失败,且返回一个 BatchJobError.INVALID_STATE_CHANGE
错误。
取消作业是一个异步操作,因此在您发出 mutate()
请求后,请轮询批量作业状态,直到状态变为 CANCELED
或 DONE
。
并且,请您务必下载结果和检查错误,因为在作业被取消之前,系统可能已经尝试执行作业中的部分操作。
上传要求
非增量上传
每个客户端库实用工具都提供了一步完成上传操作的便捷方法。但是,如果您未使用客户端库,请注意,非增量上传将不受支持。
增量上传
使用增量上传,您可以将多个上传请求发送给批量作业 uploadUrl
。该作业只会在您上传完最后一组操作后开始执行。
将 BatchJob uploadURL 更换为断点续传网址
上传过程遵循使用 XML API 实现断点续传的 Google Cloud Storage 准则。
您的 BatchJob
的 uploadUrl
必须换成支持断点续传的上传网址。
要将您的 uploadUrl
换成支持断点续传的上传网址,请向 uploadUrl
发送符合以下规范的请求:
请求属性 | |
---|---|
请求方法 | POST |
网址 | BatchJobService.mutate 返回的上传网址 |
Content-Type HTTP 标头 |
application/xml |
Content-Length HTTP 标头 |
0 |
x-goog-resumable HTTP 标头 |
start |
请求正文 | 不需要请求正文 |
如果请求成功,则返回的响应状态为 201 Created
,并且包含一个 Location
标头,其中的值就是断点续传网址。
将操作上传到断点续传网址
有了断点续传网址后,您就可以开始上传操作了。发送到断点续传网址的每个请求都必须符合以下规范。
请求属性 | |
---|---|
请求方法 | PUT |
网址 | 在上述初始化步骤中获得的断点续传网址。 |
Content-Type HTTP 标头 |
application/xml |
Content-Length HTTP 标头 |
当前请求内容的字节数。 |
Content-Range HTTP 标头 |
请求的字节数范围,后跟总字节数。对于第一个请求和中间请求,总字节数为“
* ”,但是在发送最后一个请求时,应该将总字节数设置为最终的总字节数。示例:
bytes 0-262143/* bytes 262144-524287/* bytes 524288-786431/786432 |
请求正文 |
在 BatchJobOpsService.wsdl 中指定的 XML 格式的操作。
请求正文的大小必须是 256K (262144) 字节的倍数。
|
断点续传网址的请求正文
BatchJobService 最终会将所有已上传的 XML 都连接到 uploadUrl
,并将其作为单个请求来解析,因此您必须要注意只在第一个请求和最后一个请求分别包含开始和结束的 mutate
元素。
请求 | 开始的 mutate 元素 | 结束的 mutate 元素 |
---|---|---|
第一个 | ||
中间 | ||
最后一个 |
此外,由于 BatchJobService 会将已上传的 XML 作为单个文档来解析,因此单个请求的请求正文无需包含完整的 XML 文档。例如,如果您上传 524305 字节 (256K + 256K + 17),您的请求可能如下所示:
请求 1
<?xml version="1.0" encoding="UTF-8"?> <ns1:mutate xmlns:ns1="https://adwords.google.com/api/adwords/cm/v201802"> <operations xsi:type="ns1:CampaignOperation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <operator xsi:type="ns1:Operator">ADD</operator> <operand xsi:type="ns1:Campaign"> ... </operations> <operations> ... </operat
内容长度为 262144,最后一行中的“t
”是第 262144 个字节。
请求 2
ions> <operations xsi:type="ns1:AdGroupOperation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <operator xsi:type="ns1:Operator">ADD</operator> <operand xsi:type="ns1:AdGroup"> ... </operations> <operations> ... </ope
内容长度为 262144,最后一行中的“e
”是第 262144 个字节。
请求 3
rations></mutate> ... (padded to 262144 bytes)
没有填充的内容长度为 17 字节,</mutate>
上的收尾 >
为第 17 个字节。填充后的内容总长度为 262144 字节。
最佳做法
在使用 BatchJobService 时请参考以下准则:
- 要提高总处理能力,执行少量的大作业比执行大量的小作业要好。
- 在提交同一 clientCustomerId 的多个并行作业时,尽量降低针对相同对象同时执行多个作业的可能性,同时保持大型作业的规模。如果针对同一组对象执行 mutate 操作的未完成作业(状态为
ACTIVE
或CANCELING
)过多,可能会出现死锁的情况,导致系统速度严重降低,甚至造成作业失败。 - 请勿提交在同一作业中对同一对象执行 mutate 操作的多个操作。如果您这样做,结果可能无法预测。
- 为了提高吞吐量,请按操作类型对上传操作进行排序。例如,如果您的作业包含添加广告系列、广告组和广告组条件的操作,请在上传中对操作进行排序,使所有
CampaignOperations
排在最前,后跟所有AdGroupOperations
,最后是所有AdGroupCriterionOperations
。 - 不要过于频繁地轮询作业状态,否则可能发生速率限制错误。
使用购物广告系列
使用 BatchJobService 更新产品划分树时,应遵循以下限制:
-
如果对产品划分树执行的操作列表会导致产品划分树结构无效(例如,在没有创建其他节点的情况下对节点进行了细分),则对该产品划分树执行的整个操作列表将失败。
-
不会对产品划分树进行结构性更改(例如对现有节点进行出价更改)的操作是独立执行的。
-
BatchJob
可以包含为两个以上的广告组引入产品划分树结构更改的操作。两个广告组的限制不适用于批量作业。 -
移除产品划分节点时,请将
AdGroupCriterion
对象的criterion
字段设置为ProductPartition
实例。将此字段设置为Criterion
实例会导致操作失败,并出现AdGroupCriterionError.CONCRETE_TYPE_REQUIRED
错误。
限制
-
在任意给定时间,一个 AdWords 帐号中所有未完成的批量作业中的已上传操作最多不能超过 1 GB。一旦您的帐号达到此限制,当您尝试添加新的批量作业时,系统将提示原因为
DISK_QUOTA_EXCEEDED
的BatchJobError
。如果出现此错误,请耐心等待,直到待完成的已上传操作规模下降到限额以下,然后再创建新的作业。 -
测试帐号每天处理的新作业不超过 250 个。
-
批量作业在创建后保留 60 天。之后,将无法通过
get()
或query()
请求获取它们。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· 面试官:你是如何进行SQL调优的?