GH GambleHub

Citiți modele și proiecții

Read Model este un tabel special conceput/index/vizualizare pentru citiri rapide pentru un anumit scenariu de produs. Proiecția este un proces care convertește evenimentele/modificările sursă la actualizările Read Model (de obicei upsert idempotent). În combinație cu CQRS, acest lucru vă permite să descărcați nucleul OLTP și să stabilizați citirile p95/p99, controlând „prospețimea”.

Idei principale:
  • Denormalizați la cerere, nu o „schemă universală”.
  • Actualizați incremental și idempotent.
  • Gestionați în mod explicit staleness și ordine.

1) Când să utilizați Read Models (și când nu)

Fit:
  • Citiri frecvente (alăturări/agregări/sortimente) cu latență acceptabilă de actualizare.
  • Tablouri de bord, cataloage, pagini de destinație, „top-N”, feed-uri personale, liste de căutare.
  • Partajarea sarcinii: scrieți-core - strict, citiți-plan - rapid și scalabil.
Nu este potrivit:
  • Operațiuni care necesită invarianți stricți „pe intrare” (bani, unicitate). Există o cale puternică.

2) Contur arhitectural (schema verbală)

1. Sursa modificărilor: evenimente ale domeniului (evenimente de aprovizionare) sau CDC de la OLTP.
2. Conductă de proiecție: parser → agregare/denormalizare → upsert idempotent.
3. Read Store: baza de date/index optimizat pentru interogare (RDBMS, coloană, căutare).
4. API/client: SELECT/GET rapid, cu atribute „as_of/freshness”.

3) Citiți designul modelului

Începeți cu o interogare: ce câmpuri, filtre, sortare, paginare, top N?
Denormalize: Stocați datele deja îmbinate (nume, sume, stări).

Chei:
  • Partiționare: prin 'chiriaș _ id', dată, regiune.
  • Cheie principală: cheie de afaceri + găleată de timp (de exemplu, „(tenant_id, entity_id)” sau „(tenant_id, bucket_minute)”).
  • Indici: prin frecvente unde/ordine de.
  • TTL/retenție: pentru cazurile de afișare temporară (ex. 90 de zile).

4) Actualizați fluxul și idempotența

Idempotent upsert este baza stabilității proiecției.

Pseudo:
sql
-- Projection table
CREATE TABLE read_orders (
tenant_id  TEXT,
order_id  UUID,
status   TEXT,
total    NUMERIC(12,2),
customer  JSONB,
updated_at TIMESTAMP,
PRIMARY KEY (tenant_id, order_id)
);

-- Idempotent update by event
INSERT INTO read_orders(tenant_id, order_id, status, total, customer, updated_at)
VALUES (:tenant,:id,:status,:total,:customer,:ts)
ON CONFLICT (tenant_id, order_id) DO UPDATE
SET status = EXCLUDED. status,
total = EXCLUDED. total,
customer = COALESCE(EXCLUDED. customer, read_orders. customer),
updated_at = GREATEST(EXCLUDED. updated_at, read_orders. updated_at);
Reguli:
  • Fiecare mesaj poartă o versiune/timp; acceptă doar „proaspăt sau egal” (idempotență).
  • Pentru agregate (contoare, sume) - stocați starea și utilizați actualizări comutative (sau abordări CRDT).

5) Sursa de schimbare: Evenimente vs CDC

Evenimente (evenimente de aprovizionare): semantică bogată, este ușor de construit proiecții diferite; evoluția circuitelor este importantă.
CDC (replicare logică): pur și simplu conectați-vă la o bază de date existentă; va fi necesară filtrarea DML→sobyty a cartografierii și a actualizării zgomotului.

Ambele opțiuni necesită:
  • Garanții de livrare (cel puțin o dată) și DLQ pentru mesaje „otrăvitoare”.
  • Ordine după cheie (cheie partiție = 'chiriaș _ id: entity _ id').

6) Ordine, cauzalitate și „prospețime”

Ordine după cheie: evenimentele unui obiect trebuie să vină secvențial; utilizați partiționarea și versiunile.
Sesiune/cauzalitate: Pentru ca autorul să vadă modificările lor (RYW), treceți versiunile filigranului în interogări.
Staleness mărginită: Return' as _ of '/' X-Data-Freshness 'şi ţineţi apăsat SLO (de ex. p95 ≤ 60c).

7) agregate incrementale și de top N

Exemplu de găleți de vânzări minuscule:
sql
CREATE TABLE read_sales_minute (
tenant_id TEXT,
bucket  TIMESTAMP, -- toStartOfMinute revenue  NUMERIC(14,2),
orders  INT,
PRIMARY KEY (tenant_id, bucket)
);

-- Update by Event
INSERT INTO read_sales_minute(tenant_id, bucket, revenue, orders)
VALUES (:tenant,:bucket,:amount, 1)
ON CONFLICT (tenant_id, bucket) DO UPDATE
SET revenue = read_sales_minute. revenue + EXCLUDED. revenue,
orders = read_sales_minute. orders + 1;
Pentru Top N:
  • Mențineți o vitrină clasată (de exemplu, prin „DESC de venituri”) și actualizați numai pozițiile schimbate (heap/skiplist/tabel limitat).
  • Stocați „fereastra” din partea de sus (de exemplu, 100-1000 linii pe segment).

8) Căutare și geo-proiecție

Căutare (ES/Opensearch): document denormalizat, transformări de conducte, versiune document = versiune sursă.
Geo: stochează „POINT/LAT, LON”, plăci/cuaduri pre-agregate.

9) Multi-chiriaș și regiuni

