GH GambleHub

MongoDB și scheme de date flexibile

(Secțiunea: Tehnologie și infrastructură)

Scurt rezumat

MongoDB este o stocare orientată spre documente cu circuite flexibile (BSON), inserții rapide, scalare orizontală și conducte puternice de agregare. În iGaming, este excelent pentru profilurile jucătorilor, carduri CRM flexibile, jurnale de evenimente, telemetrie, proiecții de flux materializate, cataloage de jocuri și vizualizări frontale în cache. Pentru invarianții monetari (portofele/registru), conturul SQL/CP este mai des lăsat; MongoDB este adecvat ca model de citire și stocare de documente de înaltă performanță.


Unde MongoDB profită la maximum de iGaming

Profilurile și setările jucătorului: variabile de structură (setări locale, preferințe, metadate KYC).
Cataloage conținut/jocuri/furnizor: citire rapidă a cărților, filtre, etichetare, text complet.
Evenimente/telemetrie/busteni: TPS ridicat, ferestre de timp, stocare TTL.
Vizualizări materializate (CQRS): ecrane rapide (clasamente, acțiuni recente, agregate).
Personalizare/Caracteristici ML online: modele KV în colecții, TTL scurt.


Principiile unei scheme flexibile: disciplina în loc de haos

MongoDB nu este „fără schemă” - schema trăiește în cod și validare.

Recomandat:

1. Schema ca contract: JSON Schema Validarea în colecții.

2. Versionarea documentelor cu câmpul 'schemaVersion'.

3. Câmpuri obligatorii stricte (id, chei de căutare), „coadă” de atribute rare - opțional.

4. Constrângeri dimensiunile matrice și cuiburi (pentru indici și RAM).

5. Migrații în fundal: actualizări prin 'schemaVersion', shedulers, înapoi umple.

Exemplu: Validarea schemei JSON

js db.createCollection("player_profiles", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["playerId", "createdAt", "schemaVersion"],
properties: {
playerId: { bsonType: "string" },
createdAt: { bsonType: "date" },
schemaVersion: { bsonType: "int", minimum: 1 },
locale: { bsonType: "string" },
kyc: {
bsonType: "object",
properties: {
status: { enum: ["pending", "verified", "rejected"] },
doc: { bsonType: "object" }
}
}
}
}
}
});

Modelul de date și proiectarea documentelor

Design „la cerere”: 1 ecran/punct final = 1 document sau un set mic de documente.
Denormalizare: Includeți subdocumente mici atașate (de exemplu, mini-cărți ale furnizorilor de jocuri).

Link-uri vs încorporare:
  • Încorporarea - pentru fragmente strâns legate și rar actualizate.
  • Referințe („ref”) - pentru dimensiuni mari/actualizări frecvente/reutilizare.
  • Limita de dimensiune: document ≤ 16 MB; binare mari - GridFS/depozite de obiecte.
  • Audit/metadate: 'createdAt',' UpdatedAt', 'traceId',' tenantId', 'idempotencyKey'.

Indici: citiți stabilitatea calității și latenței

Tipuri și practici de index:
  • Arborele B (primar)

Compus: Ordinea câmpurilor corespunde predicatelor și sortimentelor frecvente.
Regula prefixului: opțiunile prefixului funcționează pentru '(tenantId, playerId, createdAt)'.
Sortare: Luați în considerare „sortare” la sfârșitul indicelui (de exemplu, „creatAt: -1”).

js db.bets.createIndex(
{ tenantId: 1, playerId: 1, createdAt: -1 },
{ name: "idx_bets_tenant_player_created_desc" }
);

Parţial/Rare

Accelerați subseturile frecvente („stare:” în așteptare „”), reduceți dimensiunea.

js db.withdrawals.createIndex(
{ playerId: 1, createdAt: -1 },
{ partialFilterExpression: { status: "pending" } }
);

TTL

Pentru telemetrie/busteni/caracteristici temporare - expirare automată.

js db.events.createIndex({ expireAt: 1 }, { expireAfterSeconds: 0 });

Text/completare automată

„text” pentru textul integral (restricții lingvistice); pentru auto-finalizare - „n-gram ”/trigram prin câmpuri și abordări regex sau Atlas Search.

Index antipattern

