Vorläufiges Löschen deaktivieren

Übersicht Nutzung

Auf dieser Seite wird beschrieben, wie Sie die Funktion zum vorläufigen Löschen für neue und vorhandene Buckets in Ihrer Organisation deaktivieren.

Das vorläufige Löschen ist für neue Buckets standardmäßig aktiviert, um Datenverluste zu vermeiden. Sie können das vorläufige Löschen für vorhandene Buckets deaktivieren, indem Sie die entsprechende Richtlinie ändern. Sie können das vorläufige Löschen auch standardmäßig für neue Buckets deaktivieren, indem Sie ein organisationsweites Standard-Tag festlegen. Wenn Sie das vorläufige Löschen deaktivieren, können Ihre gelöschten Daten nicht wiederhergestellt werden, auch nicht bei versehentlichem oder böswilligem Löschen.

Erforderliche Rollen

Bitten Sie Ihren Administrator, Ihnen die folgenden IAM-Rollen auf Organisationsebene zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Deaktivieren der Funktion zum Soft-Löschen benötigen:

Diese vordefinierten Rollen enthalten die Berechtigungen, die zum Deaktivieren des vorläufigen Löschens erforderlich sind. Erweitern Sie den Abschnitt Erforderliche Berechtigungen, um die erforderlichen Berechtigungen anzuzeigen:

Erforderliche Berechtigungen

Die folgenden Berechtigungen sind erforderlich, um das vorläufige Löschen zu deaktivieren:

  • storage.buckets.get
  • storage.buckets.update
  • storage.buckets.list (ist nur erforderlich, wenn Sie die Google Cloud Console zum Ausführen der Anleitung auf dieser Seite verwenden möchten)

    Informationen zu den erforderlichen Berechtigungen, die in der Rolle „Tag-Administrator“ (roles/resourcemanager.tagAdmin) enthalten sind, finden Sie unter Erforderliche Berechtigungen zum Verwalten von Tags.

Informationen zum Zuweisen von Rollen finden Sie unter IAM mit Buckets verwenden oder Zugriff auf Projekte verwalten.

Vorläufiges Löschen für einen bestimmten Bucket deaktivieren

Beachten Sie Folgendes, bevor Sie beginnen:

  • Wenn Sie eine Richtlinie für vorläufiges Löschen für Ihren Bucket deaktivieren, der zum Zeitpunkt der Deaktivierung vorläufig gelöschte Objekte enthält, werden die vorhandenen vorläufig gelöschten Objekte so lange aufbewahrt, bis die zuvor angewendete Aufbewahrungsdauer abgelaufen ist.

  • Nachdem Sie eine Richtlinie für das vorläufige Löschen für Ihren Bucket deaktiviert haben, speichert Cloud Storage neu gelöschte Objekte nicht.

So deaktivieren Sie das vorläufige Löschen für einen bestimmten Bucket:

Console

  1. Wechseln Sie in der Cloud Console zur Seite Cloud Storage-Buckets.

    Buckets aufrufen

  2. Klicken Sie in der Liste der Buckets auf den Namen des Buckets, dessen Richtlinie für das vorläufige Löschen Sie deaktivieren möchten.

  3. Klicken Sie auf den Tab Schutz.

  4. Klicken Sie im Abschnitt Richtlinie für das vorläufige Löschen auf Deaktivieren, um die Richtlinie für das vorläufige Löschen zu deaktivieren.

  5. Klicken Sie auf Bestätigen.

Unter Fehlerbehebung erfahren Sie, wie Sie detaillierte Fehlerinformationen zu fehlgeschlagenen Cloud Storage-Vorgängen in der Google Cloud Console abrufen.

Befehlszeile

Führen Sie den Befehl gcloud storage buckets update mit dem Flag --clear-soft-delete aus:

gcloud storage buckets update --clear-soft-delete gs://BUCKET_NAME

Wobei:

  • BUCKET_NAME ist der Name des Buckets. Beispiel: my-bucket

REST APIs

