Synchronizacja danych za pośrednictwem API
1) Dlaczego potrzebna jest synchronizacja i jakie są cele
Spójność domeny: profil, portfel, katalogi, limity, KYC.
Redukcja opóźnień: prawie w czasie rzeczywistym dla procesów krytycznych (płatności, premie).
Odporność: doświadczanie przerwy w obsłudze sieci/dostawcy bez utraty zdarzeń.
Ekonomia: Zminimalizuj egress/procesor poprzez delty i pakowanie.
Wskaźniki sukcesu: opóźnienia między źródłem a konsumentem, świeżość, odsetek duplikatów, odsetek konfliktów, koszt GB/godzinę niebieskiego.
2) Modele synchronizacji
2. 1 Pull (sondaż)
Klient żąda zmian w odstępach czasu.
Plusy: prostota, kontrola obciążenia.
Minusy: opóźnienie, „puste” sondaże, ryzyko pominięcia w wysokim tempie zmian.
Ulepszenia: If-Modified-Since, Etag/If-None-Match, change_token.
2. 2 Push (webhaki/wydarzenia)
Źródło puszy zdarzenia do odbiorcy.
Plusy: prawie w czasie rzeczywistym, gospodarka sondażowa.
Minusy: potrzebna jest dostawa z przekładkami, deduplikacja, bezpieczeństwo (podpis, mTLS).
Wymagania: idempotent konsumentów, wykładnicze backoff, powtórka.
2. 3 CDC/Streaming (Zmiana przechwytywania danych)
Migawka zmian z dziennika transakcji/zdarzeń (Kafka, Debezium).
Plusy: kompletność, porządek, skala.
Wady: złożoność, potrzebujesz kontroli nad rodzajami operacji (wstawić/zaktualizować/usunąć/nagrobek).
2. 4 Hybryda
Webhaki jako „wyzwalacz”, sondaż jako awaryjny i do pojednania.
3) Delty przyrostowe
3. 1 Znak wodny (znacznik czasowy)
Klient przechowuje 'last _ seen _ ts' i żądania' updated _ at> watermark '.
Ryzyko: godzinny dryf - użyj UTC i NTP; weź okno nakładania się na 1-2 min i dedup przez ID + wersji.
3. 2 Zmień token/kursor
Stabilny token sekwencji: '? kursor = eyJvZmZzZXQiOjEwMDB9 '.
Plusy: odporność na zmianę zamówienia, skala.
Wymagania: kursory bez zubożenia, TTL i bezpieczna powtórka.
3. 3 Numerowane offsety (automatyczny przyrost)
'id> last_id'. Proste, ale rozkłada się podczas odlania i „dziury” w sekwencji.
4) Duża paginacja próbki
Keyset/kursor (preferowany): '? po = kursor & limit = 1000 '- stabilny ze zmianami.
Offset/limit - proste, ale drogie i podlegające zmianom.
Zawsze należy określić stabilny klucz sortowania (na przykład '(updated_at, id)').
json
{
"items": [ { "id": "u_1", "updated_at": "2025-11-03T16:59:10Z" } ],
"next_cursor": "eyJ1cGRhdGVkX2F0IjoiMjAyNS0xMS0wM1QxNjo1OToxMFoifQ==",
"has_more": true
}
5) Zmiana semantyki: upsert, fuzja, skreślenie
5. 1 Upsert/fuzja
„PUT/resource/{ id}” to kompletne zastąpienie.
'PATCH/resource/{ id}' - częściowa aktualizacja (scalenie łatek z walidacją).
Idempotencja przez 'Idempotency-Key' dla wszystkich pisać.
5. 2 Skreślenia
Delete (pole 'deleted = true', 'deleted _ at') - zapisz historię; zlew daje nagrobek.
Trudno usunąć - dać zdarzenie 'deleted' przed zniknięciem.
json
{ "id":"u_1", "event":"deleted", "deleted_at":"2025-11-03T17:00:00Z" }
6) Kontrola wersji i konkurencja
6. 1 ETag/If-Match (blokady optymistyczne)
Przeczytaj powroty 'ETag:' v123 ''.
Aktualizacja z 'If-Match: „v123”' - ochrona przed „utraconymi aktualizacjami”.
W przypadku konfliktu - 409 Conflict with 'error _ code: "CONFLICT_VERSION"'.
6. 2 Weryfikacja zapisów
Pole 'wersja '/' updated _ at' - w obliczeniach delta i deduplikacji.
6. 3 Konflikty
Zasady: last-write-wins, server-wins, merge-strategy by fields (na przykład sums → additive, flags → source priority).
7) Zamawianie i deduplikowanie
7. 1 Procedura dostawy
Gwarancje: przynajmniej raz plus idempotencja → de facto standard.
Dla krytycznych przepływów pieniężnych - dokładnie raz efekty przez sklep idempotence.
7. 2 klucze Idempotence
Skład pól domeny: 'source _ id' event _ type' sekwencja '.
Przechowywanie TTL 24-72 godziny (lub więcej w SLA).
7. 3 Deduplikowanie
Zapisz ostatnią wersję/sekundę zastosowaną do odbiornika; upuść starsze.
8) Powtórzenia, timeouts, backoff
Retriable: 5xx/429/408/timeouts; Nie do odzyskania: 400/401/403/404/ 409/422/410/412.
Wykładniczy backoff + jitter: 1s, 2s, 4s... do lat 30-60.
Retry-Po szacunek dla 429/503.
Czasy klienta: połączenie 3-5s, żądanie ogólne 10-30s; łączny limit prób 3-6.
9) Lags i kontrola SLA
9. 1 SLI/SLO
SLI Lag: mediana/p95 lag między „occurred _ at” a „applied in consumer”.
SLO: na przykład 'p95 lag ≤ 60s (28d)', 'udział straconych zdarzeń = 0', 'udział duplikatów ≤ 0. 01%».
Budżet błędu: wydatki na wydania/eksperymenty.
9. 2 Metryka
'sync _ lag _ seconds', 'events _ received _ total', 'events _ applied _ total', 'duplikaty _ total', 'conflicts _ total', 'retries _ total', 'backlog _ size', 'cursor _ advance _ rate'.
10) Pojednanie i zasypka
Pojednanie dzienne/godzinne: sumy/skróty okienne.
API pojednania: "GET/pojednanie? od =... & do =... "odprawy kontrolne i warianty.
Zasypka: bezpieczne przeładowanie danych historycznych w partiach za pomocą kursora, bez źródła DDOS; przestrzegać limitów.
11) Systemy i przykłady
11. 1 Wydarzenia webhook (podpisane)
json
{
"event": "user. updated",
"id": "evt_01HX",
"occurred_at": "2025-11-03T18:00:05Z",
"sequence": 123456,
"data": { "id": "u_1", "email": "a@b. com", "updated_at": "2025-11-03T18:00:02Z" }
}
Tytuły:
- „Podpis X: sha256 =
” - "X-Event-ID: evt_01HX'
- "X-Retry: 0.. N'
11. 2 Pobieranie próbek pierwotnych (sondaż)
'GET/v1/użytkowników? updated_after=2025-11-03T17: 58:00Z&cursor=...&limit=1000'
11. 3 Idempotent upsert
POST /v1/users
Idempotency-Key: upsert-u_1-20251103T1800Z
{ "id":"u_1","email":"a@b. com","version":124 }
→ 201/200 (stable)
12) Bezpieczeństwo i zgodność
Auth: zakresy OAuth2/JWT; dla kanałów łącza - mTLS na żądanie.
Wpisy: nagłówki HMAC dla haków internetowych, wirujące sekrety.
Minimalizacja PII, maskowanie w dziennikach; RODO/DSAR Prześlij/Usuń.
RBAC/ABAC: dostęp najemcy/organizacji, ścisłe kwoty.
13) Obserwowalność i kłody
Лескла: '', 'service', 'tenend', 'source', 'cursor', 'seq', 'event _ type'.
Korelacja: 'trace _ id' z wejścia → dotyczy kłód i śladów.
Deski rozdzielcze: opóźnienie, zaległości, prędkość kursora, błędy typu, 429/5xx, koszt (egress/min).
14) FinOps: koszt synchronizacji
Dozowanie (wielkość partii 100-1000) + kompresja (gzip/br).
Buforowanie i ETag dla niezmienionych stron.
Cienkie ładunki użytkowe: tylko zmienione pola, link do pełnego zasobu na żądanie.
Limity współistnienia i „okna nocne” dla zasypki.
15) Badania i jakość
15. 1 Umowy i przypadki negatywne
Zatwierdzanie systemów JSON, wymagane pola, stabilność „error _ code”.
Testy: out-of-order, duplikaty, zdarzenia pomijające, konflikt wersji, 429/5xx.
15. 2 chaos/gry
Zastrzyki: opóźnienia w sieci, spadek 10-30% zdarzeń, ponowne zamówienie.
Kryteria: utrzymanie porządku/integralności? żadnych strat? opóźnienie w ramach SLO?
16) Lista kontrolna wdrażania
- Wybrany model (push/pull/hybrid) i źródło prawdy.
- Delty przyrostowe: znak wodny lub kursor/token.
- Pagination: cursor/keyset z stabilną klasą.
- Idempotency-store, klucze i TTL; dedup przez '(id, wersja/seq)'.
- Polityka ETag/If-Match i Conflict (LWW/server-wins/merge).
- Retry/backoff/jitter, szacunek „Retry-After”.
- Mierniki lag/backlog/duplikaty/konflikty, deski rozdzielcze i wpisy.
- Uzgodnienie API + codzienne uzgodnienia.
- Bezpieczeństwo: OAuth2/JWT, podpisy internetowe, mTLS, polityka PII.
- FinOps: partia + kompresja, limity współistnienia, kwoty wyjścia.
- Pakiet testowy: reorder, duplikaty, przerwy, zasypka.
17) Plan realizacji (3 iteracje)
1. MVP (1-2 tygodnie):
Paginacja kursora, delty znaku wodnego, idempotent upsert, podstawowe opóźnienie/zaległości, wsteczne + mierniki backoff.
2. Skala (2-3 tygodnie):
Haki internetowe jako wyzwalacz + ankieta, podpisy HMAC, pojednanie, ETag/If-Match, deski rozdzielcze i nagrywanie wpisów przez lag.
3. Pro (3-4 tygodnie):
CDC/streaming (Kafka/Debezium) dla gorących domen, automatyczne zasypanie, skrypty DR, optymalizacja FinOps (partia/brotley), SLA dla opóźnienia i raportowania.
18) Mini-FAQ
Co wybrać: znak wodny lub kursor?
Kursor/klucz jest bardziej odporny na powtórzenie i skalę; znak wodny jest łatwiejszy do uruchomienia, ale dodać nakładanie się i deadup.
Czy jest potrzebny dokładnie raz?
Ogólnie rzecz biorąc, drogie. Praktyka - przynajmniej raz + idempotencja; dokładnie raz - tylko dla efektów pieniężnych.
Jak zminimalizować konflikty?
Użyj ETag/If-Match, projekt połączyć przez pola, uniknąć „ukrytych” skutków ubocznych.
Razem
Niezawodna synchronizacja to przyrostowe delty + prawidłowa paginacja + idempotencja i kontrola wersji, wzmocniona przez obserwowalność, błyszczące i ekonomiczny transport. Wybierz odpowiedni model (push/pull/CDC), przypiąć SLO do opóźnienia, wdrożyć politykę konfliktu i brudne testy scenariusza - a wymiana danych staje się przewidywalna, zrównoważona i opłacalna.