Indicele „toate” → o scădere a vitezei de scriere.
Cardinalitate scăzută fără selectivitate parțială → scăzută.
Compuși duplicați.
Câmpuri index în interiorul matrice gigant fără limite.


Conductă de agregare: ecrane rapide și rapoarte

Utilizați '$ match' → '$ sort' → '$ limit' încă din primele etape; indici de proiect sub '$ meci/$ sortare'.
'$ lookup' pentru joynes controlate (moale, în volume rezonabile).
„$ facet” pentru mai multe valori; '$ unionWith' - fuzionează colecţiile.
'$ merge '/' $ out' - materializați rezultatele în colecție (read-modele).

Exemplu: ultimul jucător pariază + seif:
js db.bets.aggregate([
{ $match: { tenantId: "eu-1", playerId: "p123" } },
{ $sort: { createdAt: -1 } },
{ $limit: 100 },
{ $group: {
_id: "$playerId",
lastBets: { $push: { amount: "$amount", ts: "$createdAt", game: "$gameId" } },
totalAmount: { $sum: "$amount" }
} }
]);

Tranzacții, coerență și idempotență

Atomicitatea atomică fără document unic; invarianți complexi - gândiți partiționarea documentelor.
Tranzacții multi-document (ACID) - disponibile cu seturi de replici, dar mai scumpe în latență; aplicați pointwise.

Scrie preocupare/Read Concern:
  • "w:" majoritate "pentru înregistrările critice (costul de latență);
  • „readConcern:” majoritate „” pentru lectură consecventă.
  • Idempotenta: chei unice pe 'idempotencyKey '/' pspTx', operatiuni UPSERT ('$ setOnInsert', '$ inc').
Exemplu UPSERT:
js db.wallet.updateOne(
{ playerId: "p123" },
{ $inc: { balanceCents: -5000 }, $set: { updatedAt: new Date() } },
{ upsert: true, writeConcern: { w: "majority" } }
);
💡 Pentru invarianții monetari, SQL este de obicei preferat. În Mongo - numai cu disciplină strictă cheie/idempotence și tranzacții limitate.

Sharding și selecție cheie

MongoDB cioburi de cheie ciob. Alegerea este critică:
  • Distribuția încărcăturii: cheie de înaltă cardinalitate și distribuție uniformă (de exemplu, „(tenantId, playerId)”).
  • Evitați monotonia: "creatAt' ca singura cheie → ciobului" fierbinte ".
Intervale vs hash:
  • Hashed - distribuie înregistrările mai uniform.
  • Ranged este mai bine pentru interogări interval, dar ceas pentru cozi fierbinți.
  • Intervale de etichete pentru reglare/localizare (EU/LatAm/TR).
Exemplu:
js sh.enableSharding("igaming");
db.bets.createIndex({ tenantId: 1, playerId: 1, _id: "hashed" });
sh.shardCollection("igaming.bets", { tenantId: 1, playerId: 1, _id: "hashed" });
Antipatterns:
  • Shard-cheie de cardinalitate scăzută („stare”) - înclinare de cioburi.
  • Frecvente '$ lookup' între colecții shardy fără co-sharing o cheie la un moment dat.
  • Cheia de cioburi schimbătoare (dificil și scump de schimbat).

Seturi de replici, citește și politica de citire după scriere

Set replica = HA și baza de tranzacție.

Citiți preferințele:
  • „primare” pentru citirea critică după scriere;
  • "premaryPreferred'/" secundar" - pentru analytics/non-critical.
  • Citiți/Scrieți coordonate de preocupare cu SLO și bugetul de latență.

Schimbați fluxurile, CDC și integrările

Schimbați fluxurile: abonamentul la inserții/actualizări/ștergeri - convenabil pentru:
  • Sincronizarea stratului cache (Redis)
  • Declanșatoare/notificări CRM,
  • descărcări în OLAP (ClickHouse/Pinot),
  • ecrane reactive.
  • Model Outbox: pentru domeniile critice, publicați evenimente într-o colecție separată, pe care conectorul o citește și o traduce în autobuz (Kafka). Acest lucru sporește predictibilitatea integrărilor.

Observabilitate și SLO

