Funktionsweise von Unterverzeichnissen

Übersicht

Dieser Abschnitt enthält Details zur Funktionsweise von Unterverzeichnissen in gsutil. Die meisten Nutzer benötigen diese Details wahrscheinlich nicht und können die Befehle, die mit Unterverzeichnissen arbeiten, z. B. "cp -r", einfach verwenden. Mit dieser zusätzlichen Dokumentation können Nutzer nachvollziehen, wie gsutil Unterverzeichnisse anders behandelt als die meisten GUI-/basierten Tools. Außerdem sollen so die Kosten und die Leistung des gsutil-Ansatzes für Interessierte erläutert werden.

gsutil erzeugt den Eindruck einer hierarchischen Dateibaumstruktur auf dem "flachen" Namespace, der vom Cloud Storage-Dienst unterstützt wird. Für den Dienst ist das Objekt gs://your-bucket/abc/def.txt einfach ein Objekt, dessen Name zufällig "/" enthält. Es gibt kein Verzeichnis "abc", nur ein einzelnes Objekt mit dem angegebenen Namen. Das folgende Diagramm zeigt, wie gsutil eine hierarchische Ansicht von Objekten in einem Bucket bereitstellt:

https://cloud.google.com/storage/images/gsutil-subdirectories.svg

gsutil erreicht die hierarchische Dateibaumstruktur durch Anwendung verschiedener Regeln, um die Benennung so zu gestalten, wie es die Nutzer erwarten. Damit gsutil beispielsweise ermitteln kann, ob eine Ziel-URL als Objektname oder als Stamm eines Verzeichnisses behandelt werden soll, in dem Objekte kopiert werden sollen, werden die folgenden Regeln verwendet:

  1. Wenn das Zielobjekt mit einem "/" endet, behandelt gsutil es als Verzeichnis. Nehmen wir beispielsweise an, dass Sie den folgenden Befehl ausführen:

    gsutil cp your-file gs://your-bucket/abc/
    

    gsutil erstellt das Objekt gs://your-bucket/abc/your-file.

  2. Wenn Sie versuchen, mehrere Quelldateien in eine Ziel-URL zu kopieren, behandelt gsutil die Ziel-URL als Verzeichnis. Nehmen wir beispielsweise an, dass Sie den folgenden Befehl ausführen:

    gsutil cp -r your-dir gs://your-bucket/abc
    

    gsutil erstellt Objekte wie gs://your-bucket/abc/your-dir/file1 usw. (wobei file1 eine Datei im Quellverzeichnis your-dir ist).

  3. Wenn keine der oben genannten Regeln zutrifft, führt gsutil eine Bucket-Auflistung aus, um festzustellen, ob das Ziel des Vorgangs eine Präfixübereinstimmung mit dem angegebenen String ist. Nehmen wir beispielsweise an, dass Sie den folgenden Befehl ausführen:

    gsutil cp your-file gs://your-bucket/abc
    

    gsutil sendet mit delimiter="/" und prefix="abc" eine Bucket-Auflistungsanfrage für den benannten Bucket. Anschließend werden die Ergebnisse der Bucket-Liste geprüft und es wird festgestellt, ob sich im Bucket Objekte befinden, deren Pfad mit gs://your-bucket/abc/ beginnt. Ist dies der Fall, behandelt gsutil das Ziel als Verzeichnisnamen. Dies wirkt sich wiederum auf den Namen des Objekts aus, das Sie erstellen: Wenn die obige Prüfung ergibt, dass es ein abc-Verzeichnis gibt, erhalten Sie schließlich das Objekt gs://your-bucket/abc/your-file. Andernfalls erhalten Sie das Objekt gs://your-bucket/abc. (Weitere Informationen finden Sie im Abschnitt zum Aufbau von Namen unter gsutil help cp.)

