Zum Inhalt springen

S3-API-Unterstützung

Die httpfs-Erweiterung unterstützt das Lesen, Schreiben und Globbing von Dateien auf Objektspeicher-Servern über die S3-API. S3 bietet eine Standard-API zum Lesen und Schreiben entfernter Dateien (während gewöhnliche HTTP-Server, die älter als S3 sind, keine gemeinsame Schreib-API anbieten). DuckDB entspricht der S3-API, die inzwischen bei Speicheranbietern der Branche üblich ist.

Plattformen

Das Dateisystem httpfs wird mit AWS S3, Minio, Google Cloud und lakeFS getestet. Andere Dienste, die die S3-API implementieren (etwa Cloudflare R2, SeaweedFS und Tigris), sollten ebenfalls funktionieren, aber nicht alle Funktionen müssen unterstützt sein.

Die folgende Tabelle zeigt, welche Teile der S3-API für die jeweilige httpfs-Funktion erforderlich sind.

Funktion Erforderliche S3-API-Funktionen
Öffentliches Lesen von Dateien HTTP-Range-Anfragen
Privates Lesen von Dateien Authentifizierung mit Secret Key oder Session Token
Datei-Glob ListObjectsV2
Schreiben von Dateien Multipart-Upload

Konfiguration und Authentifizierung

Der bevorzugte Weg zur Konfiguration und Authentifizierung gegenüber S3-Endpunkten ist die Verwendung von Secrets. Es stehen mehrere Secret-Provider zur Verfügung.

Zur Migration von der veralteten S3-API verwenden Sie ein definiertes Secret mit einem Profil. Siehe Profil auswählen.

Provider config

Der Standard-Provider config (d. h. benutzerkonfiguriert) ermöglicht den Zugriff auf den S3-Bucket durch manuelle Angabe eines Schlüssels. Zum Beispiel:

CREATE OR REPLACE SECRET secret (
TYPE s3,
PROVIDER config,
KEY_ID '⟨AKIAIOSFODNN7EXAMPLE⟩',
SECRET '⟨wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY⟩',
REGION '⟨us-east-1⟩'
);

Tip Wenn Sie einen IO-Fehler erhalten (Connection error for HTTP HEAD), konfigurieren Sie den Endpunkt explizit über ENDPOINT 's3.⟨your-region⟩.amazonaws.com'{:.language-sql .highlight}.

Um mit dem obigen Secret abzufragen, fragen Sie einfach eine Datei mit dem Präfix s3:// ab:

SELECT *
FROM 's3://⟨your-bucket⟩/⟨your_file⟩.parquet';

Provider credential_chain

Der Provider credential_chain holt Anmeldedaten automatisch über das AWS SDK (Profile, SSO, angenommene Rollen, Web Identities, Instance Metadata und mehr). Er wird von der aws-Erweiterung bereitgestellt. Beispiel für den Standard-Provider des AWS SDK:

CREATE OR REPLACE SECRET secret (
TYPE s3,
PROVIDER credential_chain
);

Die vollständige Menge der credential_chain-Optionen — CHAIN-Werte, Profilauswahl, angenommene Rollen, SSO, Web Identity (IRSA), Regionsauflösung, Validierung und automatische Aktualisierung — finden Sie auf der Seite der AWS-Erweiterung.

Überblick der S3-Secret-Parameter

Nachfolgend eine vollständige Liste der unterstützten Parameter, die sowohl für die Provider config als auch credential_chain verwendet werden können:

Name Beschreibung Secret Typ Standard
ENDPOINT Einen eigenen S3-Endpunkt angeben S3, GCS, R2 STRING s3.amazonaws.com für S3,
KEY_ID Die ID des zu verwendenden Schlüssels S3, GCS, R2 STRING -
REGION Die Region, für die authentifiziert wird (sollte zur Region des abzufragenden Buckets passen) S3, GCS, R2 STRING us-east-1
SECRET Das Secret des zu verwendenden Schlüssels S3, GCS, R2 STRING -
SESSION_TOKEN Optional kann ein Session-Token übergeben werden, um temporäre Anmeldedaten zu nutzen S3, GCS, R2 STRING -
URL_COMPATIBILITY_MODE Kann helfen, wenn URLs problematische Zeichen enthalten S3, GCS, R2 BOOLEAN true
URL_STYLE Entweder vhost (Alias virtual) oder path S3, GCS, R2 STRING vhost für S3, path für R2 und GCS
USE_SSL Ob HTTPS oder HTTP verwendet wird S3, GCS, R2 BOOLEAN true
VERIFY_SSL Ob das SSL-Zertifikat des Servers geprüft wird S3, GCS, R2 BOOLEAN true
ACCOUNT_ID Die R2-Konto-ID zur Erzeugung der Endpunkt-URL R2 STRING -
KMS_KEY_ID AWS-KMS-Schlüssel (Key Management Service) für serverseitige Verschlüsselung auf S3 S3 STRING -
REQUESTER_PAYS Ermöglicht die Nutzung von S3-Buckets mit „Requester Pays“ S3 BOOLEAN false
REFRESH Auf auto setzen, um Anmeldedaten regelmäßig zu aktualisieren (siehe die aws-Erweiterung) S3, GCS, R2 STRING -

