バッチ処理

ほとんどのサービスが提供する API は同期的であるため、リクエストを送信した後にレスポンスを待つ必要がありますが、BatchJobService を使えば複数のサービスでオペレーションの完了を待たずにバッチ処理を実行できます。

サービス固有の mutate オペレーションとは異なり、BatchJobService では 1 つのジョブによりキャンペーン、広告グループ、広告、条件、ラベル、フィード アイテムの組み合わせを操作できます。複数のジョブを送信した場合は並列実行され、RateExceededError などの一時的なエラーで失敗したオペレーションは BatchJobService によって自動的に再試行されます。

また、BatchJobService ではリクエストで一時 ID を使用できるので、依存関係のある複数のオペレーションを 1 つのジョブで送信することもできます。

対応しているオペレーション

BatchJobService は次のオペレーションに対応しています。

オペレーション 対応する同期サービス
AdGroupAdOperation
AdGroupAdLabelOperation
AdGroupAdService
AdGroupBidModifierOperation AdGroupBidModifierService
AdGroupCriterionOperation
AdGroupCriterionLabelOperation
AdGroupCriterionService
AdGroupExtensionSettingOperation AdGroupExtensionSettingService
AdGroupOperation
AdGroupLabelOperation
AdGroupService
BudgetOperation BudgetService
CampaignCriterionOperation CampaignCriterionService
CampaignExtensionSettingOperation CampaignExtensionSettingService
CampaignOperation
CampaignLabelOperation
CampaignService
CustomerExtensionSettingOperation CustomerExtensionSettingService
FeedItemOperation FeedItemService

スキーマ

クライアント ライブラリに、アップロードされたオペレーションの XML シリアル化とダウンロードされた結果の XML 逆シリアル化を処理するユーティリティが含まれています。また、バッチジョブのリクエストとレスポンスのスキーマ全体は次のサイトで入手できます。

https://adwords.google.com/api/adwords/cm/v201702/BatchJobOpsService?wsdl

バッチジョブのフロー

バッチジョブを使用するには:

  1. BatchJob を作成し、その uploadUrlmutate() レスポンスから取得します。
  2. 実行するオペレーションのリストを uploadUrl にアップロードします。
  3. バッチジョブの status を、CANCELED または DONE になるまで定期的に確認します。
  4. downloadUrl からジョブの結果をダウンロードし、processingErrors がないか確認します。

ステータスが AWAITING_FILE または ACTIVEBatchJob をキャンセルすることもできます。キャンセルするには statusCANCELING に設定します。

バッチジョブの作成

バッチジョブを作成するには、新しい BatchJob オブジェクトを含む ADD オペレーションを送信します。

// Create a BatchJob.
BatchJobOperation addOp = new BatchJobOperation();
addOp.setOperator(Operator.ADD);
addOp.setOperand(new BatchJob());

BatchJob batchJob = batchJobService.mutate(new BatchJobOperation[] {addOp}).getValue(0);

// Get the upload URL from the new job.
String uploadUrl = batchJob.getUploadUrl().getUrl();

System.out.printf("Created BatchJob with ID %d, status '%s' and upload URL %s.%n",
    batchJob.getId(), batchJob.getStatus(), uploadUrl);

この時点でジョブの statusAWAITING_FILE になります。

バッチジョブのオペレーションを作成する

この手順では、同期 API サービスで使用するのと同じアプローチでバッチジョブのオペレーションを作成します。たとえば、新しいキャンペーンを追加するための CampaignOperation オブジェクトを作成するには、次のスニペットを使用します。

List<CampaignOperation> operations = new ArrayList<>();
for (int i = 0; i < NUMBER_OF_CAMPAIGNS_TO_ADD; i++) {
  Campaign campaign = new Campaign();
  campaign.setName(String.format("Batch Campaign %s.%s", namePrefix, i));

  // Recommendation: Set the campaign to PAUSED when creating it to prevent
  // the ads from immediately serving. Set to ENABLED once you've added
  // targeting and the ads are ready to serve.
  campaign.setStatus(CampaignStatus.PAUSED);

  campaign.setId(tempIdGenerator.next());
  campaign.setAdvertisingChannelType(AdvertisingChannelType.SEARCH);
  Budget budget = new Budget();
  budget.setBudgetId(budgetId);
  campaign.setBudget(budget);
  BiddingStrategyConfiguration biddingStrategyConfiguration =
      new BiddingStrategyConfiguration();
  biddingStrategyConfiguration.setBiddingStrategyType(BiddingStrategyType.MANUAL_CPC);

  // You can optionally provide a bidding scheme in place of the type.
  ManualCpcBiddingScheme cpcBiddingScheme = new ManualCpcBiddingScheme();
  cpcBiddingScheme.setEnhancedCpcEnabled(false);
  biddingStrategyConfiguration.setBiddingScheme(cpcBiddingScheme);

  campaign.setBiddingStrategyConfiguration(biddingStrategyConfiguration);

  CampaignOperation operation = new CampaignOperation();
  operation.setOperand(campaign);
  operation.setOperator(Operator.ADD);
  operations.add(operation);
}
return operations;

