エンティティのエクスポートとインポート

このページでは、マネージド エクスポートとインポート サービスを使用して Datastore モードの Cloud Firestore エンティティをエクスポート、インポートする方法について説明します。マネージド エクスポート / インポート サービスは、gcloud コマンドライン ツールや Cloud Datastore Admin API(RESTRPC)で利用できます。

マネージド エクスポートおよびインポート サービスを利用すると、誤って削除したデータを復元したり、オフライン処理のためにデータをエクスポートしたりできます。すべてのエンティティをエクスポートすることも、特定の種類のエンティティだけをエクスポートすることもできます。同様に、エクスポートされたすべてのデータをインポートすることも、特定の種類のみをインポートすることもできます。マネージド エクスポートおよびインポート サービスを利用する際は、次の点を考慮してください。

  • エクスポート サービスでは、結果整合性読み取りが使用されます。エクスポートが単一の時点で発生すると想定することはできません。エクスポートの開始後に書き込まれたエンティティがエクスポートに含まれる場合も、エクスポートの開始前に書き込まれたエンティティがエクスポートから除外される場合もあります。

  • インデックスはエクスポートに含まれません。データをインポートすると、データベースの現在のインデックス定義を使用して、必要なインデックスが自動的に再構築されます。エンティティごとのプロパティ値のインデックス設定はエクスポートされ、インポート時に適用されます。

  • インポートでは、エンティティに新しい ID は割り当てられません。インポートでは、エクスポート時の ID が使用され、同じ ID のエンティティはすべて上書きされます。これらの ID は、エンティティのインポート中は予約された状態になります。これにより、インポートの実行中に書き込みが有効になっても、新しいエンティティと ID が競合することはありません。

  • データベース内のエンティティがインポートの影響を受けない場合、そのエンティティはインポート後もデータベースに維持されます。

  • ある Datastore モードのデータベースからエクスポートされたデータを、別の Datastore モードのデータベース(別のプロジェクト内のものでも可)にインポートできます。

  • マネージド エクスポートおよびインポート サービスでは、同時に実行できるエクスポートとインポートの数が 50 個に制限されています。プロジェクトで 1 分間に送信できるエクスポート / インポート リクエストは最大 20 個までです。

  • マネージド エクスポートの出力では、LevelDB ログ形式が使用されます。

  • エンティティのサブセットのみインポートする場合、もしくは BigQuery にデータをインポートする場合は、エクスポートでエンティティ フィルタを指定する必要があります。

始める前に

マネージド エクスポートおよびインポート サービスを使用するには、その前に、次のタスクを完了する必要があります。

  1. Google Cloud Platform プロジェクトに対する課金を有効にします。エクスポート機能とインポート機能を使用できるのは、課金が有効になっている GCP プロジェクトのみです。

  2. Datastore モードの Cloud Firestore データベースのロケーションと同じロケーションに、Cloud Storage バケットを作成します。すべてのエクスポートとインポートで Cloud Storage を使用するため、Cloud Storage バケットと Datastore モードの Cloud Firestore データベースで同じロケーションを使用する必要があります。エクスポート / インポート オペレーションには、リクエスト元による支払いバケットは使用できません。

  3. ユーザー アカウントに、datastore.databases.export 権限(データをエクスポートする場合)または datastore.databases.import 権限(データをインポートする場合)を付与する IAM 役割を割り当てます。たとえば、Cloud Datastore Import Export Admin 役割は、この両方の権限を付与します。

  4. Cloud Storage バケットが別のプロジェクト内に存在する場合、プロジェクトのデフォルトのサービス アカウントに、バケットへのアクセス権を付与します。

環境を設定する

データをエクスポートまたはインポートする前に、gcloud ツールの環境変数を設定し、ユーザー アカウントを使用して認証を行う必要があります。

  1. GCP プロジェクト ID の環境変数を設定します。

    PROJECT_ID="YOUR_PROJECT_ID"
    
  2. この変数を使用して、プロジェクトを gcloud ツールのアクティブ構成として設定します。

    gcloud config set project ${PROJECT_ID}
    
  3. gcloud ツールを使用して認証を行います。

    gcloud auth login
    
  4. Cloud Storage バケット ID の環境変数を設定します。

    BUCKET="YOUR_BUCKET_NAME[/NAMESPACE_PATH]"
    

    ここで、YOUR_BUCKET_NAME は Cloud Storage バケットの名前、NAMESPACE_PATH はオプションの Cloud Storage 名前空間パスです(これは Datastore モードの名前空間ではありません)。Cloud Storage 名前空間パスの詳細については、オブジェクト名に関する考慮事項をご覧ください。