Automatische Aktualisierung der Anmeldedaten

Unabhängig vom Secret-Parameter REFRESH aktualisiert DuckDB S3-Anmeldedaten automatisch, wenn eine Anfrage mit dem HTTP-Status 401 oder 403 fehlschlägt (z. B. wenn temporäre Anmeldedaten abgelaufen sind), und wiederholt die Anfrage. Dieses Verhalten wird durch die Einstellung httpfs_enable_credential_refresh gesteuert (BOOLEAN, Standard true):

SET httpfs_enable_credential_refresh = false;

Plattformspezifische Secret-Typen

S3-Secrets

Die httpfs-Erweiterung unterstützt serverseitige Verschlüsselung über den AWS Key Management Service (KMS) auf S3 mit der Option KMS_KEY_ID:

CREATE OR REPLACE SECRET secret (
TYPE s3,
PROVIDER credential_chain,
CHAIN config,
REGION '⟨eu-west-1⟩',
KMS_KEY_ID 'arn:aws:kms:⟨region⟩:⟨account_id⟩:⟨key⟩/⟨key_id⟩',
SCOPE 's3://⟨bucket-sub-path⟩'
);

R2-Secrets

Obwohl Cloudflare R2 die reguläre S3-API verwendet, hat DuckDB einen eigenen Secret-Typ R2, um die Konfiguration etwas zu vereinfachen:

CREATE OR REPLACE SECRET secret (
TYPE r2,
KEY_ID '⟨AKIAIOSFODNN7EXAMPLE⟩',
SECRET '⟨wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY⟩',
ACCOUNT_ID '⟨my_account_id⟩'
);

Beachten Sie die Ergänzung von ACCOUNT_ID, mit der die korrekte Endpunkt-URL für Sie erzeugt wird. Beachten Sie außerdem, dass R2-Secrets sowohl die Provider CONFIG als auch credential_chain verwenden können. Da DuckDB intern einen AWS-Client verwendet, sucht der Client bei credential_chain jedoch nach AWS-Anmeldedaten an den üblichen AWS-Stellen (Umgebungsvariablen, Credential-Dateien usw.). Ihre R2-Anmeldedaten müssen daher als AWS-Umgebungsvariablen (AWS_ACCESS_KEY_ID und AWS_SECRET_ACCESS_KEY) bereitstehen, damit die Credential Chain funktioniert. Schließlich sind R2-Secrets nur verfügbar, wenn URLs mit r2:// beginnen, zum Beispiel:

SELECT *
FROM read_parquet('r2://⟨some-file-that-uses-an-r2-secret⟩.parquet');

GCS-Secrets

Obwohl Google Cloud Storage von DuckDB über die S3-API angesprochen wird, hat DuckDB einen eigenen Secret-Typ GCS, um die Konfiguration etwas zu vereinfachen:

CREATE OR REPLACE SECRET secret (
TYPE gcs,
KEY_ID '⟨my_hmac_access_id⟩',
SECRET '⟨my_hmac_secret_key⟩'
);

Wichtig: Die Werte KEY_ID und SECRET müssen HMAC-Schlüssel sein, die speziell für die Interoperabilität mit Google Cloud Storage erzeugt wurden. Sie sind nicht dasselbe wie gewöhnliche GCP-Dienstkontoschlüssel oder Zugriffstoken. HMAC-Schlüssel können Sie gemäß der Google-Cloud-Dokumentation zur Verwaltung von HMAC-Schlüsseln anlegen.

Beachten Sie, dass das obige Secret automatisch den korrekten Google-Cloud-Storage-Endpunkt konfiguriert. Beachten Sie außerdem, dass GCS-Secrets sowohl die Provider CONFIG als auch credential_chain verwenden können. Da DuckDB intern einen AWS-Client verwendet, sucht der Client bei credential_chain jedoch nach AWS-Anmeldedaten an den üblichen AWS-Stellen (Umgebungsvariablen, Credential-Dateien usw.). Ihre GCS-HMAC-Schlüssel müssen daher als AWS-Umgebungsvariablen (AWS_ACCESS_KEY_ID und AWS_SECRET_ACCESS_KEY) bereitstehen, damit die Credential Chain funktioniert. Schließlich sind GCS-Secrets nur verfügbar, wenn URLs mit gcs:// oder gs:// beginnen, zum Beispiel:

SELECT *
FROM read_parquet('gcs://⟨some/file/that/uses/a/gcs/secret⟩.parquet');

Lesen

Das Lesen von Dateien aus S3 ist nun so einfach wie:

SELECT *
FROM 's3://⟨your-bucket⟩/⟨filename⟩.⟨extension⟩';

Teilweises Lesen