'tenant _ id' este necesar în cheile de proiecție și evenimente.
Corectitudine: limitați debitul de proiecții per chiriaș (WFQ/DRR), astfel încât „zgomotul” să nu încetinească restul.
Rezidență: proiecția trăiește în aceeași regiune cu nucleul de scriere; vitrine interregionale - agregate/rezumate.

10) Observabilitate și SLO

Măsurători:
  • 'projection _ lag _ ms' (istochnik→vitrina),' prospeţime _ age _ ms' (de la ultima deltă).
  • transfer de actualizări, rata de eroare, rata DLQ, redrive-succes.
  • Dimensiunea ferestrei, p95/p99 latență lectură.
Vectorizare/Busteni:
  • Теги: 'tenant _ id',' entity _ id', 'event _ id',' version ',' projection _ name ',' încercare '.
  • Adnotări: soluții de îmbinare, omiterea versiunilor învechite.

11) Cărți de joc (runbooks)

1. Creșterea decalajului: verificați conectorul/brokerul, creșteți părțile, includeți prioritizarea vitrinelor cheie.
2. Multe erori de schemă: înghețați redrive, migrați scheme (backfill), reporniți cu o nouă versiune a mapper-ului.
3. DLQ repetat: reduceți lotul, activați manipulatorul „shadow”, creșteți idempotența.
4. Inconsistența ferestrei: reconstruiți ferestrele din jurnal/sursă pe fereastră (chiriaș/partiție selectivă).
5. Tastele fierbinți: limitați concurența prin cheie, adăugați cozi locale, puneți unitatea într-o vitrină separată.

12) Renumărarea completă (reconstrui) și rambursare

Abordare:
  • Opriți consumul (sau treceți la o nouă versiune a casetei de prezentare).
  • Recalculați în loturi (după lot/dată/chiriaș).
  • Activați comutatorul în două faze: mai întâi completați „citiți __ v2”, apoi comutați atomic rutarea citirii.

13) Evoluția circuitelor (versioning)

'schema _ version' in evenimente/documente.
Proiecția poate citi mai multe versiuni, migrarea pe zbor.
Pentru schimbări majore - o nouă vitrină v2 și trafic canar.

14) Securitate și acces

Moșteniți RLS/ACL de la sursă; nu face vitrina mai largă în acces decât datele originale.
Masca PII în proiecții care nu sunt necesare pentru UX/analytics.
Auditul redrives/renumarari/editari manuale.

15) Șablon de configurare

yaml projections:
read_orders:
source: kafka. orders. events partition_key: "{tenant_id}:{order_id}"
idempotency: version_ts upsert:
table: read_orders conflict_keys: [tenant_id, order_id]
freshness_slo_ms: 60000 dlq:
topic: orders. events. dlq redrive:
batch: 500 rate_limit_per_sec: 50 read_sales_minute:
source: cdc. orders partition_key: "{tenant_id}:{bucket_minute}"
aggregate: increment retention_days: 90 limits:
per_tenant_parallelism: 4 per_key_serial: true observability:
metrics: [projection_lag_ms, dlq_rate, redrive_success, read_p95_ms]

16) Erori tipice

„O casetă de prezentare pentru toate cazurile” → actualizări grele și p99 rău.
Lipsa idempotenței → duplicate/salturi în agregate.
Dual-scrie direct la caseta de prezentare și OLTP → discrepanțe.
Vizibilitatea zero a prospețimii → așteptările contradictorii cu produsul.
Reconstrui fără un comutator în două faze → „găuri” în răspunsuri.
Fără partiționare/indici → creștere a costurilor și a latenței.

17) Rețete rapide

Catalog/căutare: prezentare document + upsert incremental, lag ≤ 5-15 s, indici pentru filtre.
Tablouri de bord: rezervoare minut/oră, unități 'SUM/COUNT', prospețime p95 ≤ 60 s.
Bandă personală: proiecție după utilizator + cauzal/RYW pentru autor, rezervă la memoria cache.
Global SaaS: vitrine regionale, agregate transregional; corectitudine per chiriaș.

18) Lista de verificare pre-vânzare

  • Caseta de prezentare este proiectată pentru o anumită cerere; există indici și partide.
  • Sursa de schimbare selectată (evenimente/CDC); garanții de livrare și comandă cheie.
  • Upsert idempotent cu versiuni/timp; protecție împotriva evenimentelor „vechi”.
  • Prospețimea SLO este definită și răspunde („as _ of/prospețime”).
  • DLQ și Secure Release configurate; playbook pe reconstrui/backfill.
  • Per-cheie serial și corectitudine per chiriaș.
  • Măsurători de lag/eroare/latență, alerte p95/p99 și creștere DLQ.
  • Strategia de versionare și migrare a circuitului (v2 + switch).
  • Politicile de acces/PII sunt moștenite și validate.

Concluzie

Citește Modele și proiecții sunt un accelerator de inginerie de citește: plătiți un preț mic pentru „prospețime” și infrastructura de streaming pentru a obține milisecunde previzibile și descărcați nucleul de înregistrări. Design storefronturi pentru a se potrivi cererii dvs., face actualizări idempotent, măsura lag și promite în mod clar prospețime - și API-urile vor rămâne rapide, chiar și cu creșterea sarcinii, date și geografie.

Contact

Contactați-ne

Scrieți-ne pentru orice întrebare sau solicitare de suport.Suntem mereu gata să ajutăm!

Pornește integrarea

Email-ul este obligatoriu. Telegram sau WhatsApp sunt opționale.

Numele dumneavoastră opțional
Email opțional
Subiect opțional
Mesaj opțional
Telegram opțional
@
Dacă indicați Telegram — vă vom răspunde și acolo, pe lângă Email.
WhatsApp opțional
Format: cod de țară și număr (de exemplu, +40XXXXXXXXX).

Apăsând butonul, sunteți de acord cu prelucrarea datelor dumneavoastră.