GH GambleHub

Esportazioni multipart e grandi scarichi

1) Quando è necessario esportare «grandi» e cosa è importante

Script: report finanziari, caricamento utente, controllo/regolatori, download BI, cartelle di partner, backup. Requisiti chiave:
  • Coerenza dei dati (snapshot/point nel tempo).
  • Viabilità volumica (scrittura/lettura parallela, serializzazione in streaming).
  • Rinnovabile (resumable) e spedizione parziale.
  • Integrità (checksum) e validità (manifesto).
  • Sicurezza/PII (occultamento, crittografia, controllo degli accessi).
  • Gestione del costo (compressione, timeout, CDN, TTL).

2) Formati di dati: pro/contro

CSV - compatto, scrivere/leggere rapidamente; contro: schermatura, i tipi vengono persi. Bene per i tabulati.
JSON Lines (JSONL) - riga per oggetto, facile da usare per lo streaming e il campionamento parziale; contro: volume.
Parquet/Avro - formati colinvertebrati/schemi, compressione e predicate pushdown; Ideale per gli analisti e i dati di grandi dimensioni.
Mixed: JSONL per il caricamento API della conversione offline in Parket.

Compressione: «gzip »/« zstd» (migliore). Per volumi molto elevati, gli archivi split (da 128 a 512 MB per parte).

3) Coerenza: come ottenere un'istantanea "

Database: isolamento transazionale REPEATABLE READ/SNAPSHOT; per i thread: slot logiche di replica o segno «watermark» (max «updated _ at »/versione).
Event source - Esporta per offset il registro.
Taglio: esportazione «completa» + «delta» (successivi download di modifiche da «watermark»).

4) Ripartizione (multipart/chunking)

4. 1 Viste multipart

Upload (a noi): multiplart/form-data (file piccoli), S3 Multipart Upload (MPU )/GCS Resumable (grandi).
Download (da noi): HTTP Range ('byties = start-end'), 'multipart/byteranges' (più intervalli nella stessa risposta), 'zip of parts', cartelle nello store degli oggetti.

4. 2 Strategie di ripartizione

Per dimensioni (ad esempio 256 MB per parte).
Per chiave/data («tenant _ id», «YYYY/MM/DD»).
Per tabella/entità (singoli file per tipo).

Bilanciamento: le parti 64-512 MB si scaricano bene in parallelo e non surriscaldano la memoria.

5) Architettura API di esportazione (modello asincrona)

Passi:

1. 'POST/exports', processo in coda (metadati: formato, filtri, crittografia, durata della vita).

2. I worker costruiscono snapshot, cancellano i dati e scrivono le parti nel deposito oggetti.

3. Generano un manifesto (JSON) con un elenco di parti, dimensioni, checksum, versione dello schema.

4. 'GET/exports/{ id}' restituisce lo stato e il riferimento (e) alle parti/pre-signed URL.