新しいキャンペーンとそれに対応する広告グループ、広告、キーワードで構成された包括的なキャンペーンなど、依存関係のあるオブジェクトを作成する場合は、ADD オペレーションで一時 ID を使用できます。

// Create a temporary ID generator that will produce a sequence of descending negative numbers.
Iterator<Long> tempIdGenerator =
    new AbstractSequentialIterator<Long>(-1L) {
      @Override
      protected Long computeNext(Long previous) {
        return Long.MIN_VALUE == previous.longValue() ? null : previous - 1;
      }
    };

// Use a random UUID name prefix to avoid name collisions.
String namePrefix = UUID.randomUUID().toString();

// Create the mutate request that will be sent to the upload URL.
List<Operation> operations = new ArrayList<>();

// Create and add an operation to create a new budget.
BudgetOperation budgetOperation = buildBudgetOperation(tempIdGenerator, namePrefix);
operations.add(budgetOperation);

// Create and add operations to create new campaigns.
List<CampaignOperation> campaignOperations =
    buildCampaignOperations(tempIdGenerator, namePrefix, budgetOperation);
operations.addAll(campaignOperations);

// Create and add operations to create new negative keyword criteria for each campaign.
operations.addAll(buildCampaignCriterionOperations(campaignOperations));

// Create and add operations to create new ad groups.
List<AdGroupOperation> adGroupOperations =
    new ArrayList<>(buildAdGroupOperations(tempIdGenerator, namePrefix, campaignOperations));
operations.addAll(adGroupOperations);

// Create and add operations to create new ad group criteria (keywords).
operations.addAll(buildAdGroupCriterionOperations(adGroupOperations));

// Create and add operations to create new ad group ads (text ads).
operations.addAll(buildAdGroupAdOperations(adGroupOperations));

アップロード URL へオペレーションをアップロードする

ジョブのオペレーションが揃ったら、アップロード URL へオペレーションを送信します。

クライアント ライブラリにあるユーティリティを使用している場合は、詳細を気にする必要はありません。リクエストの作成と送信はユーティリティによって処理され、次のどちらでも実行することができます。

  1. すべてのオペレーションを一度にアップロードする。
  2. ユーティリティの呼び出しを複数回行ってオペレーションをアップロードする。

方法 1: すべてのオペレーションを一度にアップロードする

下の例では、Java クライアント ライブラリの BatchJobHelper ユーティリティを使用して、すべてのオペレーションを一度にアップロードします。

// Use a BatchJobHelper to upload all operations.
BatchJobHelper batchJobHelper = adWordsServices.getUtility(session, BatchJobHelper.class);

batchJobHelper.uploadBatchJobOperations(operations, uploadUrl);

方法 2: ユーティリティの呼び出しを複数回行ってオペレーションをアップロードする

下の例では Java クライアント ライブラリの BatchJobHelper ユーティリティを使用し、その uploadIncrementalBatchJobOperations() メソッドを繰り返し呼び出してオペレーションを段階的にアップロードします。

// Use a BatchJobUploadHelper to upload all operations.
BatchJobHelper batchJobUploadHelper = new BatchJobHelper(session);
BatchJobUploadStatus startingUploadStatus =
    new BatchJobUploadStatus(0, URI.create(batchJob.getUploadUrl().getUrl()));
BatchJobUploadResponse uploadResponse;

// Create and upload the first operation to create a new budget.
BudgetOperation budgetOperation = buildBudgetOperation(tempIdGenerator, namePrefix);
uploadResponse = batchJobUploadHelper.uploadIncrementalBatchJobOperations(
    Lists.newArrayList(budgetOperation),
    false, /* pass isLastRequest = false */
    startingUploadStatus);
System.out.printf("First upload response: %s%n", uploadResponse);

// Create and upload intermediate operations to create new campaigns.
List<CampaignOperation> campaignOperations =
    buildCampaignOperations(budgetOperation, tempIdGenerator, namePrefix);
uploadResponse = batchJobUploadHelper.uploadIncrementalBatchJobOperations(
    campaignOperations,
    false, /* pass isLastRequest = false */
    uploadResponse.getBatchJobUploadStatus());
