MongoDB und flexible Datenschemata
(Abschnitt: Technologie und Infrastruktur)
Kurze Zusammenfassung
MongoDB ist ein dokumentenorientierter Speicher mit flexiblen Schemata (BSON), schnellen Einfügungen, horizontaler Skalierung und einer leistungsstarken Aggregation Pipeline. In iGaming eignet es sich hervorragend für Spielerprofile, flexible CRM-Karten, Ereignisprotokolle, Telemetrie, materialisierte Projektionen aus dem Stream, Spielkataloge und Caching-Ansichten für die Fronten. Für monetäre Invarianten (Wallets/Ledger) bleibt häufiger ein SQL/CP-Loop; MongoDB eignet sich sowohl als Lesemodell als auch als leistungsstarker Dokumentenspeicher.
Wo MongoDB im iGaming das Maximum gibt
Spielerprofile und Einstellungen: Strukturvariablen (locale Einstellungen, Präferenzen, KYC-Metadaten).
Inhalts-/Spiele-/Anbieterverzeichnisse: schnelles Kartenlesen, Filter, Tagging, Volltext.
Events/Telemetrie/Logs: hohe TPS, Zeitfenster, TTL-Speicher.
Materialisierte Ansichten (CQRS): Quick Screens (Leaderboards, letzte Aktionen, Aggregate).
Personalisierung/fichy online ML: KV-Muster in Kollektionen, kurz TTL.
Prinzipien des agilen Schemas: Disziplin statt Chaos
MongoDB ist nicht „ohne Schema“ - Schema lebt in Code und Validierung.
Empfohlen:1. Schema als Vertrag: JSON Schema Validierung in Sammlungen.
2. Versionieren von Dokumenten mit dem Feld 'schemaVersion'.
3. Strenge Pflichtfelder (ID, Suchschlüssel), „Schwanz“ seltener Attribute - optional.
4. Begrenzung der Dimension von Arrays und Verschachtelung (für Indizes und RAM).
5. Migrationen im Hintergrund: Upgrades nach 'schemaVersion', Shedulers, Backfills.
Beispiel: JSON Schema Validierung
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" }
}
}
}
}
}
});
Datenmodell und Dokumentengestaltung
Entwerfen Sie „auf Anfrage“: 1 Bildschirm/Endpunkt = 1 Dokument oder einen kleinen Satz von Dokumenten.
Denormalisierung: Kleine verschachtelte Teildokumente (z.B. Minikarten der Spieleanbieter) einbeziehen.
- Einbetten - für eng verwandte und selten aktualisierte Fragmente.
- Referenzen ('ref') - mit großer Größe/häufigen Upgrades/Wiederverwendung.
- Größenbeschränkung: Dokument ≤ 16 MB; große Binärdateien - GridFS/Objektspeicher.
- Audit/Metadaten: 'createdAt', 'updatedAt', 'traceId', 'tenantId', 'idempotencyKey'.
Indizes: Lesequalität und Latenzstabilität
Arten von Indizes und Praktiken:- B-Baum (primär)
Zusammensetzung: Die Reihenfolge der Felder entspricht häufigen Prädikaten und Sortierungen.
Präfix-Regel: Präfix-Varianten funktionieren für'(tenantId, playerId, createdAt)'.
Sortierung: Berücksichtigen Sie' sort 'am Ende des Index (z.B.' createdAt: -1').
js db.bets.createIndex(
{ tenantId: 1, playerId: 1, createdAt: -1 },
{ name: "idx_bets_tenant_player_created_desc" }
);
Partial / Sparse
Beschleunigen Sie häufige Teilmengen ('status:' pending'), reduzieren Sie die Größe.
js db.withdrawals.createIndex(
{ playerId: 1, createdAt: -1 },
{ partialFilterExpression: { status: "pending" } }
);
TTL
Für Telemetrie/Logs/Time-Fiches - automatischer Ablauf.
js db.events.createIndex({ expireAt: 1 }, { expireAfterSeconds: 0 });
Text/autocomplete
'text' für den Volltext (Sprachbeschränkungen); für Auto-Vervollständigung - 'n-gram'/trigram durch Felder und Regex-Ansätze oder Atlas-Suche.
Anti-Pattern-Indizes
Der Index „für alles“ → einen Rückgang der Schreibgeschwindigkeit.
Niedrige Kardinalität ohne partielle → geringe Selektivität.
Doppelte Zusammensetzungen.
Indizieren Sie Felder in riesigen Arrays ohne Grenzen.
Aggregation Pipeline: Schnellbildschirme und Berichte
Verwenden Sie'$ match '→' $ sort '→' $ limit 'als Frühstadium. Entwerfen Sie Indizes unter „$ match/$ sort“.
'$ lookup' für kontrollierte Joins (weich, in angemessenen Mengen).
'$ facet' für mehrere Metriken;'$ unionWith'- Zusammenführen von Sammlungen.
'$ merge '/' $ out' - Materialisierung der Ergebnisse in einer Sammlung (read-models).
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" }
} }
]);
Transaktionen, Konsistenz und Idempotenz
Single-document atomic - freie Atomarität; komplexe Invarianten - denken Sie an die Aufteilung nach Dokumenten.
Multi-document transactions (ACID) - gibt es mit Replik-Sets, aber teurer in der Latenz; punktweise anzuwenden.
- „w:“ majority „“ für kritische Datensätze (Latenzkosten);
- 'readConcern:' majority''für eine vereinbarte Lesung.
- Idempotenz: eindeutige Schlüssel auf 'idempotencyKey '/' pspTx', UPSERT-Operationen ('$ setOnInsert','$ inc').
js db.wallet.updateOne(
{ playerId: "p123" },
{ $inc: { balanceCents: -5000 }, $set: { updatedAt: new Date() } },
{ upsert: true, writeConcern: { w: "majority" } }
);
Sharding und Schlüsselauswahl
MongoDB chardiert nach Shard-Schlüssel. Die Auswahl ist kritisch:- Lastverteilung: Schlüssel mit hoher Kardinalität und gleichmäßiger Verteilung (z.B.'(tenantId, playerId)').
- Vermeiden Sie Monotonie: „createdAt“ als einziger Schlüssel → „hot“ shard.
- Hashed - Verteilt Einträge glatter.
- Ranged ist besser für Reichweitenanfragen, aber achten Sie auf heiße Schwänze.
- Zone-Sharding (Tag-Ranges) für Regulierung/Lokalisierung (EU/LatAm/TR).
js sh.enableSharding("igaming");
db.bets.createIndex({ tenantId: 1, playerId: 1, _id: "hashed" });
sh.shardCollection("igaming.bets", { tenantId: 1, playerId: 1, _id: "hashed" });
Anti-Pattern:
- Der Shard-Schlüssel für niedrige Kardinalität ('Status') ist die Schrägstellung der Shards.
- Häufige'$ lookup 'zwischen Sharded Sammlungen ohne Co-Sharding durch einen Schlüssel.
- Variabler Shard-Schlüssel (schwer und teuer zu ändern).
Replica-Sets, Lesungen und Read-after-Write-Richtlinien
Replikat-Set = HA und Basis der Transaktionen.
Read Preference:- 'primary' für kritische Read-After-Write;
- 'primaryPreferred '/' secondary' - für Analytik/nicht kritisch.
- Read/Write concern mit SLO und Latency Budget abstimmen.
Change Streams, CDC und Integrationen
Change Streams: Einschübe/Upgrades/Löschungen abonnieren - praktisch für:- Cache-Layer-Synchronisation (Redis),
- CRM-Trigger/Benachrichtigungen,
- Downloads im OLAP (ClickHouse/Pinot),
- reaktiven Bildschirmen.
- Outbox-Muster: Bei kritischen Domains veröffentlichen Sie die Ereignisse in einer separaten Sammlung, die dann vom Connector gelesen und in den Bus (Kafka) übersetzt wird. Das erhöht die Planbarkeit von Integrationen.
Beobachtbarkeit und SLO
SLO: p99 Karten lesen ≤ 10-20 ms; Einfügen von Ereignissen ≤ 20-40 ms; die Leutensi-Differenz zwischen den Shards innerhalb von X%; Verfügbarkeit ≥ 99. 9%.
Metriken: Op-Latenz, Queue-Tiefe,% Yumps auf sekundäre, Cache/WT-Statistiken, Page-Fehler, Lock-Waits, Anzahl der geöffneten Cursor/Verbindungen.
Profilierung: 'system. profile', 'explain ("executionStats')', Sperren von Sammlungen/Indizes.
Alerts: WT Cache Druck Wachstum, langsame Operationen, das Wachstum von Anfragen, die nicht in den Index, sekundäre Verzögerung, Chunk Migrationen/Balancer.
Leistung und Tuning
WiredTiger Cache: Standardmäßig ~ 50% RAM - unter dem Profil validieren.
Kompression: snappy/zstd für Sammlungen, zstd für Zeitschriften - CPU/IO Balance.
Batch-Einsätze und bulkWrite für Telemetrie.
Projection ('{field: 1}'), um „dicke“ Dokumente nicht zu schleppen.
Limit/Skip: Vermeiden Sie große' skip '→ verwenden Sie die Pagination am Cursor/Marker (' createdAt/_ id').
Capped Sammlungen für „Ring“ -Protokolle.
Sicherheit und Compliance
Auth/RBAC: Rollen auf Sammlung/DB, minimal erforderliche Privilegien.
TLS im Transit, Verschlüsselung auf Festplatte (FLE/at-rest).
PII-Richtlinien: Maskierung/Pseudonymisierung, separate Sammlungen für sensible Bereiche.
Multi-Tenant: Präfixe/einzelne DBs/Sammlungen, Filter nach 'tenantId', RLS-ähnliche Ebenen in der Anwendung möglich.
Auditing: Aktivieren Sie das Auditing von Aktivitäten auf kritischen Sammlungen.
Backups, PITR und DR
Snapshots (Snapshots) von Volumes + Oplog-Backups für Point-in-Time Recovery.
Replik-Set in einer anderen Region für DR; regelmäßige Wiederherstellungsübungen.
Steuern Sie das Wachstum von oplog unter Peak-Inserts (PSP-Webhooks/Turniere).
In Shard-Clustern gibt es konsistente Backups mit einem Config-Server.
Integration mit der restlichen Architektur
CQRS: Befehle schlagen SQL (Geld), Ereignisse → Materialisierte Ansichten in MongoDB.
Event-Streaming: Kafka/Pulsar als Bus, Mongo - sink/source über Konnektoren und Change Streams.
Redis: nebeneinander als ultra-niedrige Latenzschicht (Caches/Counter).
OLAP: Upload in ClickHouse/Pinot für lange Scans und BI.
Checkliste Umsetzung
1. Fix Domains: Was geht in Mongo (flexibel/hohe TPS/Projektionen), was bleibt in SQL.
2. Definieren Sie schema contracts: JSON Schema Validation, 'schemaVersion'.
3. Entwerfen Sie Indizes für reale Anforderungen; TTL für „laute“ Daten hinzufügen.
4. Wählen Sie einen Shard-Schlüssel (hohe Kardinalität, Gleichmäßigkeit); bei Bedarf Zone-Sharding.
5. Konfigurieren Sie das Replikat-Set, Lesen/Schreiben Sie Concern unter SLO; Richtlinie read-after-write.
6. Umfassen Beobachtbarkeit und Profiling, Alerts auf Indizes/WT Cache/oplog.
7. Organisieren Sie Backups + PITR, DR-Cluster und regelmäßige Übungen.
8. Verbinden Sie Change Streams/Outbox, um Caches und Busse zu synchronisieren.
9. Beschränken Sie die Größe der Dokumente und die Verschachtelung; Implementieren Sie die Cursor-Paginierung.
10. Separate Richtlinien für PII/Tenanten, Verschlüsselung, Audit.
Antimuster
„Kein Schema“ in der Produktion: Mangel an Validierung und Versionen → Chaos.
Shard-Schlüssel in der Zeit/monoton - heißer Shard und instabile p99.
Joins'$ lookup 'auf riesigen Sets ohne Indizes/Paginierung.
Transaktionen überall nutzen - Produktivitätsverluste.
Das Fehlen von TTL/Retention für Protokolle → eine Zunahme von Volumen und Kosten.
Speichern Sie kritische monetäre Invarianten nur in Mongo ohne strenge Idempotenz.
Ergebnisse
MongoDB ist ein leistungsstarkes Tool für flexible iGaming-Domains: Profile, Verzeichnisse, Telemetrie, Projektionen und Personalisierung. Der Schlüssel zum Erfolg sind Schema-Verträge und Validierung, durchdachte Indexierung, gut gewählte Shard-Schlüssel, bewusste Read/Write Concern, Change Streams für Integrationen und strenge Betriebsdisziplin (Beobachtbarkeit, Backups, DR). In Kombination mit SQL-Core und Streaming-Bus gibt das der Plattform schnelle Schnittstellen und Robustheit für Turnierspitzen.