マネージド エクスポートおよびインポート オペレーションの開始

このセクションでは、マネージド エクスポートまたはインポート オペレーションを開始する方法と、オペレーションの進行状況を確認する方法について説明します。

すべてのエンティティのエクスポート

データベースのすべてのエンティティをエクスポートするには、gcloud datastore export コマンドを使用します。--async フラグを追加して、gcloud ツールにオペレーションの終了を待機させないようにすることもできます。

gcloud

gcloud datastore export gs://${BUCKET} --async

rest

後述のリクエストのデータを使用する前に、次のように置き換えます。

  • project-id: プロジェクト ID
  • bucket-name: Cloud Storage バケット名

HTTP メソッドと URL:

POST https://datastore.googleapis.com/v1/projects/project-id:export

JSON 本文のリクエスト

{
  "outputUrlPrefix": "gs://bucket-name",
}

リクエストを送信するには、次のいずれかのオプションを展開します。

特定の種類または名前空間のエクスポート

種類や名前空間の特定のサブセットをエクスポートするには、エンティティ フィルタに種類と名前空間 ID の値を指定します。

gcloud

gcloud datastore export --kinds="KIND1,KIND2" --namespaces="(default),NAMESPACE2" gs://${BUCKET} --async

rest

後述のリクエストのデータを使用する前に、次のように置き換えます。

  • project-id: プロジェクト ID
  • bucket-name: Cloud Storage バケット名
  • kind: エンティティの種類
  • namespace: 名前空間 ID(デフォルトの名前空間 ID には「""」を使用します)

HTTP メソッドと URL:

POST https://datastore.googleapis.com/v1/projects/project-id:export

JSON 本文のリクエスト

{
  "outputUrlPrefix": "gs://bucket-name",
  "entityFilter": {
    "kinds": ["kind"],
    "namespaceIds": ["namespace"],
  },
}

リクエストを送信するには、次のいずれかのオプションを展開します。

メタデータ ファイルのエクスポート

エクスポート オペレーションでは、指定された名前空間と種類のペアごとにメタデータ ファイルが作成されます。通常、メタデータ ファイルの名前は [NAMESPACE_NAME]_[KIND_NAME].export_metadata です。ただし、名前空間または種類で無効な Cloud Storage オブジェクト名が作成された場合には、ファイル名が export[NUM].export_metadata になります。

メタデータ ファイルはプロトコル バッファであり、protocプロトコル コンパイラでデコードできます。たとえば、メタデータ ファイルをデコードすると、エクスポート ファイルに含まれる名前空間と種類を判別することができます。

protoc --decode_raw < export0.export_metadata

すべてのエンティティのインポート

マネージド エクスポート サービスで以前にエクスポートされたすべてのエンティティをインポートするには、gcloud datastore import コマンドを使用します。--async フラグを追加して、gcloud ツールにオペレーションの終了を待機させないようにすることもできます。

gcloud

gcloud datastore import gs://${BUCKET}/[PATH]/[FILE].overall_export_metadata --async

rest