Dieser regelbasierte Ansatz steht im Gegensatz zur Funktionsweise von vielen anderen Tools und erstellt 0-Byte-Objekte, die das Vorhandensein von Ordnern kennzeichnen. gsutil versteht mehrere Konventionen von Tools, wie die Konvention des Hinzufügens von _$folder$ zum Namen des 0-Byte-Objekts. Aber gsutil erfordert keine Markierungsobjekte, um ein mit UNIX-Befehlen konsistentes Benennungsverhalten zu implementieren.

Ein Nachteil der Benennung von gsutil-Unterverzeichnissen besteht darin, dass eine zusätzliche Bucket-Auflistung erforderlich ist, bevor der erforderliche cp- oder mv-Befehl ausgeführt wird. Diese Auflistungen sind jedoch relativ kostengünstig, da sie Trennzeichen- und Präfixparameter verwenden, um Ergebnisdaten einzuschränken. Außerdem sendet gsutil nur eine Bucket-Auflistungsanfrage pro cp/mv-Befehl, sodass sich die Kosten für die Bucket-Auflistung gleichmäßig auf alle übertragenen Objekte verteilen, z. B. beim Ausführen einer rekursiven Kopie eines Verzeichnisses in die Cloud.

Möglichkeit einer unerwarteten Benennung des Zielunterverzeichnisses

Der obige regelbasierte Ansatz zur Bestimmung, wie Zielpfade erstellt werden, kann zum folgenden unerwarteten Verhalten führen: Angenommen, Sie versuchen zuerst einmal, alles in einem lokalen Verzeichnis in ein noch nicht vorhandenes Bucket-"Unterverzeichnis" hochzuladen:

gsutil cp -r ./your-dir/* gs://your-bucket/new

Im Verzeichnis "your-dir" befinden sich Verzeichnisse wie "dir1" und "dir2". Wenn Sie diesen Befehl zum ersten Mal ausführen, werden die folgenden Objekte erstellt:

gs://your-bucket/new/dir1/abc
gs://your-bucket/new/dir2/abc

Das liegt daran, dass "gs://your-bucket/new" noch nicht vorhanden ist. Wenn Sie denselben Befehl noch einmal ausführen, werden die folgenden zusätzlichen Objekte erstellt, da "gs://your-bucket/new" jetzt vorhanden ist:

gs://your-bucket/new/your-dir/dir1/abc
gs://your-bucket/new/your-dir/dir2/abc

Abgesehen davon, dass dieses Benennungsverhalten für Nutzer unerwartet sein kann, sollten Sie besonders vorsichtig sein, wenn Sie Skripte für gsutil-Uploads mit einer Wiederholungsschleife erstellen. Wenn Sie so vorgehen und beim ersten Versuch einige, aber nicht alle Dateien kopiert werden, stößt der zweite Versuch auf ein bereits vorhandenes Zielunterverzeichnis und führt zum oben beschriebenen Benennungsproblem.

Es gibt mehrere Möglichkeiten, dieses Problem zu vermeiden:

1. Verwenden Sie den Befehl "gsutil rsync". Da "rsync" nicht die von Unix cp definierten Verzeichnisnamensregeln verwendet, ist die Funktionsweise konsistent, unabhängig davon, ob das Zielunterverzeichnis vorhanden ist oder nicht.

2. Wenn "rsync" für Sie nicht anwendbar ist, können Sie als Erstes ein "Platzhalterobjekt" erstellen, um festzulegen, dass das Ziel ein Unterverzeichnis ist. Dazu führen Sie einen Befehl wie den folgenden aus:

gsutil cp some-file gs://your-bucket/new/placeholder

An dieser Stelle wird beim Ausführen des oben genannten Befehls "gsutil cp -r" "gs://your-bucket/new" konsistent als Unterverzeichnis behandelt. Sobald sich mindestens ein Objekt in diesem Unterverzeichnis befindet, können Sie das Platzhalterobjekt löschen. Darauffolgende Uploads in dieses Unterverzeichnis funktionieren weiterhin mit dem erwarteten Benennungsverhalten.