5. `GET /exports/{id}/manifest. json'è una macchina della verità per la verifica/controllo.

Esempio di manifesto:
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) Scarichi rinnovabili (resumable)

HTTP Range: il client esegue la coda del file: 'Range: byties = 241172480'.
Più intervalli: «Range: byties = 0-999,2000-2999», risposta «Content-Type: multipart/byteranges».
Strategia dei clienti: «worker» paralleli a pezzi, verifica «sha256» ciascuno, retrai con backoff esponenziale.
CDN - Supporto Range, buffer di grandi risposte disattivato.

7) Grandi download a noi (resumable upload)

S3 Multiplart Upload: i client caricano parti (5-5000) e il server raccoglie «CompleteMultipartUpload».
GCS Resumable: una sessione, offset - il client può continuare con Content-Range.
Il TUS (protocollo) è un appload indipendente e rinnovabile sopra HTTP.

Pattern B2B: assegniamo l'URL pre-signed per l'applicazione delle parti direttamente allo store e i metadati alla nostra API.

8) Compressione, crittografia, integrità

Compressione: «zstd» è preferibile (migliore ratio/velocità). Comprimi ciascuna parte separatamente (è più facile riprendere/memorizzare la cache).

Crittografia:
  • TLS 1 sul filo. 2+.
  • In linea: server-side KMS (SSE-KMS) o client-side (AES-256-GCM) con avvolgimento chiave (key wrapping).
  • Non mettere mai la chiave cruda nel manifesto.
  • Checksum: minimo SHA-256 per parte + totale per l'intero set. Controllare il client prima di ack.

9) Integrazione con perimetro: NGINX/CDN

NGINX (Range + grandi timeout + disattivare buffering):
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;
}
}
Titoli di risposta:
  • `Content-Disposition: attachment; filename="export_2025-10-31_part-00000. parquet. zst"`
  • «ETAG »/« If-Range» per un corretto controllo.
  • «Cache-Control» (ad esempio, «private, max-age = 3600») per i download personali.

10) Sicurezza e compliance

Autenticazione/autorizzazione: rilascio di esportazioni solo al proprietario/ruolo; collegamenti temporanei (pre-signed) con TTL breve.
PII: maschera/alias; nel manifesto ci sono solo campi tecnici.
GDPR/regolatori locali: rimozione di esportazioni TTL, controllo dei download, divieto di rilascio crociato-regionale senza motivo.
Rate limiting & quote: limita il numero di esportazioni simultanee e il volume totale al giorno/mese (per-tenant).
Anti-scraping: filtri SAR/Bot per il rilascio di riferimenti, limiti di intervalli (parti parallele massime).

11) Osservabilità e funzionamento

Metriche:
  • `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`
Logi/verifiche:
  • Chi ha creato l'esportazione, filtri, watermark, l'elenco dei download (IP/UA/tempo).
  • Hash parti e compressione sul lato client (conferma).
Tracing:
  • Span per fasi: snapshot → serialize → upload part → finalize.

12) Prestazioni e costi

Parallelità: generate più parti contemporaneamente (N worker), ma limitate I/O.
Memoria: seriatizzazione in streaming (iteratori, cursori di database, chanci da 4 a 16 MB).
Per le esportazioni frequenti, cache of parts intelligente per filtri/hashtag.
CDN: utile per i set pubblici «condivisi» personale - attenzione (sicurezza/PII).

13) Esempi di interfaccia

13. 1 Creazione esportazione (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"}
}
Risposta:
json
{
"id":"exp_2025_10_31_001",
"status":"queued",
"estimated_parts": 12,
"manifest_url": "/exports/exp_2025_10_31_001/manifest. json"
}

13. 2 Rilascio parte con Range

http
GET /exports/exp_.../part-00003. parquet. zst
Range: bytes=1048576-

13. 3 Pseudocode worker

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) Pattern delta-export

Esportazione completa una volta in N (giorno/settimana) + delta ogni ora à updated _ at> watermark '.
Dal lato del consumatore, applicare i delta in ordine, con la validazione dì version "/" seq ".
Conservare l'ultimo watermark nel consumatore e nel manifesto.

15) Anti-pattern

Generazione di esportazione nella query (sincrona) - Timeout e OOM.
Un file gigantesco non diviso è l'impossibilità di riprendere o scaricare parallelamente.
L'assenza di checksum e di un manifesto non può essere dimostrata.
Rilascia collegamenti pubblici costanti ai dati personali.
Buffer SSE/CDN o Range disattivate - Rompe il dosaggio.
Esporta dati «sporchi» (senza snapshot/isolante).

16) Assegno-foglio di implementazione

  • Formato e compressione: CSV/JSONL/Parket + 'zstd/gzip'.
  • Coerenza: snapshot transazionale o watermark/offset.
  • Partizione: parti 64-512 MB, generazione e download paralleli.
  • Manifesto: elenco di parti, dimensioni, SHA-256, versione schema, watermark.
  • Riapertura: HTTP Range, supporto «multipart/byteranges», retrai client.
  • Protezione: pre-signed URLs, TTL, crittografia (KMS/AEAD), maschera PII.
  • Limiti/quote: per-tenant, quantità giornaliere, numero di attivi.
  • Osservabilità: metriche delle parti, controllo dei download, alert per checksum-fail.
  • Costo: CDN per set pubblici, TTL e auto-cleanup nello store.
  • Runbooks/Game Days - Scollature della rete, indisponibilità dello store, surriscaldamento del database, errore di KMS.

17) Game Days (playbook)

Dirottamento della rete durante il download: il client deve continuare con Range.
Impossibile caricare una parte, il retro della parte senza ritardare l'intera esportazione.
La caduta del Worker, il jobs, riparte dall'ultima chat non confermata.
KMS non disponibile: degrado sicuro (pausa di generazione, non crittografia).
Crescita dei dati x 2: controllare i tempi di generazione, ridistribuire il parallelismo, non uccidere il database.

18) Riepilogo

Grandi carichi di lavoro affidabili: architettura asincrona + ripartenza + integrità verificabile. Fai snapshot, scrivi parti parallele, pubblichi un manifesto con checksum, supporta HTTP Range e collegamenti brevi. Pensate alla sicurezza, ai limiti e all'osservabilità - e gli esporti gigabyte non saranno più un incubo per le squadre e gli utenti.

Contact

Mettiti in contatto

Scrivici per qualsiasi domanda o richiesta di supporto.Siamo sempre pronti ad aiutarti!

Telegram
@Gamble_GC
Avvia integrazione

L’Email è obbligatoria. Telegram o WhatsApp — opzionali.

Il tuo nome opzionale
Email opzionale
Oggetto opzionale
Messaggio opzionale
Telegram opzionale
@
Se indichi Telegram — ti risponderemo anche lì, oltre che via Email.
WhatsApp opzionale
Formato: +prefisso internazionale e numero (ad es. +39XXXXXXXXX).

Cliccando sul pulsante, acconsenti al trattamento dei dati.