Exportação Multipart e Grandes Descarga
1) Quando você precisa de exportações «grandes» e o que é importante
Cenários: relatórios financeiros, download de usuários, auditorias/reguladores, downloads BI, diretórios associados, cópias de segurança. Requisitos essenciais:- Coerência de dados (snapshot/ponto no tempo).
- Passagem em volume (entrada/leitura paralela, seriado em streaming).
- Renovabilidade (resumable) e entrega parcial.
- Integridade (checksum) e credibilidade (manifesto).
- Segurança/PII (camuflagem, criptografia, controle de acesso).
- Controle de custo (compressão, temporais, CDN, TTL).
2) Formatos de dados: prós/contras
CSV - compacto, escrever/ler rápido; contras: telas, tipos perdidos. Bom para os relatórios de tabela.
JSON Lines (JSONL) - linha por objeto, fácil de fazer streaming e amostra parcial; contras: volume.
Parquet/Avro - formatos de invertebrados/esquemas, compressão e predicate pushdown; perfeito para analistas e grandes dados.
Mixed: JSONL para API → conversão off-line no Parquet.
Compressão: 'gzip '/' zstd' (melhor). Para grandes quantidades, arquivos split (por £128-512 MB por parte).
3) Coerência: como obter uma «foto»
BD: isolamento transacional REPEATABLE READ/SNAPSHOT; para os fluxos - slots lógicos de replicação ou marca 'watermark' (máxima 'updated _ at '/versão).
Event surcing: exportação por offset journal.
Corte: exportação «completa» + «delta» (a partir de «watermark»).
4) Dividir em partes (multipart/chunking)
4. 1 Vistas «multipart»
Upload (a nós): multiplart/forma-data (arquivos pequenos), S3 Multiplart Upload (MPU )/GCS Resumable (grandes).
Download (de nós): HTTP Range ('bytes = start-end'), 'multipart/byteranges' (várias faixas na mesma resposta), 'zip of parts', diretórios no estoque de objetos.
4. 2 Estratégias de partilha
Em tamanho (por exemplo, 256 MB por parte).
Por chave/data («tenant _ id», «YYYY/MM/DD»).
Por tabela/entidade (arquivos individuais por tipos).
Balanço: partes de 64-512 MB são bem baixadas paralelamente e não superaquecem a memória.
5) API de exportação (modelo asincrona)
Passos:1. 'POST/exports' → a tarefa na fila (metadados: formato, filtros, criptografia, tempo de vida).
2. Os worker constroem snapshot, removem dados e escrevem partes no armazém de objetos.
3. Geram um manifesto (JSON) com uma lista de partes, tamanhos, checksum, uma versão do esquema.
4. 'GET/exports/diante de se identificar' devolve o status e o link (e) para as partes/pré-assined do URL.
5. `GET /exports/{id}/manifest. json 'é uma máquina da verdade para verificação/pré-teste.
Exemplo de 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) Descarga renovável (resumable)
HTTP Range: o cliente grava a «cauda» do arquivo: 'Range: bytes = 241172480-'.
Várias faixas: 'Range: bytes = 0-999,2000-2999' → resposta 'Conteúdo-Tipo: multipart/byteranges'.
Estratégia do cliente: «workers» paralelos em partes, verificação de «sha256» cada, retais com backoff exponencial.
CDN: suporte Range, tampão de respostas maiores desligado.
7) Grandes downloads para nós (resumable upload)
S3 Multiplart Upload: clientes carregam partes (5-5.000) e o servidor recolhe 'CompleteMultipartUpload'.
GCS Resumable: uma sessão, deslocamentos - O cliente pode continuar com o Conteúdo-Range.
O TUS (protocolo) é um apload renovável independente sobre HTTP.
Pattern B2B: Damos o URL pré-assined para a aplicação de partes diretamente para o store e metadados para a nossa API.
8) Compressão, criptografia, integridade
Compressão: 'zstd' é preferível (melhor ratio/velocidade). Estreite cada parte separadamente (mais fácil de reabrir/armazenar).
Criptografia:- TLS 1 no fio. 2+.
- Em paz: server-side KMS (SSE-KMS) ou cliente-side (AES-256-GCM) com a chave (key wrapping).
- Nunca coloque a chave crua no manifesto.
- Checksum: mínimo SHA-256 por parte + total para conjunto. Verifique o cliente antes da ack.
9) Integração com perímetro: NGINX/CDN
NGINX (Range + grandes temporizadores + desativar tampão):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;
}
}
Cabeçalhos de respostas:
- `Content-Disposition: attachment; filename="export_2025-10-31_part-00000. parquet. zst"`
- 'ETAG '/' If-Range' para o ajuste correto.
- 'Cachê-controle' (por exemplo, 'private, max-age = 3600') para descarregamentos pessoais.
10) Segurança e complacência
Autenticação/autorização: emissão de exportação somente para o proprietário/papel; links temporários (pré-assined) com TTL curto.
PII: camuflagem/pseudonimização; no manifesto, apenas campos técnicos.
GDPR/reguladores locais: remoção de exportações por TTL, auditoria de downloads, proibição de emissão regional cruzada sem fundamento.
Rate limiting & cotas: limitar o número de exportações simultâneas e o volume total por dia/mês (per-tenant).
Anti-scraping: Filtros RP/bot para a emissão de links, limitação de intervalo (partes paralelas máximas).
11) Observabilidade e exploração
Métricas:- `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`
- Quem criou exportação, filtros, watermark, lista de downloads (IP/UA/tempo).
- Hasteamento de partes e acerto no lado do cliente (confirmação).
- Span para etapas: snapshot → serialize → upload partt → finalize.
12) Desempenho e custo
Paralelismo: Gere várias partes simultaneamente (N worker), mas limite I/O.
Memória: Serigrafia por streaming (iteradores, cursores BD, chancas de 4-16 MB).
Deadup: Para exportações frequentemente repetidas, um cache of parts inteligente em filtros/hashtag.
CDN: Benéfico para conjuntos públicos «comuns»; para pessoais - cuidado (segurança/PII).
13) Exemplos de interface
13. 1 Criação de Exportação (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"}
}
Resposta:
json
{
"id":"exp_2025_10_31_001",
"status":"queued",
"estimated_parts": 12,
"manifest_url": "/exports/exp_2025_10_31_001/manifest. json"
}
13. 2 Emissão de parte com Range
http
GET /exports/exp_.../part-00003. parquet. zst
Range: bytes=1048576-
13. 3 Pseudocode de 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) Patternas de exportação delta
Exportação completa para N (dia/semana) + delta a cada hora por 'updated _ at> watermark'.
Para o lado do consumidor, aplicar os delta de acordo com a ordem de «version »/« seq».
Guarde o último watermark no consumidor e no manifesto.
15) Anti-pattern
Geração de exportação na consulta (sincronizado) - timeouts e OU.
Um arquivo gigante sem partilha é a impossibilidade de reativar ou fazer o download paralelo.
Falta de checksum e manifesto - não se pode provar integridade.
Emite links públicos constantes para dados pessoais.
O tampão SSE/CDN ou Range desativado rompe o «pré-acionamento».
Exportar dados «sujos» (sem snapshot/isolamento).
16) Folha de cheque de implementação
- Formato e compressão: CSV/JSONL/Parquet + 'zstd/gzip'.
- Coerência: snapshot transacional ou watermark/offset.
- Partilha: partes 64-512 MB, geração paralela e download.
- Manifesto: lista de partes, dimensões, SHA-256, versão de circuito, watermark.
- Reabertura: HTTP Range, suporte para 'multipart/byteranges', retais de clientes.
- Segurança: pré-signed OUTMs, TTL, criptografia (KMS/AEAD), camuflagem PII.
- Os limites/quotas são: per-tenant, quantidades diárias, número de propriedades ativas.
- Observabilidade: métricas/partes, auditoria de downloads, alertas em checksum-fail.
- Custo: CDN para conjuntos públicos, TTL e auto-cleanup no estoque.
- Runbooks/Game Days: falhas de rede, indisponibilidade, superaquecimento do banco de dados, falha do KMS.
17) Game Days (playbooks)
Desabamento da rede no download: o cliente deve continuar com 'Range'.
Falha ao carregar uma parte: parte retraí sem reencontrar todas as exportações.
A queda do worker, o jobs, reabre com a última chanca não confirmada.
O KMS não está disponível: degradação segura (interrupção de geração, não execrado).
Crescimento de dados x 2: verificar o tempo de geração, redistribuir o paralelismo, não matar o BD.
18) Resultado
Grandes embarques confiáveis são arquitetura asíncrona + divisão em partes + retomada + integridade verificável. Faça snapshot, escreva partes paralelas, publique um manifesto checksum, suporte HTTP Range e links curtos. Pensem em segurança, limites e observabilidade, e as exportações gigabytes deixarão de ser um pesadelo para as equipes e usuários.