JSON API

  1. Die gcloud CLI installieren und initialisieren, um ein Zugriffstoken für den Header Authorization zu generieren.

  2. Erstellen Sie eine JSON-Datei, die folgende Informationen enthält:

    {
      "softDeletePolicy": {
        "retentionDurationSeconds": "0"
      }
    }
  3. Verwenden Sie cURL, um die JSON API mit einer PATCH-Bucket-Anfrage aufzurufen:

    curl -X PATCH --data-binary @JSON_FILE_NAME \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json" \
      "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME"

    Dabei gilt:

    • JSON_FILE_NAME ist der Pfad für die JSON-Datei, die Sie in Schritt 2 erstellt haben.
    • BUCKET_NAME ist der Name des entsprechenden Buckets. Beispiel: my-bucket.

Vorläufiges Löschen für die 100 größten Buckets in einem Projekt deaktivieren

In der Google Cloud Console können Sie das vorläufige Löschen für bis zu 100 Buckets gleichzeitig deaktivieren. Die Buckets werden nach der Anzahl der vorläufig gelöschten Bytes oder dem höchsten Verhältnis von vorläufig gelöschten zu aktiven Bytes sortiert. So können Sie Buckets mit den größten Auswirkungen auf Ihre Kosten für das vorläufige Löschen verwalten.

  1. Wechseln Sie in der Cloud Console zur Seite Cloud Storage-Buckets.

    Buckets aufrufen

  2. Klicken Sie auf der Seite „Cloud Storage“ auf Einstellungen.

  3. Klicken Sie auf den Tab Vorläufiges Löschen .

  4. Wählen Sie in der Liste Top-Buckets nach gelöschten Bytes die Buckets aus, für die Sie das vorläufige Löschen deaktivieren möchten.

  5. Klicken Sie auf Vorläufiges Löschen deaktivieren.

    Das vorläufige Löschen ist für die von Ihnen ausgewählten Buckets deaktiviert.

Vorläufiges Löschen für mehrere oder alle Buckets in einem Projekt deaktivieren

Führen Sie mit der Google Cloud CLI den Befehl gcloud storage buckets update mit dem Flag --project und dem Wildcard-Zeichen * aus, um das vorläufige Löschen für mehrere oder alle Buckets in einem Projekt gleichzeitig zu deaktivieren:

gcloud storage buckets update --project=PROJECT_ID --clear-soft-delete gs://*

Wobei:

  • PROJECT_ID ist die ID des Projekts. Beispiel: my-project

Vorläufiges Löschen für alle Buckets in einem Ordner deaktivieren

Führen Sie mit der Google Cloud CLI die Befehle gcloud projects list und gcloud storage buckets update aus, um das vorläufige Löschen für Buckets in allen Projekten in einem bestimmten Ordner zu deaktivieren.

Führen Sie die Befehle gcloud projects list und gcloud storage buckets update aus, um alle Buckets in einem bestimmten Ordner aufzulisten, und deaktivieren Sie dann das vorläufige Löschen für alle Buckets im Ordner:

gcloud projects list --filter="parent.id: FOLDER_ID" --format="value(projectId)" | while read project
do
  gcloud storage buckets update --project=$project --clear-soft-delete gs://*
done

Wobei:

  • FOLDER_ID ist der Name des Ordners. Beispiel: 123456

Vorläufiges Löschen auf Organisationsebene deaktivieren

Führen Sie über die Google Cloud CLI den Befehl gcloud storage buckets update mit dem Flag --clear-soft-delete und dem Wildcard-Zeichen * aus, um das Soft-Löschen auf Organisationsebene zu deaktivieren:

Führen Sie den Befehl gcloud storage buckets update mit dem Flag --clear-soft-delete und dem Wildcard-Zeichen * aus, um das vorläufige Löschen für alle Buckets in Ihrer Organisation zu deaktivieren:

gcloud projects list --format="value(projectId)" | while read project
do
  gcloud storage buckets update --project=$project --clear-soft-delete gs://*
done