System.out.printf("Intermediate upload response: %s%n", uploadResponse);

// Upload more intermediate requests...

// Create and upload operations to create new ad group ads (text ads).
// This is the final upload request for the BatchJob.
uploadResponse = batchJobUploadHelper.uploadIncrementalBatchJobOperations(
    buildAdGroupAdOperations(adGroupOperations),
    true, /* pass isLastRequest = true */
    uploadResponse.getBatchJobUploadStatus());
System.out.printf("Last upload response: %s%n", uploadResponse);

バッチジョブのステータスを確認する

オペレーションをアップロードした後、バッチジョブはジョブキューに送信されます。そのため、ジョブのステータスが CANCELEDDONE になるまでステータスを定期的に確認する必要があります。確認の回数が過剰にならないように、指数バックオフ ポリシーを使用してください。下のスニペットを使用すると、最初の試行では 30 秒間隔、2 回目の試行では 60 秒間隔、3 回目の試行では 120 秒間隔といった具合に確認が実行されます。

int pollAttempts = 0;
boolean isPending = true;
Selector selector =
    new SelectorBuilder()
        .fields(BatchJobField.Id, BatchJobField.Status, BatchJobField.DownloadUrl,
            BatchJobField.ProcessingErrors, BatchJobField.ProgressStats)
        .equalsId(batchJob.getId())
        .build();
do {
  long sleepSeconds = (long) Math.scalb(30, pollAttempts);
  System.out.printf("Sleeping %d seconds...%n", sleepSeconds);
  Thread.sleep(sleepSeconds * 1000);

  batchJob = batchJobService.get(selector).getEntries(0);
  System.out.printf(
      "Batch job ID %d has status '%s'.%n", batchJob.getId(), batchJob.getStatus());

  pollAttempts++;
  isPending = PENDING_STATUSES.contains(batchJob.getStatus());
} while (isPending && pollAttempts < MAX_POLL_ATTEMPTS);

バッチジョブの結果のダウンロードとエラーの確認

この時点で、ジョブは次のステータスのいずれかになっています。

ステータス 説明 対応
DONE アップロードした各オペレーションが BatchJobService によって正常に解析、試行されました。
  • バッチジョブの downloadUrl から各オペレーションの結果をダウンロードします。
CANCELED アップロードしたオペレーションを BatchJobService が解析しようとしたときに、エラーが発生しました。
  • バッチジョブの processingErrors のリストを確認します。
  • 正常に解析されたオペレーションがある場合は、バッチジョブの downloadUrl から結果をダウンロードします。

ダウンロード URL を使用すると、アップロードされたオペレーションごとに mutateResult 要素が返されます。各結果には BatchJobOpsService.wsdl で定義されている次の属性が含まれています。

属性 説明
result Operand オペレーションが正常に完了した場合は、この属性に次の子要素のいずれかが含まれています。
  • Ad
  • AdGroup
  • AdGroupAd
  • AdGroupAdLabel
  • AdGroupBidModifier
  • AdGroupCriterion
  • AdGroupCriterionLabel
  • AdGroupExtensionSetting
  • AdGroupLabel
  • Budget
  • Campaign
  • CampaignCriterion
  • CampaignExtensionSetting
  • CampaignLabel
  • CustomerExtensionSetting
  • FeedItem
返される要素とオブジェクトは、同じ index を持つオペレーションの型に対応 しています。たとえば、オペレーションが正常に完了した CampaignOperation であれば、Campaign 要素が返されます。
errorList ErrorList オペレーションが失敗した場合は 1 つ以上の errors 要素が含まれています。各要素は ApiError のインスタンスか、そのサブクラスのインスタンスになります。
index long オペレーションに付加された、0 から始まるオペレーション番号です。この番号を使用して、この結果とアップロード内の対応するオペレーションが関連付けられます。

下記のコードはダウンロード URL から返された結果を処理する 1 つの方法です。

if (batchJob.getDownloadUrl() != null && batchJob.getDownloadUrl().getUrl() != null) {
  BatchJobMutateResponse mutateResponse =
      batchJobHelper.downloadBatchJobMutateResponse(batchJob.getDownloadUrl().getUrl());
  System.out.printf("Downloaded results from %s:%n", batchJob.getDownloadUrl().getUrl());
  for (MutateResult mutateResult : mutateResponse.getMutateResults()) {
    String outcome = mutateResult.getErrorList() == null ? "SUCCESS" : "FAILURE";
    System.out.printf("  Operation [%d] - %s%n", mutateResult.getIndex(), outcome);
  }
} else {
  System.out.println("No results available for download.");
}

