Multipart-Exporte und große Uploads
1) Wenn „große“ Exporte benötigt werden und was wichtig ist
Szenarien: Finanzberichte, Upload von Benutzeraktivitäten, Audits/Regulatoren, BI-Uploads, Partnerverzeichnisse, Backups. Die wichtigsten Anforderungen sind:- Datenkonsistenz (Snapshot/Point in Time).
- Durchgängigkeit durch Volumen (paralleles Schreiben/Lesen, Streaming-Serialisierung).
- Erneuerbar (resumable) und teilweise Lieferung.
- Integrität (checksum) und Verifizierbarkeit (Manifest).
- Sicherheit/PII (Maskierung, Verschlüsselung, Zugriffskontrolle).
- Kostenmanagement (Kompression, Timeouts, CDN, TTL).
2) Datenformate: Vor-/Nachteile
CSV - kompakt, schnell zu schreiben/zu lesen; Nachteile: Abschirmung, Typen gehen verloren. Gut für tabellarische Berichte.
JSON Lines (JSONL) - pro Zeile pro Objekt, bequem für Streaming und teilweise Sampling; Nachteile: Volumen.
Parkett/Avro - Spalten/Schaltung Formate, Komprimierung und predicate pushdown; Ideal für Analytics und Big Data.
Mixed: JSONL für API-Uploads → Offline-Konvertierung in Parket.
Kompression: 'gzip '/' zstd' (besser). Für sehr große Mengen - Split-Archive (~ 128-512 MB pro Teil).
3) Konsistenz: Wie man eine „Momentaufnahme“ erhält
DB: transaktionale Isolation REPEATABLE READ/SNAPSHOT; für Threads die logischen Replikationssteckplätze oder die Markierung 'watermark' (max. 'updated _ at '/Version).
Event sourcing: Export durch Offset-Log.
Slices: „full“ export + „deltas“ (nachfolgende Uploads von Änderungen seit 'watermark').
4) Partitionierung (multipart/chunking)
4. 1 Arten von „multipart“
Upload (zu uns): multipart/form-data (kleine Dateien), S3 Multipart Upload (MPU )/GCS Resumable (große).
Download (von uns): HTTP Range ('bytes = start-end'), 'multipart/byteranges' (mehrere Bereiche in einer Antwort), "zip of parts', Verzeichnisse im Objektstore.
4. 2 Partitionierungsstrategien
Nach Größe (z.B. 256 MB pro Teil).
Nach Schlüssel/Datum (sharding by 'tenant _ id', 'YYYY/MM/DD').
Nach Tabelle/Entität (einzelne Dateien pro Typ).
Balance: 64-512 MB Teile werden gut parallel heruntergeladen und überhitzen den Speicher nicht.
5) Export-API-Architektur (asynchrones Modell)
Schritte:1. 'POST/exports' → einen Auftrag in der Warteschlange (Metadaten: Format, Filter, Verschlüsselung, Lebensdauer).
2. Worker bauen Snapshot, streamen Daten und schreiben Teile in den Objektspeicher.
3. Generieren Sie ein Manifest (JSON) mit einer Liste von Teilen, Abmessungen, checksum, Version des Schemas.
4. 'GET/exports/{ id}' gibt den Status und die Referenz (en) auf die Teile/pre-signed URL zurück.
5. `GET /exports/{id}/manifest. json 'ist eine Wahrheitsmaschine zum Verifizieren/Dosieren.
Beispiel für ein Manifest:json
{
"export_id": "exp_2025_10_31_001",
"created_at": "2025-10-31T14:23:00Z",
"schema": "orders_v3",
"format": "parquet+zstd",
"parts": [
{"name":"part-00000. parquet. zst","size":268435456,"sha256":"...","url":"...","range":"bytes=0-268435455"},
{"name":"part-00001. parquet. zst","size":241172480,"sha256":"...","url":"..."}
],
"total_bytes": 509607936,
"encryption": {"type":"AES-256-GCM","key_id":"kms/keys/exp"},
"watermark": {"type":"updated_at","value":"2025-10-31T00:00:00Z"}
}
6) Erneuerbare Entladungen (resumable)
HTTP Range: Der Client nimmt den „Schwanz“ der Datei auf: 'Range: bytes = 241172480-'.
Mehrere Bereiche: 'Range: bytes = 0-999,2000-2999' → die Antwort 'Content-Type: multipart/byteranges'.
Kundenstrategie: parallele „Worker“ in Teilen, Verifizierung von „sha256“ jeweils, Retrays mit exponentiellem Backoff.
CDN: Range-Unterstützung, deaktivierte Pufferung großer Antworten.
7) Große Downloads zu uns (resumable upload)
S3 Multipart Upload: Clients laden Teile hoch (5-5000), Server sammelt 'CompleteMultipartUpload'.
GCS Resumable: eine Sitzung, Offsets - der Client kann mit 'Content-Range' fortfahren.
TUS (Protokoll) ist ein unabhängiges, erneuerbares Apload über HTTP.
B2B-Muster: Wir geben die Pre-Signed-URL für die Apload-Teile direkt an den Stor und die Metadaten an unsere API.
8) Kompression, Verschlüsselung, Integrität
Kompression: 'zstd' bevorzugt (besseres Verhältnis/Geschwindigkeit). Komprimieren Sie jedes Teil separat (bequemer zu erneuern/zwischenspeichern).
Verschlüsselung:- Am Draht: TLS 1. 2+.
- Im Ruhezustand: Server-Side KMS (SSE-KMS) oder Client-Side (AES-256-GCM) mit Schlüsselverpackung (Key Wrapping).
- Legen Sie niemals einen „rohen“ Schlüssel in ein Manifest.
- Checksum: mindestens SHA-256 pro Teil + gemeinsam für das gesamte Set. Überprüfen Sie auf dem Client vor ack.
9) Integration mit Perimeter: NGINX/CDN
NGINX (Bereich + große Timeouts + Pufferung deaktivieren):nginx server {
listen 443 ssl http2;
server_name downloads. example. com;
location /exports/ {
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 3600s;
add_header Accept-Ranges bytes;
proxy_pass http://export-backend;
}
}
Antworten Titel:
- `Content-Disposition: attachment; filename="export_2025-10-31_part-00000. parquet. zst"`
- 'ETag '/' If-Range' zum korrekten Laden.
- „Cache-Control“ (z.B. „privat, max-age = 3600“) für persönliche Uploads.
10) Sicherheit und Compliance
Authentifizierung/Autorisierung: Erteilung von Ausfuhren nur an Inhaber/Rollen; temporäre Referenzen (pre-signed) mit kurzer TTL.
PII: Maskierung/Pseudonymisierung; Das Manifest enthält nur technische Felder.
DSGVO/lokale Regulierungsbehörden: Löschung von TTL-Exporten, Prüfung von Downloads, Verbot der cross-regionalen Ausgabe ohne Grundlage.
Rate limiting & quotas: Begrenzung der Anzahl gleichzeitiger Exporte und des Gesamtvolumens pro Tag/Monat (per-tenant).
Anti-Scraping: ATS/Bot-Filter für die Ausgabe von Links, Begrenzung der Bereiche (max. parallele Teile).
11) Beobachtbarkeit und Betrieb
Metriken:- `export_jobs_total{status}` (queued/running/succeeded/failed/expired)
- `export_bytes_total`, `export_part_duration_ms{p50,p95,p99}`
- `download_range_requests_total`, `resumes_total`, `checksum_fail_total`
- `storage_cost_estimate` и `egress_bytes_cdn`
- Wer hat den Export, Filter, Wasserzeichen, Download-Liste (IP/UA/Zeit) erstellt.
- Teile-Hashes und Abgleich auf Kundenseite (Bestätigungen).
- Spans in Stufen: snapshot → serialize → upload part → finalize.
12) Leistung und Kosten
Parallelität: mehrere Teile gleichzeitig erzeugen (N Worker), aber I/O begrenzen.
Speicher: Streaming-Serialisierung (Iteratoren, DB-Cursor, 4-16 MB Chunks).
Dedup: Für häufig wiederkehrende Exporte ein intelligenter Cache von Teilen durch Filter/Hash.
CDN: vorteilhaft für „allgemeine“ öffentliche Sets; für persönliche - Vorsicht (Sicherheit/PII).
13) Beispiele für Schnittstellen
13. 1 Export erstellen (REST)
http
POST /exports
Content-Type: application/json
Authorization: Bearer <token>
{
"format": "parquet+zstd",
"filters": {"date_from":"2025-10-01","date_to":"2025-10-31","tenant":"acme"},
"split_size_mb": 256,
"encryption": {"mode":"server-side-kms","key_id":"kms/keys/exp"}
}
Die Antwort lautet:
json
{
"id":"exp_2025_10_31_001",
"status":"queued",
"estimated_parts": 12,
"manifest_url": "/exports/exp_2025_10_31_001/manifest. json"
}
13. 2 Ausgabe des Teils mit Range
http
GET /exports/exp_.../part-00003. parquet. zst
Range: bytes=1048576-
13. 3 Pseudocode eines Workers
pseudo snapshot = db. begin_snapshot()
for shard in plan_shards(snapshot):
part_stream = encode_stream(shard. rows, format="parquet", compress="zstd")
url = object_store. upload_stream(part_stream, part_name, encryption=KMS)
manifest. add(part_name, size, sha256, url)
write_manifest(manifest)
14) Muster der Delta-Exporte
Vollständiger Export einmal pro N (Tag/Woche) + Deltas stündlich durch 'updated _ at> watermark'.
Auf der Verbraucherseite: Delta in der Reihenfolge anwenden, Verifizierung 'version '/' seq'.
Bewahren Sie die letzte Wassermarke im Verbraucher und im Manifest auf.
15) Anti-Muster
Export-Generierung in der Abfrage (synchron) - Timeouts und OOM.
Eine gigantische Datei ohne Partitionierung - Unmöglichkeit der Wiederaufnahme/paralleles Hochladen.
Mangel an checksum und Manifest - Integrität kann nicht bewiesen werden.
Ständige öffentliche Verweise auf personenbezogene Daten.
SSE/CDN-Pufferung oder deaktivierte Range - bricht das „Dosieren“.
Export von „schmutzigen“ Daten (ohne Snapshot/Isolation).
16) Checkliste Umsetzung
- Format und Kompression: CSV/JSONL/Parkett + „zstd/gzip“.
- Konsistenz: transaktionaler Snapshot oder Watermark/Offset.
- Partitionierung: 64-512 MB Teile, parallele Erzeugung und Download.
- Manifest: Stückliste, Abmessungen, SHA-256, Schemaversion, Wasserzeichen.
- Wiederaufnahme: HTTP Range, Unterstützung für 'multipart/byteranges', Client-Retrays.
- Sicherheit: vorsignierte URLs, TTL, Verschlüsselung (KMS/AEAD), PII-Maskierung.
- Grenzwerte/Quoten: per-tenant, Tagesmengen, Anzahl der aktiven Jobs.
- Beobachtbarkeit: Job-/Parts-Metriken, Download-Audit, Alerts auf checksum-fail.
- Kosten: CDN für öffentliche Sets, TTL und Auto-Cleanup im Stor.
- Runbooks/Game Days: Netzwerkabbrüche, Stora-Unzugänglichkeit, OBD-Überhitzung, KMS-Ausfall.
17) Spieltage (Playbooks)
Netzwerkabbruch beim Download: Der Client muss mit 'Range' fortfahren.
Fehler beim Laden eines Teils: Retrait des Teils, ohne den gesamten Export neu zu erstellen.
Worker Drop: Der Job wird mit dem letzten unbestätigten Chank wieder aufgenommen.
KMS nicht verfügbar: sichere Degradation (Generierungspause, nicht unverschlüsselt freigeben).
Datenwachstum × 2: Generationszeit prüfen, Parallelität umverteilen, DB nicht töten.
18) Ergebnisse
Zuverlässige große Uploads sind asynchrone Architektur + Partitionierung + Wiederaufnahme + überprüfbare Integrität. Machen Sie einen Snapshot, schreiben Sie Teile parallel, veröffentlichen Sie ein Manifest mit checksum, pflegen Sie den HTTP-Bereich und kurzlebige Links. Denken Sie an Sicherheit, Grenzen und Beobachtbarkeit - und Gigabyte-Exporte werden für Teams und Benutzer kein Albtraum mehr sein.