Eksport wielopartyjny i duże przesyłki
1) Kiedy „duży” eksport jest potrzebny i co jest ważne
Scenariusze: raporty finansowe, przesyłanie działań użytkowników, audyty/regulatory, przesyłanie BI, katalogi partnerów, kopie zapasowe. Kluczowe wymagania:- Spójność danych (migawka/punkt w czasie).
- Pasywność w woluminie (równoległe zapisywanie/odczytywanie, serializacja strumieniowa).
- Dostawa odnawialna i częściowa.
- Integralność (checksum) i weryfikowalność (manifest).
- Bezpieczeństwo/PII (maskowanie, szyfrowanie, kontrola dostępu).
- Zarządzanie kosztami (kompresja, timeouts, CDN, TTL).
2) Formaty danych: plusy/minusy
CSV - kompaktowe, szybkie do zapisu/odczytu; minusy: osłona, typy utracone. Dobre dla raportów tabelarycznych.
JSON Lines (JSONL) - według linii na obiekt, wygodne do strumieniowania i częściowego pobierania próbek; minus: objętość.
Parkiet/Avro - formaty kolumn/obwodów, kompresja i przewidywanie przepychania; idealny do analizy i dużych danych.
Mieszane: JSONL do API pobierz → konwersja offline do Parkiet.
Kompresja: 'gzip '/' zstd' (lepsza). Dla bardzo dużych woluminów - podzielone archiwa (~ 128-512 MB na część).
3) Spójność: Jak uzyskać „migawkę”
DB: POWTARZALNA izolacja transakcyjna odczytu/migawki; dla gwintów, gniazd do replikacji logicznej lub znaku wodnego (max. 'updated _ at '/version).
Źródło zdarzeń: eksport przez dziennik offsetowy.
Plasterki: „pełny” eksport + „deltas” (późniejsze przesyłanie zmian od 'znak wodny').
4) Multipart/chunking
4. 1 Rodzaje „multipart”
Prześlij (do nas): multipart/form-data (małe pliki), S3 Multipart Upload (MPU )/GCS Wznawialne (duże).
Pobierz (od nas): HTTP Range ('bytes = start-end'), 'multipart/byteranges' (kilka zakresów w jednej odpowiedzi), 'zip of parts', katalogi w stosie obiektu.
4. 2 Strategie podziału
Według rozmiaru (na przykład 256 MB na część).
Według klucza/daty (shading przez 'lokator _ id',' RRRY/MM/DD').
Według tabeli/podmiotu (poszczególne pliki w podziale na typy).
Balans: Części 64-512 MB pobrać dobrze równolegle i nie przegrzać pamięci.
5) Eksport architektury API (asynchroniczny model)
Kroki:1. 'POST/export' → zadanie w kolejce (metadane: format, filtry, szyfrowanie, żywotność).
2. Pracownicy budują migawki, dane strumieniowe i piszą części do magazynu obiektów.
3. Wygeneruj manifest (JSON) z listą części, rozmiarów, checksum, wersji schematu.
4. „GET/export/{ id}” zwraca status i łącze do części/wstępnie podpisanego adresu URL.
5. "GET/export/{ id }/manifest. json '- maszyna prawdy do weryfikacji/przeładunku.
Przykład jawi się następująco: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) Możliwe do wznowienia
Zakres HTTP: klient ładuje „ogon” pliku: 'Zakres: bajty = 241172480-'.
Wiele zakresów: 'Zakres: bajty = 0-999,2000-2999' → 'Content-Type: multipart/byteranges' response.
Strategia klienta: równoległe „pracownicy” w częściach, weryfikacja 'sha256' każdego, retrai z wykładniczym backoff.
CDN: Obsługa zakresu, duży bufor odpowiedzi wyłączony.
7) Duże pliki do pobrania do nas (wznawialne przesyłanie)
S3 Multipart Upload: klienci pobierają części (5-5000), serwer zbiera ' MultipartUpload'.
GCS Wznawialne - jedna sesja, offsety - klient może kontynuować 'Content-Range'.
TUS (protokół) to niezależne, odnawialne oklaski na szczycie HTTP.
Wzór B2B: wysyłamy wstępnie podpisany adres URL do przesyłania części bezpośrednio do sklepu, a metadane do naszego interfejsu API.
8) Kompresja, szyfrowanie, integralność
Kompresja: preferowane 'zstd' (lepszy stosunek/prędkość). Kompresować każdą część oddzielnie (wygodniej jest odnowić/cache).
Szyfrowanie:- Na drucie: TLS 1. 2+.
- W spoczynku: serwer-side KMS (SSE-KMS) lub klient-side (AES-256-GCM) z owinięciem klucza.
- Nigdy nie wkładaj „surowego” klucza do manifestu.
- Checksum: minimalna SHA-256 na część + wspólna dla całego zestawu. Sprawdź klienta przed ack.
9) Integracja obwodowa: NGINX/CDN
NGINX (Zakres + długie czasy + wyłączenie buforowania):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;
}
}
Nagłówki odpowiedzi:
- "Treść-dyspozycja: załącznik; nazwa pliku = "export _ 2025-10-31 _ part-00000. parkiet. zst"'
- 'ETag '/' If-Range' dla prawidłowego obciążenia.
- 'Cache-Control' (na przykład 'private, max-age = 3600') do osobistych przesyłek.
10) Bezpieczeństwo i zgodność
Uwierzytelnianie/autoryzacja: wystawianie eksportu wyłącznie do właściciela/ról; wstępnie podpisane z krótkim TTL.
PII: maskowanie/aliasing; w manifestze - tylko pola techniczne.
RODO/lokalne organy regulacyjne: usuwanie eksportu przez TTL, audyt pobierania, zakaz transgranicznej emisji bez powodu.
Ograniczenie stawek i kontyngentów: ograniczenie liczby równoczesnego wywozu i całkowitej ilości na dzień/miesiąc (w przeliczeniu na najemcę).
Anty-skrobanie: filtry CAP/bot do wydawania linków, zakresy ograniczające (maksymalnie równoległe części).
11) Obserwowalność i działanie
Metryka:- „export _ jobs _ total {status}” (w kolejce/running/succeeded/failed/expired)
- „export _ bytes _ total”, „export _ part _ duration _ ms {p50, p95, p99}”
- 'download _ range _ requests _ total', 'CV _ total', 'checksum _ fail _ total'
- "storage _ cost _ estimate" "egress _ bytes _ cdn'
- Kto stworzył eksport, filtry, znak wodny, listę pobierania (IP/UA/czas).
- Hashes części i uzgodnienia po stronie klienta (potwierdzenia).
- Przęsła: migawka → serialize → upload part → finalize.
12) Wydajność i koszt
Paralelizm: Generować wiele części jednocześnie (N pracowników), ale ograniczyć I/O.
Pamięć: serializacja strumieniowa (iteratory, kursory bazy danych, kawałki 4-16 MB).
Dedup: dla często powtarzanego eksportu, inteligentna pamięć podręczna części przez filtry/hash.
CDN: korzystne dla „generycznych” zbiorów publicznych; dla osobistej ostrożności (bezpieczeństwo/PII).
13) Przykłady interfejsów
13. 1 Utwórz eksport (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"}
}
Odpowiedź:
json
{
"id":"exp_2025_10_31_001",
"status":"queued",
"estimated_parts": 12,
"manifest_url": "/exports/exp_2025_10_31_001/manifest. json"
}
13. 2 Część emisyjna z zakresem
http
GET /exports/exp_.../part-00003. parquet. zst
Range: bytes=1048576-
13. Pseudokod 3 Vorkera
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) Wzory eksportu delta
Pełny eksport raz w N (dzień/tydzień) + delty co godzinę przez 'updated _ at> watermark'.
Po stronie konsumenta należy zastosować delty w kolejności poprzez sprawdzenie 'wersji '/' następnej'.
Przechowywać ostatni znak wodny w konsument i w manifest.
15) Anty-wzory
Generowanie eksportu w żądaniu (synchroniczne) - timeouts i OOM.
Jeden gigantyczny plik bez podziału to niemożność wznowienia/pobrania równoległego.
Brak checksum i manifestu - nie można udowodnić integralności.
Wydawanie stałych publicznych linków do danych osobowych.
Buforowanie SSE/CDN lub wyłączony zakres - przerywa „przeładowanie”.
Eksportuj brudne dane (bez migawki/izolacji).
16) Lista kontrolna wdrażania
- Format i kompresja: CSV/JSONL/Parquet + 'zstd/gzip'.
- Spójność: migawka transakcyjna lub znak wodny/offset.
- Partytura: 64-512 MB części, generacja równoległa i pobieranie.
- Manifest: lista części, wymiary, SHA-256, wersja schematu, znak wodny.
- Odnowienie: HTTP Range, wsparcie „multipart/byteranges”, przekaźniki klienta.
- Bezpieczeństwo: wstępnie podpisane adresy URL, TTL, szyfrowanie (KMS/AEAD), maskowanie PII.
- Limity/kwoty: na najemcę, dzienne wolumeny, liczba aktywnych miejsc pracy.
- Obserwability: job/part metrics, download audits, checksum-fail alerts.
- Koszt: CDN dla zestawów publicznych, TTL i automatycznego czyszczenia w sklepie.
- Runbooks/Game Days: przerwy w sieci, niedostępność sklepu, przegrzanie bazy danych, awaria KMS.
17) Dni gry (playbooks)
Spadek sieci podczas pobierania: Klient musi kontynuować 'Range'.
Jedna część nie udało się załadować: część przekaźnika bez odtwarzania całego eksportu.
Upadek pracownika: Praca wznawia się z ostatnim niepotwierdzonym kawałkiem.
KMS niedostępne: bezpieczne degradacja (generacja pauza, nie zwolnić niezaszyfrowane).
Wzrost danych × 2: sprawdź czas generowania, redystrybuuj równoległość, nie zabijaj bazy danych.
18) Kwoty całkowite
Niezawodne duże obciążenia to architektura asynchroniczna + partycjonowanie + odnowienie + możliwa do zweryfikowania integralność. Zrób migawkę, napisz równolegle części, opublikuj manifest z checksum, obsługuj HTTP Range i krótkotrwałe linki. Zastanów się nad bezpieczeństwem, ograniczeniami i obserwowalnością - a eksport gigabajtów przestanie być koszmarem dla zespołów i użytkowników.