In Cloud Storage ist das vorläufige Löschen für vorhandene Buckets deaktiviert. Objekte, die bereits vorläufig gelöscht wurden, verbleiben in den Buckets, bis die Aufbewahrungsdauer für das vorläufige Löschen abgelaufen ist. Danach werden sie endgültig gelöscht.

Vorläufiges Löschen für neue Buckets deaktivieren

Das vorläufige Löschen ist für neue Buckets standardmäßig aktiviert. Sie können jedoch mithilfe von Tags verhindern, dass das vorläufige Löschen standardmäßig aktiviert wird. Mit dem Schlüssel storage.defaultSoftDeletePolicy wird in Tags eine Richtlinie für das vorläufige Löschen mit einer Dauer von 0d (null Tage) auf Organisationsebene angewendet. Dadurch wird die Funktion deaktiviert und das zukünftige Speichern gelöschter Daten verhindert.

Folgen Sie der Anleitung unten, um das vorläufige Löschen standardmäßig zu deaktivieren, wenn Sie neue Buckets erstellen. Die folgenden Anweisungen entsprechen nicht der Festlegung einer Organisationsrichtlinie, die eine bestimmte Richtlinie für die Datenlöschung vorschreibt. Sie können die Datenlöschung für bestimmte Bucket weiterhin aktivieren, indem Sie bei Bedarf eine Richtlinie angeben.

  1. Erstellen Sie mit der Google Cloud CLI das Tag storage.defaultSoftDeletePolicy, mit dem die standardmäßige Aufbewahrungsdauer für das vorläufige Löschen für neue Buckets geändert wird. Beachten Sie, dass nur der Tag-Name storage.defaultSoftDeletePolicy die standardmäßige Aufbewahrungsdauer für das vorläufige Löschen aktualisiert.

    Erstellen Sie einen Tag-Schlüssel mit dem Befehl gcloud resource-manager tags keys create:

    gcloud resource-manager tags keys create storage.defaultSoftDeletePolicy \
     --parent=organizations/ORGANIZATION_ID \
     --description="Configures the default softDeletePolicy for new Storage buckets."
    

    Wobei:

    • ORGANIZATION_ID ist die numerische ID der Organisation, für die Sie eine standardmäßige Aufbewahrungsdauer für vorläufiges Löschen festlegen möchten. Beispiel: 12345678901. Informationen zum Abrufen der Organisations-ID finden Sie unter Ressourcen-ID Ihrer Organisation abrufen.
  2. Erstellen Sie mit dem Befehl gcloud resource-manager tags values create einen Tag-Wert für 0d (null Tage), um die Aufbewahrungsdauer für das vorläufige Löschen standardmäßig für neue Buckets zu deaktivieren:

    gcloud resource-manager tags values create 0d \
      --parent=ORGANIZATION_ID/storage.defaultSoftDeletePolicy \
      --description="Disables soft delete for new Storage buckets."
    

    Wobei:

    • ORGANIZATION_ID ist die numerische ID der Organisation, für die Sie die standardmäßige Aufbewahrungsdauer für das vorläufige Löschen festlegen möchten. Beispiel: 12345678901.
  3. Hängen Sie das Tag mit dem Befehl gcloud resource-manager tags bindings create an die Ressource an:

    gcloud resource-manager tags bindings create \
     --tag-value=ORGANIZATION_ID/storage.defaultSoftDeletePolicy/0d \
     --parent=RESOURCE_ID
    

    Wobei:

    • ORGANIZATION_ID ist die numerische ID der Organisation, unter der das Tag erstellt wurde. Beispiel: 12345678901

    • RESOURCE_ID ist der vollständige Name der Organisation, für die Sie die Tagbindung erstellen möchten. Wenn Sie beispielsweise ein Tag an organizations/7890123456 anhängen möchten, geben Sie //cloudresourcemanager.googleapis.com/organizations/7890123456 ein.

Vorläufiges Löschen für Buckets deaktivieren, die einen bestimmten Kostengrenzwert überschreiten

