MongoDB i elastyczne schematy danych
(Sekcja: Technologia i infrastruktura)
Krótkie podsumowanie
MongoDB to zorientowana na dokumenty pamięć masowa z układami elastycznymi (BSON), szybkimi wkładkami, poziomym skalowaniem i potężnym rurociągiem agregacyjnym. W iGaming jest świetny dla profili graczy, elastycznych kart CRM, dzienników wydarzeń, telemetrii, zmaterializowanych projekcji strumieniowych, katalogów gier i buforowanych widoków z przodu. W przypadku monetarnych niezmienników (portfele/księga) kontur SQL/CP jest częściej pozostawiony; MongoDB jest odpowiedni jako model odczytu i wysokiej wydajności przechowywania dokumentów.
Gdzie MongoDB wykorzystuje iGaming
Profile i ustawienia gracza: zmienne struktury (ustawienia lokalne, preferencje, metadane KYC).
Katalogi treści/gier/dostawców: szybki odczyt kart, filtry, tagowanie, pełny tekst.
Zdarzenia/telemetria/dzienniki: wysoki TPS, okna czasowe, pamięć TTL.
Zmaterializowane widoki (CQRS): szybkie ekrany (lidery, ostatnie działania, agregaty).
Personalizacja/funkcje online ML: wzory KV w kolekcjach, krótki TTL.
Zasady elastycznego systemu: dyscyplina zamiast chaosu
MongoDB nie jest „bez schematu” - schemat żyje w kodzie i walidacji.
Zalecane:1. Program jako umowa: JSON Schema Validation w zbiorach.
2. Wersioning dokumentów z polem 'schemaVersion'.
3. Ściśle obowiązkowe pola (id, klucze wyszukiwania), „ogon” rzadkich atrybutów - opcjonalnie.
4. Ograniczenia wymiarów tablic i gniazdowania (dla indeksów i RAM).
5. Migracje w tle: aktualizacje przez 'schemaVersion', shedulery, backfills.
Przykład: JSON Schema Validation
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" }
}
}
}
}
}
});
Model danych i projekt dokumentów
Projekt „na żądanie”: 1 ekran/punkt końcowy = 1 dokument lub mały zestaw dokumentów.
Denormalizacja: Należy dołączyć małe subdokumenty (na przykład mini-karty dostawców gier).
- Osadzanie - dla ściśle związanych i rzadko aktualizowanych fragmentów.
- Referencje („ref”) - dla dużych rozmiarów/częstych aktualizacji/ponownego użycia.
- Limit wielkości: dokument ≤ 16 MB; duże binaria - magazyny GridFS/obiektów.
- Audyt/metadane: „ At”, „ At”, „traceId”, „tenantId',” idempot„ Key ”.
Indeksy: czytaj jakość i latency stabilność
Rodzaje i praktyki indeksów:- Drzewo B (pierwotne)
Związek: Kolejność pól odpowiada częstym predykatom i rodzajom.
Reguła prefiksu: opcje prefiksu działają dla '(tenantId, plaاId, At)'.
Sortowanie: Należy rozważyć 'sortowanie' na końcu indeksu (na przykład ' At: -1').
js db. bets. createIndex(
{ tenantId: 1, playerId: 1, createdAt: -1 },
{ name: "idx_bets_tenant_player_created_desc" }
);
Częściowy/Sparse
Przyspieszyć częste podzbiory ('status: „oczekujący”), zmniejszyć rozmiar.
js db. withdrawals. createIndex(
{ playerId: 1, createdAt: -1 },
{ partialFilterExpression: { status: "pending" } }
);
TTL
Dla telemetrii/dzienników/funkcji tymczasowych - automatyczne wygaśnięcie.
js db. events. createIndex({ expireAt: 1 }, { expireAfterSeconds: 0 });
Tekst/autokompletny
„text” dla pełnego tekstu (ograniczenia językowe); do automatycznego wykonania - 'n-gram'/trygram poprzez pola i podejścia regeksowe lub Atlas Search.
Index antipatterns
Wskaźnik „wszystko” → spadek prędkości zapisu.
Niska kardynalność bez częściowego → niska selektywność.
Duplikaty związków.
Pola indeksu wewnątrz olbrzymich tablic bez ograniczeń.
Rurociąg agregacyjny: Szybkie ekrany i raporty
Użyj '$ match' → '$ sort' → '$ limit' we wczesnych etapach; indeksy projektów pod '$ match/$ sort'.
'$ searup' dla kontrolowanych joynów (miękkich, w rozsądnych ilościach).
'$ facet' dla wielu mierników; '$ "Z' - kolekcje scalone.
'$ merge '/' $ out' - zmaterializować wyniki w kolekcji (czytaj-modele).
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" }
} }
]);
Transakcje, spójność i idempotencja
Jednolity dokument atomowy - wolna atomowość; niezmienne złożone - myśl o podziale dokumentów.
Transakcje wieloprocesowe (ACID) - dostępne z zestawami replik, ale droższe w opóźnieniu; Zastosuj pointwise.
- "w:" większość "dla zapisów krytycznych (koszt opóźnienia);
- "readConcern:" majority "dla spójnego czytania.
- Idempotencja: unikalne klucze na 'idempotelklucz '/' pspTx', operacje UPSERT ('$ setOnInsert', '$ inc').
js db. wallet. updateOne(
{ playerId: "p123" },
{ $inc: { balanceCents: -5000 }, $set: { updatedAt: new Date() } },
{ upsert: true, writeConcern: { w: "majority" } }
);
Shading i wybór klucza
MongoDB odłamki za pomocą klucza odłamkowego. Wybór jest krytyczny:- Rozkład obciążenia: klucz o wysokiej kardynalności i równomierny rozkład (na przykład '(tenantId, plaاId)').
- Unikaj monotonii: ' At' jako jedyny klucz → „gorący” odłamek.
- Hashed - rozprowadza rekordy równomierniej.
- Zakresy są lepsze dla zapytań, ale uważaj na gorące ogony.
- Zakresy znaczników do regulacji/lokalizacji (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" });
Antypattery:
- Shard-key przez niską kardynalność ('status') - skew odłamków.
- Częste wyszukiwanie „$” pomiędzy ostrymi kolekcjami bez współrzucania jednego klucza na raz.
- Wymienny klucz odłamkowy (trudny i kosztowny do zmiany).
Repliki, odczyty i zasady odczytu po zapisie
Zestaw replik = HA i podstawa transakcji.
Przeczytaj preferencje:- „primary” dla krytycznego odczytu po zapisie;
- „Preferowane ”/„ wtórne” - dla analityki/niekrytycznych.
- Przeczytaj/Napisz troskę koordynować z SLO i opóźnienia budżetu.
Zmiany strumieni, CDC i integracji
Zmień strumienie: subskrypcja wstawek/aktualizacji/usunięć - wygodne dla:- Synchronizacja warstwy pamięci podręcznej (Redis)
- wyzwalacze/powiadomienia CRM,
- pliki do pobrania do OLAP (ClickHouse/Pinot),
- ekrany reaktywne.
- Wzorzec skrzynki zewnętrznej: dla domen krytycznych publikuj zdarzenia do oddzielnej kolekcji, którą złącze następnie czyta i tłumaczy do autobusu (Kafka). Zwiększa to przewidywalność integracji.
Obserwowalność i SLO
SLO: odczyt kart p99 ≤ 10-20 ms; wprowadzenie zdarzeń ≤ 20-40 ms; różnica między odłamkami w granicach X%; dostępność ≥ 99. 9%.
Metryki: opcja opóźnienia, głębokość kolejki,% ump na wtórną, statystyki pamięci podręcznej/WT, błędy stron, blokady-czeki, liczba otwartych kursorów/połączeń.
Profilowanie: 'system. profil ',' explain ("executionStats') ', kolekcja/zamki indeksowe.
Wpisy: wzrost ciśnienia w pamięci podręcznej WT, powolne operacje, wzrost wniosków nieuwzględnionych w indeksie, zaległości w żądaniach wtórnych, kawałek migracji/balancer.
Wydajność i dostrajanie
WiredTiger Cache: domyślnie ~ 50% RAM - sprawdź poprawność profilu.
Kompresja: snappy/zstd do kolekcji, zstd do dzienników - saldo procesora/IO.
Wkładki wsadowe i przegrodyNapisz do telemetrii.
Projekcja ('{pole: 1}'), aby nie przeciągać „grubych” dokumentów.
Limit/Skip: Unikaj dużego 'skip' → użyj paginacji kursora/znacznika (' At/_ id').
Zbiory limitowane do dzienników „ring”.
Bezpieczeństwo i zgodność
Auth/RBAC: role w bazie kolekcji/danych, minimalne wymagane uprawnienia.
TLS w tranzycie, szyfrowanie na dysku (FLE/at-rest).
Polityka PII: maskowanie/aliasing, oddzielne zbiory dla pól wrażliwych.
Wielopoziomowość: prefiksy/poszczególne bazy danych/kolekcje, filtry przez 'tenantId', można w aplikacji warstwy podobne do RLS.
Audyt: umożliwia audyt operacji na zbiorach krytycznych.
Kopie zapasowe, PITR i DR
Migawki woluminów + kopie zapasowe oplog dla Recovery Point-in-Time.
Replika ustawiona w innym regionie dla DR; regularne ćwiczenia odzyskiwania.
Kontrola wzrostu oplog dla pików wstawiania (PSP webhooks/turnieje).
W klastrach shard - spójne kopie zapasowe z serwerem config.
Integracja z resztą architektury
CQRS: zespoły hit SQL (pieniądze), wydarzenia → Zmaterializowane widoki w MongoDB.
Event-Streaming: Kafka/Pulsar jako autobus, Mongo - zlew/źródło przez złącza i strumienie zmiany.
Redis: w pobliżu jako ultra-niska warstwa opóźnienia (bufory/liczniki).
OLAP: prześlij do ClickHouse/Pinot dla długich skanów i BI.
Lista kontrolna implementacji
1. Fix domeny: co idzie w Mongo (elastyczne/wysokie TPS/projekcja), co pozostaje w SQL.
2. Zdefiniuj umowy schematu: JSON Schema Validation, 'schemaVersion'.
3. Indeksy projektowe do prawdziwych zapytań; dodać TTL dla hałaśliwych danych.
4. Wybierz klucz odłamkowy (wysoka kardynalność, jednolitość); w razie potrzeby - strzelanie strefowe.
5. Skonfiguruj zestaw replik, Przeczytaj/Napisz troskę o SLO; zasady odczytu po zapisie.
6. Umożliwia obserwację i profilowanie, alerty do indeksów pamięci podręcznej/oplog/WT.
7. Organizowanie kopii zapasowych + PITR, klastra DR i regularnych ćwiczeń.
8. Podłącz zmiany strumieni/skrzynki zewnętrznej do synchronizacji buforów i autobusów.
9. Ograniczony rozmiar dokumentu i gniazdowanie; Wdrożenie paginacji przez kursor.
10. Odrębna polityka dla PII/najemców, szyfrowanie, audyt.
Anty-wzory
„Brak schematu” w produkcie: brak walidacji i wersji → chaos.
Klucz odłamkowy w czasie/monotonny - gorący strzał i niestabilny p99.
Joynes '$ lookup' na ogromne zestawy bez indeksów/paginacji.
Wykorzystaj transakcje wszędzie - utracona wydajność.
Brak TTL/retencji dla logów → wzrost wolumenu i kosztów.
Przechowywać najważniejsze monetarne niezmienne tylko w Mongo bez ścisłej idempotencji.
Podsumowanie
MongoDB to potężne narzędzie do elastycznych domen iGaming: profili, katalogów, telemetrii, projekcji i personalizacji. Kluczem do sukcesu jest program kontraktowy i walidacja, przemyślane indeksowanie, dobrze dobrany klucz odłamkowy, świadomy problem czytania/pisania, zmiany strumieni dla integracji i ścisłej dyscypliny operacyjnej (obserwowalność, kopie zapasowe, DR). W połączeniu z rdzeniem SQL i autobusem strumieniowym daje to platformie szybkie interfejsy i stabilność dla szczytów turnieju.