SLO: citire card p99 ≤ 10-20 ms; inserarea evenimentelor ≤ 20-40 ms; diferența de leutență între cioburi în X%; disponibilitate ≥ 99. 9%.
Valori: op-latență, adâncimea cozii,% din pompe pe secundar, statistici cache/WT, defecțiuni de pagină, blocare-așteaptă, numărul de cursoare deschise/conexiuni.
Profilare: "sistem. profil „,” explica („executionStats')”, colectare/blocare index.
Alerte: creșterea presiunii cache WT, operații lente, creșterea cererilor neincluse în index, restanțe ale cererilor secundare, migrații/balancer.


Performanţă şi reglare

WiredTiger Cache: în mod implicit ~ 50% RAM - validați pentru profil.
Compresie: snappy/zstd pentru colecții, zstd pentru bușteni - echilibru CPU/IO.
Inserții de lot și vracScrie pentru telemetrie.
Proiecție ('{field: 1}') pentru a nu trage documente „groase”.
Limit/Skip: Evitați „skip ”-ul mare → utilizați paginația cursor/marker ('createdAt/_ id').
Colecții plafonate pentru jurnalele „inel”.


Siguranță și conformitate

Auth/RBAC: roluri în colecția/baza de date, privilegii minime necesare.
TLS în tranzit, criptare pe disc (FLE/at-rest).
Politici PII: mascare/aliasing, colectii separate pentru campuri sensibile.
Multi-chirie: prefixe/baze de date individuale/colecții, filtre de 'chiriașID', puteți straturi de tip RLS în aplicație.
Audit: Permite auditarea operațiunilor privind colecțiile critice.


Copii de rezervă, PITR și DR

Instantanee de volume + backup-uri oplog pentru Point-in-Time Recovery.
Replica stabilit într-o altă regiune pentru DR; exerciții regulate de recuperare.
Controlul creșterii oplog pentru vârfurile de inserție (cârlige/turnee PSP).
În grupuri de cioburi - backup-uri consistente cu un server de configurare.


Integrarea cu restul arhitecturii

CQRS: echipele au lovit SQL (bani), evenimente → Vizualizări materializate în MongoDB.
Eveniment-Streaming: Kafka/Pulsar ca un autobuz, Mongo - chiuvetă/sursă prin conectori și schimbarea fluxurilor.
Redis: în apropiere ca un strat de latență ultra-scăzut (cache/contoare).
OLAP: încărcați pe ClickHouse/Pinot pentru scanări lungi și BI.


Lista de verificare a implementării

1. Fix domenii: ceea ce merge în Mongo (TPS flexibil/ridicat/proiecție), ceea ce rămâne în SQL.
2. Definirea contractelor de schemă: Validarea schemei JSON, „schemaVersion”.
3. Indici de proiectare pentru interogări reale; adăugați TTL pentru date zgomotoase.
4. Selectați cheia ciobului (cardinalitate ridicată, uniformitate); dacă este necesar - zona-sharding.
5. Configurarea unui set de replici, Read/Write Concerne pentru SLO; politica de citire după scriere.
6. Activați observabilitatea și profilarea, alerte la/WT cache/oplog indexuri.
7. Organizați copii de rezervă + PITR, cluster DR și exerciții regulate.
8. Conectați schimbarea fluxurilor/Outbox pentru a sincroniza cache-urile și autobuzele.
9. Limitați dimensiunea documentului și cuibăritul; Implementarea paginării prin cursor.
10. Politici separate pentru PII/chiriași, criptare, audit.


Anti-modele

„Fără schemă” în produs: lipsa validării și versiunile → haos.
Cheia ciobului în timp/monoton - ciobul fierbinte și p99 instabil.
Joynes '$ lookup' pe seturi uriașe, fără indici/paginare.
Utilizați tranzacțiile peste tot - a pierdut productivitatea.
Lipsa TTL/retenții pentru bușteni → creșterea volumului și a costurilor.
Stocați invarianții monetari critici numai în Mongo fără idempotență strictă.


Rezultate

MongoDB este un instrument puternic pentru domeniile iGaming flexibile: profile, directoare, telemetrie, proiecții și personalizare. Cheia succesului este o schemă de contract și validare, indexare atentă, o cheie de cioburi bine aleasă, preocupare conștientă de citire/scriere, fluxuri de schimbare pentru integrări și disciplină operațională strictă (observabilitate, copii de rezervă, DR). Combinat cu nucleul SQL și autobuzul de streaming, acest lucru oferă platformei interfețe rapide și stabilitate pentru vârfurile turneelor.

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ă.