バッチジョブの processingErrors には、入力ファイルの破損エラーなど、アップロードしたオペレーションの前処理中に発生したすべてのエラーが含まれます。下記のコードは、そのようなエラーを処理する方法の 1 つを示しています。

if (batchJob.getProcessingErrors() != null) {
  int i = 0;
  for (BatchJobProcessingError processingError : batchJob.getProcessingErrors()) {
    System.out.printf(
        "  Processing error [%d]: errorType=%s, trigger=%s, errorString=%s, fieldPath=%s"
        + ", reason=%s%n",
        i++, processingError.getApiErrorType(), processingError.getTrigger(),
        processingError.getErrorString(), processingError.getFieldPath(),
        processingError.getReason());
  }
} else {
  System.out.println("No processing errors found.");
}

一時 ID を使用する

BatchJobService の特長として、一時 ID を使用できます。一時 ID は負の値(long)です。バッチジョブ内のオペレーションはこの ID を使用して、同じバッチジョブ内の前のオペレーションによる ADD オペレーションの結果を参照することができます。まず親オブジェクトの ADD オペレーションで ID に負の値を指定し、同じバッチジョブ内の依存関係にある他のオブジェクトに対する以後の mutate() オペレーションで、その ID を再利用します。

一時 ID は、1 つのバッチジョブ内で包括的なキャンペーンを作成する際によく使用されます。たとえば、各 operand に次の ID が割り当てられた ADD オペレーションを含む単一のジョブを作成することができます。

このプロセスは次のように進行します。

  • (一時)ID を -1 に設定したキャンペーンを追加する
    • 一時 ID を -2 に設定した広告グループをキャンペーン -1 に追加する
      • 広告グループ -2 に広告を追加する
      • 広告グループ -2 に複数の条件(キーワード)を追加する
  • キャンペーン -1 にラベルを付ける
  • キャンペーン -1 にキャンペーンの除外条件(キーワード)を追加する

バッチジョブをキャンセルする

BatchJobstatusAWAITING_FILEACTIVE であればキャンセルできます。キャンセルするには、BatchJobService.mutate() リクエストを発行して、次のように指定した BatchJobOperation を渡します。

  • operator = SET
  • operand = BatchJob:
    • id = バッチジョブ ID
    • status = CANCELING

上記のリクエストを発行する際に BatchJobstatusAWAITING_FILEACTIVE のどちらでもない場合、リクエストは失敗し、BatchJobError.INVALID_STATE_CHANGE エラーが返されます。

ジョブのキャンセルは非同期オペレーションであるため、mutate() リクエストの後、CANCELEDDONE になるまでバッチジョブのステータスを確認してください。ジョブがキャンセルされる前に一部のオペレーションが試行されている場合があるため、必ず結果をダウンロードし、エラーの有無を確認してください。

アップロードの要件

増分アップロード以外のアップロード

各クライアント ライブラリのユーティリティには、ワンステップで複数のオペレーションをアップロードできる便利な機能が備わっています。ただし、クライアント ライブラリを使用していない場合は、増分アップロード以外のアップロードを利用できませんのでご注意ください。

増分アップロード

増分アップロードでは、バッチジョブの uploadUrl に複数のアップロード リクエストを送信できます。ジョブの実行は最後のオペレーションがアップロードされた後に開始されます。

BatchJob uploadURL と再開可能アップロード URL の置き換え

アップロード プロセスは XML API を使用した再開可能アップロードに関する Google Cloud Storage のガイドラインに準拠しています。

BatchJobuploadUrl は再開可能アップロード URL に置き換える必要がありますuploadUrl を再開可能アップロード URL に置き換えるには、次の仕様を満たす uploadUrl にリクエストを送信します。

リクエストの属性
リクエスト メソッド POST
URL BatchJobService.mutate によって返されるアップロード URL
Content-Type HTTP ヘッダー application/xml
Content-Length HTTP ヘッダー 0
x-goog-resumable HTTP ヘッダー start
リクエスト本文 リクエスト本文は不要

リクエストが正常に送信されると、ステータスが 201 CreatedLocation ヘッダーが再開可能アップロード URL に設定されたレスポンスが返されます。

再開可能アップロード URL へのオペレーションのアップロード

再開可能アップロード URL を取得できたら、オペレーションのアップロードを開始できます。再開可能アップロード URL に送信する各リクエストは、次の仕様を満たしている必要があります。

