MongoDB және икемді деректер схемалары
(Бөлім: Технологиялар және Инфрақұрылым)
Қысқаша түйіндеме
MongoDB - икемді схемалары (BSON), жылдам ендірмелері, көлденең масштабтауы және қуатты Aggregation Pipeline бар құжатқа бағдарланған сақтау орны. iGaming-те ол ойыншылардың профильдері, икемді CRM карточкалары, оқиғалар логтары, телеметрия, материалданған стрим проекциялары, ойын каталогтары және фронттарға арналған кешенделген көріністер үшін өте жақсы. Ақша инварианттары (әмияндар/ledger) үшін SQL/CP-контур жиі қалады; MongoDB read-model және жоғары өнімді құжат қоймасы ретінде орынды.
MongoDB iGaming максимумын береді
Ойыншылардың профильдері мен параметрлері: ауыспалы құрылымдар (жергілікті параметрлер, артықшылықтар, KYC-метадеректер).
Мазмұн/ойындар/провайдерлер каталогтары: карточкаларды жылдам оқу, сүзгілер, тегтеу, толық мәтін.
Оқиғалар/телеметрия/журналдар: жоғары TPS, уақытша терезелер, TTL-сақтау.
Материалдандырылған көріністер (CQRS): жылдам экрандар (лидбордтар, соңғы әрекеттер, агрегаттар).
Персонализация/фичи онлайн-ML: Коллекциядағы KV үлгілері, қысқа TTL.
Икемді схема қағидаттары: хаос орнына тәртіп
MongoDB «схемасыз» емес - схема код пен валидацияда өмір сүреді.
Мыналар ұсынылады:1. Келісім-шарт сияқты схема: JSON Schema Validation коллекцияларда.
2. 'schemaVersion' өрісімен құжаттарды нұсқалау.
3. Қатаң міндетті өрістер (id, іздеу кілттері), сирек атрибуттардың «артқы» - опциондық.
4. Массивтер мен ішкі өлшемдерін шектеу (индекстер мен RAM үшін).
5. Фондағы көші-қон: 'schemaVersion' бойынша апдейттер, шедулерлер, бэк-филлдер.
Мысалы: 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" }
}
}
}
}
}
});
Деректер моделі және құжаттарды жобалау
«Сұрауға» жобалаңыз: 1 экран/эндпойнт = 1 құжат немесе кішігірім құжаттар жиынтығы.
Денормализация: шағын ішкі қосымша құжаттарды қосыңыз (мысалы, ойын провайдерлерінің шағын карточкалары).
- Кірістіру - тығыз байланысқан және сирек жаңартылатын фрагменттер үшін.
- Сілтемелер ('ref') - үлкен/жиі жаңартылған/қайта пайдаланылған кезде.
- Өлшемін шектеу: 16 МБ ≤ құжат; ірі бинарниктер - GridFS/объектілік қоймалар.
- Аудит/метадеректер: 'createdAt', 'updatedAt', 'traceId', 'tenantId', 'idempotencyKey'.
Индекстер: оқу сапасы және latency тұрақтылығы
Индекстер мен практиканың түрлері:- B-Tree (негізгі)
Compound: өрістердің реті жиі предикаттарға және сұрыптауларға сәйкес келеді.
Prefix ережесі: '(tenantId, playerId, createdAt)' үшін префиксті нұсқалар жұмыс істейді.
Сұрыптау: индекс соңында 'sort' дегенді ескеріңіз (мысалы, 'createdAt: -1').
js db.bets.createIndex(
{ tenantId: 1, playerId: 1, createdAt: -1 },
{ name: "idx_bets_tenant_player_created_desc" }
);
Partial / Sparse
Жиіліктерді жылдамдатады ('status:' pending ''), өлшемін азайтады.
js db.withdrawals.createIndex(
{ playerId: 1, createdAt: -1 },
{ partialFilterExpression: { status: "pending" } }
);
TTL
Телеметрия/логтар/уақытша фичтер үшін - автоматты түрде өту.
js db.events.createIndex({ expireAt: 1 }, { expireAfterSeconds: 0 });
Мәтіндік/autocomplete
толық мәтін үшін 'text' (тілдер бойынша шектеулер); автотолтыру үшін - 'n-gram '/trigram өрістер мен regex-тәсілдер немесе Atlas Search арқылы.
Индекстерге қарсы
Барлық индекс → жазу жылдамдығының төмендеуі.
Partial → селективтілігі төмен.
Қайталанатын компаунд.
Үлкен жиектердің ішіндегі өрістерді шектеусіз индекстеу.
Aggregation Pipeline: жылдам экрандар мен есептер
'$match' → '$sort' → '$limit' деп таңдаңыз; индекстерді «$match/ $sort» деп жобалаңыз.
Бақыланатын джойндар үшін '$lookup' (жұмсақ, ақылға қонымды көлемде).
Көп өлшемдер үшін '$facet'; '$unionWith' - жиынтықтарды біріктіру.
'$merge '/' $out' - жиынтықтағы нәтижелерді материалдандыру (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" }
} }
]);
Транзакциялар, келісімділік және теңсіздік
Single-document atomic - тегін атомарлық; күрделі инварианттар - құжаттар бойынша бөлу туралы ойланыңыз.
Multi-document transactions (ACID) - реплика-желілерде бар, бірақ latency бойынша қымбат; нүктелі қолдану.
- 'w: сыни жазбалар үшін «majority» (latency құны);
- 'readConcern: «majority» келісілген оқу үшін.
- Сәйкестік: 'idempotencyKey '/' pspTx', UPSERT-операцияларындағы бірегей кілттер ('$setOnInsert', '$inc').
js db.wallet.updateOne(
{ playerId: "p123" },
{ $inc: { balanceCents: -5000 }, $set: { updatedAt: new Date() } },
{ upsert: true, writeConcern: { w: "majority" } }
);
Кілттерді шардалау және таңдау
MongoDB shard key бойынша шардарлайды. Таңдау өте қиын:- Жүктемені бөлу: жоғары түбегейлі және біркелкі бөлу кілті (мысалы, '(tenantId, playerId)').
- Жалғыз кілт ретінде 'createdAt' деген біркелкілікті болдырмаңыз → «ыстық» шард.
- Hashed - жазбаларды біркелкі бөледі.
- Ranged - диапазондық сұраулар үшін жақсы, бірақ ыстық қалдықтарды қадағалаңыз.
- Реттеуіш/оқшаулауға арналған аймақ-шардинг (tag ranges) (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" });
Антипаттерндер:
- Төменгі кардиналдығы бойынша шард-кілт ('status') - шардтардың қисаюы.
- Бір кілт бойынша бірлесе шардаланбаған жинақтар арасында жиі '$lookup'.
- Өзгертілетін shard key (өзгерту қиын және қымбат).
Реплика-жиынтықтар, оқу және саясат read-after-write
Реплика-сет = HA және транзакциялар негізі.
Read Preference:- сыни read-after-write үшін 'primary';
- 'primaryPreferred '/' secondary' - талдау үшін/сыни емес.
- Read/Write concern SLO және latency бюджетімен келісіңіз.
Change Streams, CDC және интеграция
Change Streams: кірістіруге/жаңартуға/жоюға жазылу - мыналарға ыңғайлы:- Кэш қабаттарын үндестіру (Redis),
- CRM/хабарламалар триггерлері,
- OLAP жүктеулері (ClickHouse/Pinot),
- реактивті экрандар.
- Outbox-паттерн: сындарлы домендер үшін оқиғаларды жеке жинаққа жариялаңыз, содан кейін оны коннектор оқиды және шинаға (Kafka) таратады. Бұл интеграцияның болжамдылығын арттырады.
Бақылау және SLO
SLO: p99 карточкаларды оқу ≤ 10-20 мс; оқиғаларды енгізу ≤ 20-40 мс; шардалар арасындағы X% шегіндегі лейтенсі айырмашылығы; қол жетімділік ≥ 99. 9%.
Метриктер: оп-латенттілік, queue depth, қайталама юмпстерге%, cache/WT статистикасына, page faults, lock-waits, ашық курсорлар/қосылыстар саны.
Профильдеу: 'system. profile ',' explain («executionStats») ', жинақтар/индекстер бұғатталады.
Тәуекелдер: WT cache pressure өсуі, баяу операциялар, сұрау индексіне түспеген өсу, қайталама артта қалу, chunk migrations/balaner.
Өнімділік және тюнинг
WiredTiger Cache: әдепкі 50% RAM ~ - профиліңіздің астында валидацияланыңыз.
Compression: коллекциялар үшін snappy/zstd, журналдар үшін zstd - CPU/IO балансы.
Batch-кірістіру және bulkWrite телеметрия үшін.
Projection ('{field: 1}') қалың құжаттарды сүйретпеу үшін.
Limit/Skip: үлкен 'skip' → курсор/маркер пагинациясын пайдаланыңыз ('createdAt/_ id').
Сақиналы логтар үшін capped жиыны.
Қауіпсіздік және комплаенс
Auth/RBAC: коллекциядағы рөлдер/БД, ең аз қажетті артықшылықтар.
Транзиттегі TLS, дискідегі шифрлау (FLE/at-rest).
PII саясаты: бүркемелеу/бүркемелеу, сезімтал өрістерге арналған жеке коллекциялар.
Мульти-тенанттық: префикстер/жеке БД/коллекциялар, 'tenantId' бойынша сүзгілер, қосымшадағы RLS-ұқсас қабаттарға болады.
Аудит: күрделі коллекциялардағы операциялар аудитін қосыңыз.
Бэкаптар, PITR және DR
Томдардың түсірілімдері (snapshots) + Point-in-Time Recovery үшін oplog-бэкаптар.
DR үшін басқа аймақтағы реплика-жиынтық; тұрақты қалпына келтіру оқу-жаттығулары.
Кірістіру шыңдары бойынша oplog өсуін бақылау (PSP веб-хактар/турнирлер).
Шард-кластерлерде - config-серверімен келісілген бэкаптар.
Басқа архитектурамен біріктіру
CQRS: командалар SQL (ақша) соққы, оқиғалар → MongoDB Materialized Views.
Event-Streaming: Kafka/Pulsar шина ретінде, Mongo - sink/source коннекторлар және Change Streams арқылы.
Redis: ультра төмен жасырындылық қабаты ретінде қатар (кэштер/есептегіштер).
OLAP: ClickHouse/Pinotқа ұзын сканерлер мен BI үшін жүктеу.
Енгізу парағы
1. Домендерді бекітіңіз: Mongo (икемді/жоғары TPS/проекция), бұл SQL-де қалады.
2. Schema contracts: JSON Schema Validation, 'schemaVersion' дегенді анықтаңыз.
3. Индекстерді нақты сұрауларға жобалаңыз; «шулы» деректер үшін TTL қосыңыз.
4. shard key (жоғары түбірлік, біркелкілік) таңдаңыз; қажет болған жағдайда - zone-шардинг.
5. SLO үшін реплика-жиынтықты, Read/Write Concern баптаңыз; read-after-write саясаты.
6. Бақылау және бейіндеуді ,/WT cache/oplog индекстеріндегі тәуекелдерді қосыңыз.
7. + PITR, DR-кластер және тұрақты жаттығулар ұйымдастырыңыз.
8. Кэштер мен шиналарды үндестіру үшін Change Streams/Outbox бағдарламасын қосыңыз.
9. Құжаттардың өлшемі мен тіркемесін шектеңіз; меңзер бойынша пагинацияны енгізіңіз.
10. PII/тенанттар үшін жеке саясат, шифрлау, аудит.
Антипаттерндер
Өнімде «схемасыз»: валидацияның және нұсқалардың болмауы → хаос.
Уақыт бойынша шард-кілт/монотонды - ыстық шард және тұрақсыз p99.
Джойндар '$lookup' индекстерсіз/пагинациясыз үлкен жиындарда.
Транзакцияларды барлық жерде пайдалану - өнімділікті жоғалту.
Логтар үшін TTL/ретенцияның болмауы → көлемі мен құнының өсуі.
Өте маңызды ақша инварианттарын тек Mongo-да қатаң демпотенттіліксіз сақтау.
Қорытынды
MongoDB - iGaming икемді домендері үшін қуатты құрал: профильдер, каталогтар, телеметрия, проекциялар және дербестендіру. Табысқа жетудің кілті - келісім-шарттар мен валидация, ойластырылған индекстеу, сауатты таңдалған shard key, саналы Read/Write Concern, интеграцияға арналған Change Streams және қатаң пайдалану тәртібі (бақылау, бэкап, DR). SQL-ядромен және стримингтік шинамен бірге бұл платформаға жарыс шыңдарына тез интерфейстер мен тұрақтылық береді.