Die httpfs-Erweiterung unterstützt teilweises Lesen aus S3-Buckets.

Objektversionen festnageln

Standardmäßig liest eine länger laufende Abfrage ein Objekt in der Version, die zum Lesezeitpunkt aktuell ist; diese kann sich ändern, wenn das Objekt überschrieben wird. Setzen Sie s3_version_id_pinning (BOOLEAN, Standard false), um Lesevorgänge auf die Objektversion festzunageln, die beim ersten HEAD-Request erfasst wurde, sodass eine Abfrage eine konsistente Version sieht, auch wenn das Objekt mitten in der Abfrage überschrieben wird. Dazu ist der HTTP-Metadaten-Cache erforderlich:

SET enable_http_metadata_cache = true;
SET s3_version_id_pinning = true;

Mehrere Dateien lesen

Mehrere Dateien sind ebenfalls möglich, zum Beispiel:

SELECT *
FROM read_parquet([
's3://⟨your-bucket⟩/⟨filename-1⟩.parquet',
's3://⟨your-bucket⟩/⟨filename-2⟩.parquet'
]);

Globbing

Datei-Globbing wird über den API-Aufruf ListObjectsV2 umgesetzt und erlaubt dateisystemähnliche Glob-Muster, um mehrere Dateien zu treffen, zum Beispiel:

SELECT *
FROM read_parquet('s3://⟨your-bucket⟩/*.parquet');

Diese Abfrage trifft alle Dateien im Wurzelverzeichnis des Buckets mit der Parquet-Erweiterung.

Mehrere Matching-Funktionen werden unterstützt, etwa * für eine beliebige Anzahl beliebiger Zeichen, ? für ein einzelnes beliebiges Zeichen oder [0-9] für ein einzelnes Zeichen aus einem Zeichenbereich:

SELECT count(*) FROM read_parquet('s3://⟨your-bucket⟩/folder*/100?/t[0-9].parquet');

Eine nützliche Funktion beim Einsatz von Globs ist die Option filename, die eine Spalte namens filename hinzufügt, die die Datei kodiert, aus der eine bestimmte Zeile stammt:

SELECT *
FROM read_parquet('s3://⟨your-bucket⟩/*.parquet', filename = true);

Das könnte beispielsweise folgendes Ergebnis liefern:

column_a column_b filename
1 examplevalue1 s3://bucket-name/file1.parquet
2 examplevalue1 s3://bucket-name/file2.parquet

Hive-Partitionierung

DuckDB bietet außerdem Unterstützung für das Hive-Partitionierungsschema, das bei HTTP(S)- und S3-Endpunkten verfügbar ist.

Schreiben

Das Schreiben nach S3 verwendet die Multipart-Upload-API. Damit kann DuckDB Dateien robust und mit hoher Geschwindigkeit hochladen. Das Schreiben nach S3 funktioniert sowohl für CSV als auch für Parquet:

COPY table_name TO 's3://⟨your-bucket⟩/⟨filename⟩.⟨extension⟩';

Partitioniertes Kopieren nach S3 funktioniert ebenfalls:

COPY table TO 's3://⟨your-bucket⟩/partitioned' (
FORMAT parquet,
PARTITION_BY (⟨part_col_a⟩, ⟨part_col_b⟩)
);

Es wird automatisch geprüft, ob bereits Dateien/Verzeichnisse existieren; die Prüfung ist derzeit recht konservativ (und fügt auf S3 etwas Latenz hinzu). Um diese Prüfung zu deaktivieren und das Schreiben zu erzwingen, gibt es das Flag OVERWRITE_OR_IGNORE:

COPY table TO 's3://⟨your-bucket⟩/partitioned' (
FORMAT parquet,
PARTITION_BY (⟨part_col_a⟩, ⟨part_col_b⟩),
OVERWRITE_OR_IGNORE true
);

Das Namensschema der geschriebenen Dateien sieht so aus:

s3://⟨your-bucket⟩/partitioned/part_col_a=⟨val⟩/part_col_b=⟨val⟩/data_⟨thread_number⟩.parquet

Konfiguration

Für den S3-Upload gibt es einige zusätzliche Konfigurationsoptionen, die Standardwerte sollten jedoch für die meisten Anwendungsfälle ausreichen.

Name Beschreibung Standard
s3_uploader_max_parts_per_file Wird zur Berechnung der Teilgröße verwendet, siehe AWS-Dokumentation 10000
s3_uploader_max_filesize Wird zur Berechnung der Teilgröße verwendet, siehe AWS-Dokumentation 800GB
s3_uploader_thread_limit Maximale Anzahl von Uploader-Threads 50

Weitere S3-bezogene Einstellungen sind verfügbar und in der Konfigurationsreferenz dokumentiert, darunter enable_global_s3_configuration, merge_http_secret_into_s3_request, s3_allow_recursive_globbing, httpfs_enable_credential_refresh, s3_version_id_pinning und unsafe_disable_etag_checks.