Mit den Cloud-Clientbibliotheken für Python können Sie das Soft-Delete für Bucket deaktivieren, die einen bestimmten relativen Kostengrenzwert überschreiten. Verwenden Sie dazu ein Python-Clientbibliotheksbeispiel. Das Beispiel führt Folgendes aus:

  1. Berechnet die relativen Speicherkosten für jede Speicherklasse.

  2. Hier sehen Sie die Kosten für das vorläufige Löschen, die in Ihren Buckets angefallen sind.

  3. Hier legen Sie einen Kostengrenzwert für die Nutzung des vorläufigen Löschens fest. Außerdem werden die Buckets aufgelistet, die den festgelegten Grenzwert überschreiten. Sie können das vorläufige Löschen für diese Buckets deaktivieren.

Weitere Informationen zum Einrichten der Python-Clientbibliothek und Verwenden des Beispiels finden Sie auf der Seite Kostenanalyse für die Soft Delete-Funktion von Cloud Storage README.md.

Im folgenden Beispiel wird das schrittweise Löschen für Buckets deaktiviert, die einen bestimmten Kostengrenzwert überschreiten:

from __future__ import annotations

import argparse
import json
import google.cloud.monitoring_v3 as monitoring_client


def get_relative_cost(storage_class: str) -> float:
    """Retrieves the relative cost for a given storage class and location.

    Args:
        storage_class: The storage class (e.g., 'standard', 'nearline').

    Returns:
        The price per GB from the https://cloud.google.com/storage/pricing,
        divided by the standard storage class.
    """
    relative_cost = {
        "STANDARD": 0.023 / 0.023,
        "NEARLINE": 0.013 / 0.023,
        "COLDLINE": 0.007 / 0.023,
        "ARCHIVE": 0.0025 / 0.023,
    }

    return relative_cost.get(storage_class, 1.0)


def get_soft_delete_cost(
    project_name: str,
    soft_delete_window: float,
    agg_days: int,
    lookback_days: int,
) -> dict[str, list[dict[str, float]]]:
    """Calculates soft delete costs for buckets in a Google Cloud project.

    Args:
        project_name: The name of the Google Cloud project.
        soft_delete_window: The time window in seconds for considering
          soft-deleted objects (default is 7 days).
        agg_days: Aggregate results over a time period, defaults to 30-day period
        lookback_days: Look back up to upto days, defaults to 360 days

    Returns:
        A dictionary with bucket names as keys and cost data for each bucket,
        broken down by storage class.
    """

    query_client = monitoring_client.QueryServiceClient()

    # Step 1: Get storage class ratios for each bucket.
    storage_ratios_by_bucket = get_storage_class_ratio(
        project_name, query_client, agg_days, lookback_days
    )

    # Step 2: Fetch soft-deleted bytes and calculate costs using Monitoring API.
    soft_deleted_costs = calculate_soft_delete_costs(
        project_name,
        query_client,
        soft_delete_window,
        storage_ratios_by_bucket,
        agg_days,
        lookback_days,
    )

    return soft_deleted_costs


