MongoDB和靈活的數據模式
(部分: 技術和基礎設施)
簡短的摘要
MongoDB是一種面向文檔的存儲,具有靈活的電路(BSON),快速插入,水平縮放和功能強大的Aggregation Pipeline。在iGaming中,它非常適合玩家配置文件、靈活CRM卡、事件日誌、遙測、流中的實例化投影、遊戲目錄和面向前面的可壓縮表示。對於現金不變量(錢包/ledger),SQL/CP回路更常見。MongoDB作為閱讀模型和高性能文檔存儲是合適的。
其中MongoDB在iGaming中給出最大值
玩家配置文件和設置:結構變量(位置設置、首選項、KYC元數據)。
內容/遊戲/提供商目錄:快速讀卡、過濾器、標簽、全文。
事件/遙測/日誌:高TPS,時間窗口,TTL存儲。
實例化視圖(CQRS):快速屏幕(領導板、最新動作、聚合)。
個性化/fici online ML: KV模式集合,簡稱TTL。
靈活方案原則: 紀律而不是混亂
MongoDB不是「沒有方案」-方案生活在代碼和驗證中。
建議:1.計劃作為合同:JSON計劃驗證。
2.通過「schemaVersion」字段對文檔進行測試。
3.嚴格的必填字段(id,搜索鍵),稀有屬性的「尾巴」是可選的。
4.限制陣列尺寸和嵌套值(用於索引和RAM)。
5.背景遷移:通過「schemaVersion」進行的升級,shedulers,後門。
示例: 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" }
}
}
}
}
}
});
數據模型和文檔設計
在提示下設計:1個屏幕/結束點=1個文檔或一小組文檔。
非規範化:包括小型嵌套子文件(例如遊戲提供商迷你卡)。
- 嵌入-用於緊密相關且很少更新的片段。
- 鏈接(「ref」)-大尺寸/頻繁升級/重用。
- 大小限制:文檔≤ 16 MB;大型二進制-GridFS/對象存儲。
- 審計/元數據:「createdAt」,「updatedAt」,「traceId」,「tenantId」,「idempotencyKey」。
索引: 閱讀質量和穩定性
索引和實踐類型:- 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 });
文本/自動復制
全文的「text」(語言限制);對於巡回賽-「n-gram」/trigram通過字段和regex方法或Atlas Search。
指數的反模式
所有索引→記錄速度下降。
沒有部分的低基數→低選擇性。
復制的復合體。
在沒有限制的巨型陣列中索引字段。
Aggregation Pipeline: 快速屏幕和報告
使用「$match」 → 「$sort」 → 「$limit」作為早期階段;將索引設計為「$match/$sort」。
「$lookup」用於受控的joins(柔軟,數量合理)。
多項指標的「$facet」;「$unionWith」是集合的組合。
「$merge」/「$out」-實現集合中的結果(閱讀模型)。
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" }
} }
]);
交易、一致性和平均性
單文檔原子-免費原子性;復雜的不變式-考慮按文檔劃分。
多文檔交易(ACID)-帶有復制集,但後期價格更高;逐點應用。
Write Concern / Read Concern:
"w: 關鍵記錄的'majority'(後期成本);
'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在硬鍵上搖搖欲墜。選擇至關重要:- 負載分布:高基數鍵和均勻分布(例如「(tenantId,playerId)」)。
- 避免單調:「createdAt」作為→「熱」陰謀的唯一關鍵。
- Hashed-更均勻地分配記錄。
- Ranged-適用於範圍查詢,但要註意熱尾巴。
- 用於調節/定位(EU/LatAm/TR)的區域緩解(tag ranges)。
js sh.enableSharding("igaming");
db.bets.createIndex({ tenantId: 1, playerId: 1, _id: "hashed" });
sh.shardCollection("igaming.bets", { tenantId: 1, playerId: 1, _id: "hashed" });
反模式:
- 低基數的Shard鍵(「狀態」)是Shard的偏斜。
- 在破折號的集合之間經常出現「$lookup」,而無需通過一個鍵進行共同破解。
- 可變硬鍵(難以更換且昂貴)。
復制集,閱讀和閱讀後寫入策略
復制集=HA和事務基礎。
Read Preference:
關鍵閱讀後寫作的「主要」;
「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%.
度量標準:op-latentity, queue depth,每個次要,cache/WT統計數據的百分比,page faults, lock-waits, Kol in open遊標/連接。
分析:'系統。profile","explain("executionStats")",集合/索引鎖。
Alerts: WT cache pressure的增長,操作緩慢,查詢不屬於索引的增長,次要積壓,chunk migrations/balancer。
性能和調音
WiredTiger Cache:默認情況下~ 50% RAM-驗證配置文件。
Compression: snappy/zstd for Collections, zstd for Magazine-CPU/IO平衡。
用於遙測的Batch插入和bulkWrite。
投影(「{field: 1}」)以免拖動「厚」文檔。
Limit/Skip:避免大型「skip」 →使用遊標/標記(「createdAt /_id」)分區。
為「環形」徽標捕獲的集合。
安全和合規性
Auth/RBAC:集合/DB中的角色,最低要求的特權。
過境中的TLS,磁盤加密(FLE/at rest)。
PII策略:掩碼/別名化,敏感字段的單獨集合。
多重性:前綴/單個DB/集合,「tenantId」過濾器,可以在應用程序中使用類似RLS的層。
審核:包括對關鍵集合的操作審核。
Bacaps,PITR和DR
點對點恢復的+oplog備份卷快照(快照)。
DR在不同地區的復制集;定期恢復演習。
在插入峰值下控制oplog生長(PSP webhooks/錦標賽)。
在shard群集中-與config服務器一致的備份。
與體系結構的其余部分集成
CQRS:團隊擊敗SQL(金錢),事件→ MongoDB的Materialized Views。
Event-Streaming:Kafka/Pulsar作為總線,Mongo是通過連接器和Change Streams進行的sink/source。
Redis:旁邊是超低潛能層(緩存/計數器)。
OLAP:在ClickHouse/Pinot卸載長掃描和BI。
實施支票清單
1.記錄域:在Mongo(靈活/高TPS/投影)中會發生什麼,這保留在SQL中。
2.定義schema contracts:JSON Schema Validation,「schemaVersion」。
3.為實際查詢設計索引;為「嘈雜」數據添加TTL。
4.選擇硬鍵(高基數,均勻性);如有必要-分區。
5.在SLO下配置復制集Read/Write Concern;閱讀後寫入策略。
6.在/WT cache/oplog索引上啟用可觀察性和分析。
7.組織備用+PITR,DR集群和定期演習。
8.連接Change Streams/Outbox以同步緩存和輪胎。
9.限制文檔大小和附件;通過遊標引入分區。
10.PII/Tenant的單獨策略,加密,審核。
反模式
「沒有計劃」在銷售:缺乏驗證和版本→混亂。
按時間/單調鍵是熱鍵和不穩定的p99。
Joins '$lookup'在沒有索引/分割的巨大套裝上。
無處不在地使用事務-性能損失。
缺少TTL/博客轉義 →數量和成本增長。
僅在Mongo中存儲關鍵的貨幣不變量,而無需嚴格的冪等。
三.成果
MongoDB是靈活的iGaming域的強大工具:配置文件,目錄,遙測,投影和個性化。成功的關鍵是電路合同和驗證,經過深思熟慮的索引,精心挑選的軟管鍵,Read/Write Concern意識到,用於集成的Change Streams和嚴格的操作紀律(可觀察性,備份,DR)。結合SQL內核和流媒體總線,這為平臺提供了快速的界面和錦標賽高峰的可持續性。