Amazon S3 ist ein weitverbreiteter Cloud-Speicherdienst, der für seine Skalierbarkeit und Zuverlässigkeit bekannt ist. Dennoch berichten Nutzer immer wieder von langsamen Reaktionszeiten bei bestimmten Operationen, insbesondere beim Auflisten von Objekten mit der ListObjects API. Einige Fälle zeigen sogar Antwortzeiten von bis zu 120 Sekunden, was bei anspruchsvollen Anwendungen zu erheblichen Problemen führen kann. Doch warum ist das Auflisten von Objekten in einigen Situationen so langsam, und wie lassen sich diese Performanceprobleme beheben? Die Antwort liegt vor allem in der Art und Weise, wie S3 mit Versionierung und Delete Markern umgeht, sowie in der Struktur und Verwaltung der gespeicherten Daten. Im Kern basiert das langsame Verhalten von ListObjects bei manchen Buckets auf den sogenannten Delete Markern, die bei aktiviertem Versioning eine zentrale Rolle spielen.
Sobald die Versionierung für einen Bucket aktiviert ist, wird bei jedem Löschen eines Objekts kein physisches Löschen der Datei vorgenommen. Stattdessen setzt S3 einen sogenannten Delete Marker als neue Version des Objekts. Diese Marker signalisieren, dass die aktuelle Version des Objekts als gelöscht gilt. Für den Benutzer erscheinen diese gelöscht, tatsächlich sind die Daten jedoch weiterhin gespeichert. Dies bringt für S3 bei Aufruf von ListObjects eine zusätzliche Herausforderung mit sich.
Der Dienst muss nämlich alle Delete Marker durchgehen, um zu verstehen, welche Versionen als gelöscht gelten und diese aus dem Resultat entfernen. Je mehr Delete Marker also in einem Bucket existieren, desto aufwändiger wird diese Filterung. In einer Bucket-Struktur mit vielen Millionen Objekten führt das zu erheblichen Verzögerungen. So zeigt der Fall eines Buckets, der über mehrere Jahre genutzt und in dem unzählige Dateien gelöscht wurden, dass das Auflisten ohne Einschränkung durch Präfixe extrem langsam wird. Im Vergleich dauert das Listen des gesamten Buckets bis zu 120 Sekunden, während das Filtern auf bestimmte Präfixe (zum Beispiel einen Buchstaben) nur wenige Millisekunden in Anspruch nimmt.
Der Grund hierfür ist, dass S3 beim Auflisten mit einem Präfix viel schneller die relevanten Teilbereiche durchsuchen kann und nur eine kleine Menge an Daten verarbeitet werden muss. Ein vollständiges Listing hingegen muss durch sämtliche Einträge inklusive der Delete Marker scannen, was die Leistung drastisch mindert. Darüber hinaus gibt es Phänomene, die als Cold Start bekannt sind – das erstmalige Auflisten nach längerer Inaktivität kann besonders langwierig sein. Das liegt daran, dass S3 intern Caches und Indizes nutzen muss, die zunächst aufgewärmt werden müssen, bevor das Listing flotter ablaufen kann. Branchenbeobachtungen zeigen, dass solche Starts bis zu 30 Sekunden oder mehr dauern können, ehe die normale Performance erreicht wird.
Ein weiterer Aspekt ist die Datenorganisation innerhalb des Buckets. Moderne Anwendungen wie Databend nutzen beispielsweise Zeit-basierte UUIDs (UUIDv7) in Objekt-Pfaden, um eine lexikographisch sortierte Reihenfolge zu erreichen. Dadurch kann ListObjects gezielt und schnell auf einen Teil des Buckets zugreifen. Problemlos scheint dies jedoch erst, wenn die Bucket-Größe und Anzahl der Delete Marker überschaubar bleiben. Werden jedoch große Datenmengen gelöscht und Versionen mit Delete Markern überschüttet, wird selbst diese Optimierung an ihre Grenzen stoßen.
Warum ist das Handling von Delete Markern eine Herausforderung für die S3-Infrastruktur? Die Antwort liegt in der Notwendigkeit einer konsistenten Sicht auf die Objektversionen. Die Delete Marker verhindern, dass gelöschte Versionen in Listen auftauchen, was für den Anwender intuitiv richtig ist. Gleichzeitig muss S3 aber weiterhin seine interne Versionskontrolle aufrechterhalten, um etwaige Wiederherstellungen oder Prüfungen zu ermöglichen. Diese Kopplung führt dazu, dass ListObjects Operations im schlimmsten Fall durch eine Vielzahl von Versionseinträgen inklusive Delete Marker laufen, was zu erheblichen Verzögerungen führt. Wie können Anwender dieses Problem umgehen oder zumindest abmildern? Ein entscheidender Hebel ist die Verwendung von Lifecycle Policies, welche automatisch Delete Marker und alte Versionen entfernen können.
Mit einer wohlkonfigurierten Lebenszyklusverwaltung können nicht mehr benötigte Versionen und Marker nach einer bestimmten Zeit gelöscht werden, wodurch der Bucket sauber und performant bleibt. Dadurch verringert sich der Overhead bei ListObjects erheblich, da weniger Elemente durchsucht werden müssen. Neben der Anwendung von Lifecycle Rules sollten Betroffene auch prüfen, ob die Versionierung für den jeweiligen Anwendungsfall unbedingt notwendig ist. Da die Versionierung zusätzlichen Speicherplatz und komplexere Verwaltung verursacht, kann sie bei unkritischen Szenarien deaktiviert oder durch alternative Backup-Strategien ersetzt werden. Zudem empfiehlt es sich, beim Listen nach Möglichkeit mit Präfixen oder sogar S3 Select zu arbeiten, um den abgerufenen Objektumfang einzuschränken und dadurch bessere Antwortzeiten zu erzielen.
Beim Design von datenintensiven Anwendungen, die S3 als Speicher nutzen, sollte auch die Datenstruktur selbst beachtet werden. Die Nutzung von zeitlich sortierten Schlüsselpräfixen kann die Suche und das Auflisten beschleunigen. Gleichzeitig sollte jedoch ein Augenmerk darauf gelegt werden, gelöschte oder veraltete Daten regelmäßig per Cleanup-Prozess oder Vacuum-Aufgaben zu entfernen, um die Bucket-Größe nicht unnötig zu erhöhen. Als Beispiel zeigt der Einsatz von Rust-basierten Bibliotheken wie OpenDAL, die einheitliche APIs für verschiedene Speicherformate bereitstellen und mit eingebauten Timeout-Funktionen Probleme wie das übermäßige Warten bei ListOperations adressieren können. Dennoch bleibt der grundlegende Flaschenhals beim Storage-Backend selbst.
Entwickler und Betreiber sollten daher auch immer eine Realitätsprüfung der Infrastruktur sowie Metriken der Bucketgröße und Versionen durchführen. Die Erkenntnisse aus der Praxis machen deutlich, dass S3, trotz seiner vielfach bewährten Stabilität, bei bestimmten Einsatzszenarien an Grenzen stößt. Große Buckets mit aktivierter Versionierung und vielen gelöschten Objekten bergen ein Risiko für Performanceeinbrüche, die sich maßgeblich durch richtiges Lifecycle-Management und präzises Datenhandling reduzieren lassen. Abschließend bleibt zu sagen, dass S3 Versionierung eine nützliche Funktion ist, die aber nicht ohne Kosten kommt. Wer sie aktiviert, sollte sich bewusst sein, dass sie zusätzlichen Verwaltungsaufwand nach sich zieht und gegebenenfalls Optimierungsmaßnahmen eingeführt werden müssen.
Ein kontinuierliches Monitoring und frühzeitiges Eingreifen bei Anzeichen von Performanceverschlechterungen ist essenziell, um langfristig schnelle und zuverlässige Zugriffe auf Objektdaten sicherzustellen. Im Ergebnis nimmt die Dauer von ListObjects-Anfragen stark zu, wenn ein Bucket eine große Anzahl an Delete Markern enthält, was auf die Art und Weise zurückzuführen ist, wie S3 Versionierung verwaltet. Lösungswege bestehen vor allem im regelmäßigen Entfernen dieser Marker, der überlegten Nutzung von Präfixen sowie der Anpassung der Versionierungsstrategie. Wer diese Faktoren berücksichtigt, kann die Leistung beim S3-Listing erheblich verbessern und Wartezeiten von über einer Minute vermeiden.