def calculate_soft_delete_costs(
    project_name: str,
    query_client: monitoring_client.QueryServiceClient,
    soft_delete_window: float,
    storage_ratios_by_bucket: dict[str, float],
    agg_days: int,
    lookback_days: int,
) -> dict[str, list[dict[str, float]]]:
    """Calculates the relative cost of enabling soft delete for each bucket in a
       project for certain time frame in secs.

    Args:
        project_name: The name of the Google Cloud project.
        query_client: A Monitoring API query client.
        soft_delete_window: The time window in seconds for considering
          soft-deleted objects (default is 7 days).
        storage_ratios_by_bucket: A dictionary of storage class ratios per bucket.
        agg_days: Aggregate results over a time period, defaults to 30-day period
        lookback_days: Look back up to upto days, defaults to 360 days

    Returns:
        A dictionary with bucket names as keys and a list of cost data
        dictionaries
        for each bucket, broken down by storage class.
    """
    soft_deleted_bytes_time = query_client.query_time_series(
        monitoring_client.QueryTimeSeriesRequest(
            name=f"projects/{project_name}",
            query=f"""
                    {{  # Fetch 1: Soft-deleted (bytes seconds)
                        fetch gcs_bucket :: storage.googleapis.com/storage/v2/deleted_bytes
                        | value val(0) * {soft_delete_window}\'s\'  # Multiply by soft delete window
                        | group_by [resource.bucket_name, metric.storage_class], window(), .sum;

                        # Fetch 2: Total byte-seconds (active objects)
                        fetch gcs_bucket :: storage.googleapis.com/storage/v2/total_byte_seconds
                        | filter metric.type != 'soft-deleted-object'
                        | group_by [resource.bucket_name, metric.storage_class], window(1d), .mean  # Daily average
                        | group_by [resource.bucket_name, metric.storage_class], window(), .sum  # Total over window

                    }}  # End query definition
                    | every {agg_days}d  # Aggregate over larger time intervals
                    | within {lookback_days}d  # Limit data range for analysis
                    | ratio  # Calculate ratio (soft-deleted (bytes seconds)/ total (bytes seconds))
                    """,
        )
    )

    buckets: dict[str, list[dict[str, float]]] = {}
    missing_distribution_storage_class = []
    for data_point in soft_deleted_bytes_time.time_series_data:
        bucket_name = data_point.label_values[0].string_value
        storage_class = data_point.label_values[1].string_value
        # To include location-based cost analysis:
        # 1. Uncomment the line below:
        # location = data_point.label_values[2].string_value
        # 2. Update how you calculate 'relative_storage_class_cost' to factor in location
        soft_delete_ratio = data_point.point_data[0].values[0].double_value
        distribution_storage_class = bucket_name + " - " + storage_class
        storage_class_ratio = storage_ratios_by_bucket.get(
            distribution_storage_class
        )
        if storage_class_ratio is None:
            missing_distribution_storage_class.append(
                distribution_storage_class)
        buckets.setdefault(bucket_name, []).append({
            # Include storage class and location data for additional plotting dimensions.
            # "storage_class": storage_class,
            # 'location': location,
            "soft_delete_ratio": soft_delete_ratio,
            "storage_class_ratio": storage_class_ratio,
            "relative_storage_class_cost": get_relative_cost(storage_class),
        })

    if missing_distribution_storage_class:
        print(
            "Missing storage class for following buckets:",
            missing_distribution_storage_class,
        )
        raise ValueError("Cannot proceed with missing storage class ratios.")

    return buckets


def get_storage_class_ratio(
    project_name: str,
    query_client: monitoring_client.QueryServiceClient,
    agg_days: int,
    lookback_days: int,
) -> dict[str, float]:
    """Calculates storage class ratios for each bucket in a project.

    This information helps determine the relative cost contribution of each
    storage class to the overall soft-delete cost.

    Args:
        project_name: The Google Cloud project name.
        query_client: Google Cloud's Monitoring Client's QueryServiceClient.
        agg_days: Aggregate results over a time period, defaults to 30-day period
        lookback_days: Look back up to upto days, defaults to 360 days

    Returns:
        Ratio of Storage classes within a bucket.
    """
    request = monitoring_client.QueryTimeSeriesRequest(
        name=f"projects/{project_name}",
        query=f"""
            {{
            # Fetch total byte-seconds for each bucket and storage class
            fetch gcs_bucket :: storage.googleapis.com/storage/v2/total_byte_seconds
            | group_by [resource.bucket_name, metric.storage_class], window(), .sum;
            # Fetch total byte-seconds for each bucket (regardless of class)
            fetch gcs_bucket :: storage.googleapis.com/storage/v2/total_byte_seconds
            | group_by [resource.bucket_name], window(), .sum
            }}
            | ratio  # Calculate ratios of storage class size to total size
            | every {agg_days}d
            | within {lookback_days}d
            """,
    )

    storage_class_ratio = query_client.query_time_series(request)

    storage_ratios_by_bucket = {}
    for time_series in storage_class_ratio.time_series_data:
        bucket_name = time_series.label_values[0].string_value
        storage_class = time_series.label_values[1].string_value
        ratio = time_series.point_data[0].values[0].double_value

        # Create a descriptive key for the dictionary
        key = f"{bucket_name} - {storage_class}"
        storage_ratios_by_bucket[key] = ratio

    return storage_ratios_by_bucket