後述のリクエストのデータを使用する前に、次のように置き換えます。

  • project-id: プロジェクト ID
  • bucket-name: Cloud Storage バケット名
  • object-name: Cloud Storage オブジェクト名(例: 2017-05-25T23:54:39_76544/2017-05-25T23:54:39_76544.overall_export_metadata

HTTP メソッドと URL:

POST https://datastore.googleapis.com/v1/projects/project-id:import

JSON 本文のリクエスト

{
  "inputUrl": "gs://bucket-name/object-name",
}

リクエストを送信するには、次のいずれかのオプションを展開します。

Google Cloud Platform Console の Cloud Storage UI を使用してバケットを表示するか、エクスポートの完了後に gcloud datastore export 出力または ExportEntitiesResponse を調べることで、インポート ロケーションに使用されている値を確認できます。インポート ロケーションの値の例を以下に示します。

gcloud

gs://${BUCKET}/2017-05-25T23:54:39_76544/2017-05-25T23:54:39_76544.overall_export_metadata --async

rest

"outputUrl": "gs://'${BUCKET}'/2017-05-25T23:54:39_76544/2017-05-25T23:54:39_76544.overall_export_metadata",

特定の種類または名前空間のインポート

種類や名前空間の特定のサブセットをインポートするには、エンティティ フィルタに種類と名前空間 ID の値を指定します。

エクスポート ファイルがエンティティ フィルタで作成された場合にのみ、種類と名前空間を指定できます。すべてのエンティティのエクスポートから、種類と名前空間のサブセットをインポートすることはできません。

gcloud

gcloud datastore import --kinds="KIND1,KIND2" --namespaces="(default),NAMESPACE2" gs://${BUCKET}/[PATH]/[FILE].overall_export_metadata --async

rest

後述のリクエストのデータを使用する前に、次のように置き換えます。

  • project-id: プロジェクト ID
  • bucket-name: Cloud Storage バケット名
  • object-name: Cloud Storage オブジェクト名(例: 2017-05-25T23:54:39_76544/2017-05-25T23:54:39_76544.overall_export_metadata
  • kind: エンティティの種類
  • namespace: 名前空間 ID(デフォルトの名前空間 ID には「""」を使用します)

HTTP メソッドと URL:

POST https://datastore.googleapis.com/v1/projects/project-id:import

JSON 本文のリクエスト

{
  "inputUrl": "gs://bucket-name/object-name",
  "entityFilter": {
    "kinds": ["kind"],
    "namespaceIds": ["namespace"],
  },
}

リクエストを送信するには、次のいずれかのオプションを展開します。

非同期エクスポートまたはインポート

エクスポートとインポートには長い時間がかかります。エクスポートまたはインポートを実行するときに、--async フラグを指定すると gcloud ツールがオペレーションの完了を待たないように設定できます。

エクスポートまたはインポート オペレーションの開始後は、gcloud ツールで返される ID を使用してオペレーションのステータスを確認できます。例:

gcloud datastore operations describe ASAyMDAwOTEzBxp0bHVhZmVkBxJsYXJ0bmVjc3Utc2Jvai1uaW1kYRQKKhI

--async フラグを指定しなかった場合も、Ctrl+c でオペレーションの待機を止めることができます。Ctrl+c を入力しても、オペレーションはキャンセルされません。

長時間実行オペレーションの管理

長時間実行オペレーションとは、完了までに膨大な時間がかかる可能性があるメソッドの呼び出しです。Datastore モードのデータベースは、データのエクスポートまたはインポート時に長時間実行オペレーションを作成します。

たとえば、エクスポートが開始されると、Datastore モードのデータベースはエクスポート ステータスを追跡するための長時間実行オペレーションを作成します。エクスポートの開始からの出力を以下に示します。

{
  "name": "projects/[YOUR_PROJECT_ID]/operations/ASAyMDAwOTEzBxp0bHVhZmVkBxJsYXJ0bmVjc3Utc2Jvai1uaW1kYRQKKhI",
  "metadata": {
    "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata",
    "common": {
      "startTime": "2017-05-25T23:54:39.583780Z",
      "operationType": "EXPORT_ENTITIES"
    },
    "progressEntities": {},
    "progressBytes": {},
    "entityFilter": {
      "namespaceIds": [
        ""
      ]
    },
    "outputUrlPrefix": "gs://[YOUR_BUCKET_NAME]"
  }
}

name フィールドの値は、長期実行オペレーションの ID です。

Datastore モードの Cloud Firestore では、オペレーション Admin API を使用して、長時間実行オペレーションのステータスを確認したり、長時間実行オペレーションをキャンセル、削除、一覧表示したりできます。

メソッド 説明
projects.operations.cancel 長時間実行オペレーションをキャンセルします。
projects.operations.delete 長時間実行オペレーションを削除します。
注: 削除しても、オペレーションはキャンセルされません。
projects.operations.get 長時間実行オペレーションのステータスを取得します。
projects.operations.list 長時間実行オペレーションを一覧表示します。

長時間実行オペレーションの一覧表示

長時間実行オペレーションを一覧表示するには、gcloud datastore operations list コマンドを使用します。

gcloud

gcloud datastore operations list

rest

後述のリクエストのデータを使用する前に、次のように置き換えます。

  • project-id: プロジェクト ID

HTTP メソッドと URL:

GET https://datastore.googleapis.com/v1/projects/project-id/operations

リクエストを送信するには、次のいずれかのオプションを展開します。

次の出力例には、最近完了したエクスポート オペレーションが示されています。完了後のオペレーションには数日間アクセスできます。

{
  "operations": [
    {
      "name": "projects/[YOUR_PROJECT_ID]/operations/ASAyMDAwOTEzBxp0bHVhZmVkBxJsYXJ0bmVjc3Utc2Jvai1uaW1kYRQKKhI",
      "metadata": {
        "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata",
        "common": {
          "startTime": "2017-12-05T23:01:39.583780Z",
          "endTime": "2017-12-05T23:54:58.474750Z",
          "operationType": "EXPORT_ENTITIES"
        },
        "progressEntities": {
          "workCompleted": "21933027",
          "workEstimated": "21898182"
        },
        "progressBytes": {
          "workCompleted": "12421451292",
          "workEstimated": "9759724245"
        },
        "entityFilter": {
          "namespaceIds": [
            ""
          ]
        },
        "outputUrlPrefix": "gs://[YOUR_BUCKET_NAME]"
      },
      "done": true,
      "response": {
        "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesResponse",
        "outputUrl": "gs://[YOUR_BUCKET_NAME]/2017-05-25T23:54:39_76544/2017-05-25T23:54:39_76544.overall_export_metadata"
      }
    }
  ]
}

エンティティをインポートするときには、input_url 値を使用します。

完了時間の見積もり

オペレーションを実行すると、state フィールドの値で、オペレーション全体のステータスが確認できます。

長時間実行オペレーションのステータスをリクエストすると、workEstimatedworkCompleted の指標も合わせて返されます。これらの指標はバイト数とエンティティ数の両方で返されます。workEstimated は、データベース統計情報に基づき、オペレーションが処理すると推定されるバイト数とエンティティ数の合計を示します。workCompleted には、これまでに処理されたバイト数とドキュメント数が表示されます。オペレーションが完了すると、実際に処理されたバイト数とエンティティ数の合計が workCompleted に反映されます。この値は、workEstimated の値より大きい場合もあります。

進行した割合を大まかに得るには、workCompletedworkEstimated で割ります。この割合は、最新の統計情報コレクションとの間に遅延があるために正確ではない可能性があります。

例として、エクスポート オペレーションの進行状況を次に示します。

{
  "operations": [
    {
      "name": "projects/[YOUR_PROJECT_ID]/operations/ASAyMDAwOTEzBxp0bHVhZmVkBxJsYXJ0bmVjc3Utc2Jvai1uaW1kYRQKKhI",
      "metadata": {
        "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata",
        ...
        "progressEntities": {
          "workCompleted": "1",
          "workEstimated": "3"
        },
        "progressBytes": {
          "workCompleted": "85",
          "workEstimated": "257"
        },
        ...

オペレーションが完了すると、オペレーションの説明に、"done": true が含まれます。オペレーションの結果をみるには、state フィールドの値を確認します。done フィールドがレスポンスに設定されていない場合、値は false になります。進行中のオペレーションに関しては、done の値の有無は参考になりません。

マネージド エクスポートおよびインポートの課金と料金

マネージド エクスポートおよびインポート サービスを使用する前に、Google Cloud Platform プロジェクトに対する課金を有効にする必要があります。エクスポートとインポートのオペレーションは、次のような形で Google Cloud Platform のコストに反映されます。

エクスポートおよびインポート オペレーションのコストは、App Engine の使用量上限の計算対象になりません。また、オペレーションが完了するまで、エクスポート / インポート オペレーションで Google Cloud Platform の予算アラートはトリガーされません。同様に、エクスポートまたはインポート オペレーションの実行中に行われる読み取りと書き込みは、オペレーションが完了してから 1 日の割り当てに適用されます。

権限

エクスポートおよびインポートのオペレーションを実行するには、ユーザー アカウントとプロジェクトのデフォルトのサービス アカウントに以下の Cloud Identity and Access Management 権限が必要です。

ユーザー アカウント権限

オペレーションを開始するユーザー アカウントまたはサービス アカウントには、datastore.databases.exportdatastore.databases.import の Cloud IAM 権限を必要です。プロジェクト オーナーであれば、アカウントに必要な権限が付与されています。そうでない場合は、次の Cloud IAM 役割により、必要な権限を付与します。

  • Cloud Datastore オーナー
  • Cloud Datastore インポート / エクスポート管理者

プロジェクト オーナーがアクセスの許可の手順に従ってこれらの役割のいずれかを付与します。

デフォルトのサービス アカウント権限

GCP プロジェクトでは、PROJECT_ID@appspot.gserviceaccount.com という名前のデフォルト サービス アカウントが自動的に作成されます。エクスポートおよびインポート オペレーションでは、このサービス アカウントを使用して Cloud Storage オペレーションを承認します。

プロジェクトのデフォルトのサービス アカウントには、エクスポートまたはインポート オペレーションで使用される Cloud Storage バケットへのアクセス権限が必要です。Cloud Storage バケットが Datastore モードのデータベースと同じプロジェクトにある場合は、最初からデフォルトのサービス アカウントでバケットにアクセスできます

Cloud Storage バケットが別のプロジェクトにある場合は、デフォルトのサービス アカウントに Cloud Storage バケットへのアクセス権限を付与する必要があります。

デフォルトのサービス アカウントに役割を割り当てる

gsutil コマンドライン ツールを使用して、以下のいずれかの役割を割り当てることができます。たとえば、Storage Admin の役割をデフォルトのサービス アカウントに割り当てるには、次のコマンドを実行します。

gsutil iam ch serviceAccount:[PROJECT_ID]@appspot.gserviceaccount.com:roles/storage.admin \
    gs://[BUCKET_NAME]

別の方法として、GCP Console を使用してこの役割を割り当てることもできます。

オペレーションをエクスポートする

別のプロジェクトのバケットが関連するオペレーションをエクスポートする場合、バケットの権限を変更して、Datastore モードのデータベースを含むプロジェクトのデフォルト サービス アカウントに、次のいずれかの Cloud Storage の役割を割り当てます。

  • ストレージ管理者
  • ストレージ オブジェクト管理者
  • ストレージのレガシー バケット書き込み

次の権限を持つ Cloud IAM カスタム役割を作成することもできます。

  • storage.buckets.get
  • storage.objects.create
  • storage.objects.list

オペレーションをインポートする

別のプロジェクトの Cloud Storage バケットが関連するオペレーションをインポートする場合、バケットの権限を変更して、Datastore モードのデータベースを含むプロジェクトのデフォルト サービス アカウントに、次のいずれかの Cloud Storage の役割を割り当てます。

  • ストレージ管理者
  • ストレージ オブジェクト閲覧者とストレージのレガシー バケット読み取りの両方

次の権限を持つ Cloud IAM カスタム役割を作成することもできます。

  • storage.buckets.get
  • storage.objects.get

Cloud Datastore 管理バックアップとの違い

以前に Cloud Datastore 管理コンソールをバックアップ用に使用していた場合は、次の違いに注意してください。

  • マネージド エクスポートおよびインポート サービスの GUI はありません。

  • マネージド エクスポートによって作成されたエクスポートは、Cloud Datastore 管理コンソールには表示されません。マネージド エクスポートおよびインポートは新しいサービスであり、GCP Console で管理する App Engine のバックアップおよび復元機能とはデータを共有しません。

  • マネージド エクスポートおよびインポート サービスは、Cloud Datastore 管理バックアップと同じメタデータをサポートしているわけではありません。また、データベースに進行状況を保管することはしません。エクスポートおよびインポート オペレーションの進行状況を確認する方法については、長時間実行オペレーションの管理をご覧ください。

  • マネージド エクスポートおよびインポート オペレーションのサービスログを表示することはできません。

  • マネージド インポート サービスには、Cloud Datastore 管理バックアップ ファイルとの後方互換性があります。マネージド インポート サービスを使用して Cloud Datastore 管理バックアップ ファイルをインポートすることはできますが、Cloud Datastore 管理コンソールを使用してマネージド エクスポートの出力をインポートすることはできません。

BigQuery へのインポート

マネージド エクスポートから BigQuery にデータをインポートするには、Cloud Datastore エクスポート サービスデータの読み込みをご覧ください。

制限事項

  • エンティティ フィルタを指定せずにエクスポートされたデータは、BigQuery に読み込むことができません。BigQuery にデータをインポートするには、エクスポート リクエストでエンティティ フィルタに 1 種類以上の名前を含める必要があります。