リクエストの属性
リクエスト メソッド PUT
URL 上記の初期化手順で取得した再開可能アップロード URL
Content-Type HTTP ヘッダー application/xml
Content-Length HTTP ヘッダー 現在のリクエストのコンテンツに含まれるバイト数
Content-Range HTTP ヘッダー
リクエストのバイト数の範囲と合計バイト数。合計バイト数は最初のリクエストと中間のリクエストでは * になりますが、最後のリクエストを送信する際は最終的な合計バイト数に設定されます。
例:
bytes 0-262143/*
bytes 262144-524287/*
bytes 524288-786431/786432
リクエスト本文
BatchJobOpsService.wsdl で指定されている XML 形式のオペレーション。

再開可能アップロード URL のリクエスト本文

BatchJobService は最終的に、uploadUrl にアップロードされた XML をすべて連結して 1 つのリクエストとして解析します。そのため、最初と最後のリクエストには、それぞれ開始と終了の mutate 要素のみが含まれるようにしてください。

リクエスト 開始 mutate 要素 終了 mutate 要素
最初 チェックマーク 禁止マーク
中間 禁止マーク 禁止マーク
最後 禁止マーク チェックマーク

また、BatchJobService はアップロードされた XML を 1 つのドキュメントとして解析するため、1 つのリクエストの本文に完全な XML ドキュメントが含まれている必要はありません。たとえば、524,305 バイト(256K+256K+17)をアップロードする場合、リクエストは次のようになります。

リクエスト 1

<?xml version="1.0" encoding="UTF-8"?>
<ns1:mutate xmlns:ns1="https://adwords.google.com/api/adwords/cm/v201702">
<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

コンテンツの長さは 262,144 です。最後の行の t が 262,144 番目のバイトです。

リクエスト 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

コンテンツの長さは 262,144 です。最後の行の e が 262,144 番目のバイトです。

リクエスト 3

rations></mutate>
... (262144 バイトまでパディング)

パディングを除いたコンテンツの長さは 17 バイトです。</mutate> の最後の > が 17 番目のバイトです。パディングを加えたコンテンツの長さの合計は 262,144 バイトです。

おすすめの方法

BatchJobService を使用する際は、次のガイドラインを参考にしてください。

  • 処理能力を高めるには、小さなジョブを数多く行うよりも、ジョブを大きくして数を減らすようにします。
  • 同じ clientCustomerId が複数のジョブを連続して送信する場合は、ジョブのサイズを維持しつつ、同じオブジェクトに対してジョブのオペレーションが同時に発生する可能性を減らすようにします。完了していない多数のジョブ(ステータスが ACTIVE または CANCELING)がオブジェクトの同じグループを変換しようとすると、サーバーの速度低下やジョブの失敗などにより処理が停止してしまうことがあります。
  • 複数のオペレーションが同一ジョブ内の同じオブジェクトを変換しないようにします。
  • スループットを高めるには、アップロードするオペレーションを種類別に順序付けます。たとえばキャンペーン、広告グループ、広告グループの条件を追加するオペレーションがジョブに含まれている場合は、すべての CampaignOperations、すべての AdGroupOperations、そしてすべての AdGroupCriterionOperations の順に並べます。
  • ジョブ ステータスを頻繁に確認しないようにします。確認の間隔が短すぎると、レート制限エラーが発生することがあります。

ショッピング キャンペーンでの使用

BatchJobService を使用した商品分割ツリーの更新には以下の制限があります。

  1. 一連のオペレーションを行うことによって商品分割ツリーの構造が無効な状態になる場合(ノードが分割されるが、もう一方のノードが作成されない場合など)は、その商品分割ツリーに対する一連のオペレーション全体が失敗します。

  2. 商品分割ツリーの構造を変更しないオペレーション(既存のノードの入札単価の変更など)は個別に実行されます。

  3. 商品分割ノードを削除するときは、AdGroupCriterion オブジェクトの criterion フィールドに ProductPartition インスタンスを設定します。このフィールドに Criterion インスタンスを設定するとオペレーションは失敗し、AdGroupCriterionError.CONCRETE_TYPE_REQUIRED エラーが発生します。

制限事項

  • AdWords アカウントで保持できるアップロード済みオペレーションは、常に、未完了のバッチジョブ全体で最大 1 GB です。この上限に達してから新しいバッチジョブを追加しようとすると、DISK_QUOTA_EXCEEDED を理由として BatchJobError が発生します。このエラーが発生した場合は、保留中のアップロード済みオペレーションのサイズが上限を下回るまで待ってから、新しいジョブを作成してください。

コードサンプル

上記のすべての機能を示したコードサンプルの全文が、次のクライアント ライブラリに用意されています。

フィードバックを送信...

ご不明な点がありましたら、Google のサポートページをご覧ください。