def soft_delete_relative_cost_analyzer(
    project_name: str,
    cost_threshold: float = 0.0,
    soft_delete_window: float = 604800,
    agg_days: int = 30,
    lookback_days: int = 360,
    list_buckets: bool = False,
    ) -> str | dict[str, float]: # Note potential string output
    """Identifies buckets exceeding the relative cost threshold for enabling soft delete.

    Args:
        project_name: The Google Cloud project name.
        cost_threshold: Threshold above which to consider removing soft delete.
        soft_delete_window: Time window for calculating soft-delete costs (in
          seconds).
        agg_days: Aggregate results over this time period (in days).
        lookback_days: Look back up to this many days.
        list_buckets: Return a list of bucket names (True) or JSON (False,
          default).

    Returns:
        JSON formatted results of buckets exceeding the threshold and costs
        *or* a space-separated string of bucket names.
    """

    buckets: dict[str, float] = {}
    for bucket_name, storage_sources in get_soft_delete_cost(
        project_name, soft_delete_window, agg_days, lookback_days
    ).items():
        bucket_cost = 0.0
        for storage_source in storage_sources:
            bucket_cost += (
                storage_source["soft_delete_ratio"]
                * storage_source["storage_class_ratio"]
                * storage_source["relative_storage_class_cost"]
            )
        if bucket_cost > cost_threshold:
            buckets[bucket_name] = round(bucket_cost, 4)

    if list_buckets:
        return " ".join(buckets.keys())  # Space-separated bucket names
    else:
        return json.dumps(buckets, indent=2)  # JSON output


def soft_delete_relative_cost_analyzer_main() -> None:
    # Sample run: python storage_soft_delete_relative_cost_analyzer.py <Project Name>
    parser = argparse.ArgumentParser(
        description="Analyze and manage Google Cloud Storage soft-delete costs."
    )
    parser.add_argument(
        "project_name", help="The name of the Google Cloud project to analyze."
    )
    parser.add_argument(
        "--cost_threshold",
        type=float,
        default=0.0,
        help="Relative Cost threshold.",
    )
    parser.add_argument(
        "--soft_delete_window",
        type=float,
        default=604800.0,
        help="Time window (in seconds) for considering soft-deleted objects.",
    )
    parser.add_argument(
        "--agg_days",
        type=int,
        default=30,
        help=(
            "Time window (in days) for aggregating results over a time period,"
            " defaults to 30-day period"
        ),
    )
    parser.add_argument(
        "--lookback_days",
        type=int,
        default=360,
        help=(
            "Time window (in days) for considering the how old the bucket to be."
        ),
    )
    parser.add_argument(
        "--list",
        type=bool,
        default=False,
        help="Return the list of bucketnames seperated by space.",
    )

    args = parser.parse_args()

    response = soft_delete_relative_cost_analyzer(
        args.project_name,
        args.cost_threshold,
        args.soft_delete_window,
        args.agg_days,
        args.lookback_days,
        args.list,
    )
    if not args.list:
        print(
            "To remove soft-delete policy from the listed buckets run:\n"
            # Capture output
            "python storage_soft_delete_relative_cost_analyzer.py"
            " [your-project-name] --[OTHER_OPTIONS] --list > list_of_buckets.txt \n"
            "cat list_of_buckets.txt | gcloud storage buckets update -I "
            "--clear-soft-delete",
            response,
        )
        return
    print(response)


if __name__ == "__main__":
    soft_delete_relative_cost_analyzer_main()

Nächste Schritte