MongoDBと柔軟なデータスキーマ
(セクション: 技術とインフラ)
簡単な要約
MongoDBは、柔軟な回路(BSON)、高速インサート、水平スケーリング、強力なアグリゲーションパイプラインを備えたドキュメント指向のストレージです。iGamingでは、プレイヤープロファイル、柔軟なCRMカード、イベントログ、テレメトリー、実体化されたストリームプロジェクション、ゲームカタログ、キャッシュされたフロントビューに最適です。通貨不変量(ウォレット/レジャー)の場合、SQL/CPの輪郭はより頻繁に残されます。MongoDBは、読み取りモデルおよび高性能ドキュメントストレージとして適切です。
MongoDBがiGamingを最大限に活用する場所
プレーヤープロファイルと設定:構造変数(ロケール設定、環境設定、KYCメタデータ)。
コンテンツ/ゲーム/プロバイダカタログ:クイックカード読み取り、フィルタ、タグ付け、全文。
イベント/テレメトリー/ログ:高いTPS、時間ウィンドウ、TTLストレージ。
マテリアライズドビュー(CQRS):クイックスクリーン(リーダーボード、最近のアクション、集計)。
パーソナライゼーション/特長オンラインML:コレクションのKVパターン、短いTTL。
柔軟なスキームの原則: カオスの代わりに規律
MongoDBは「スキーマなし」ではありません。スキーマはコードと検証に住んでいます。
推奨される:1.契約としてのスキーム:コレクション内のJSONスキーマ検証。
2.'schemaVersion'フィールドを持つドキュメントのバージョン管理。
3.厳密な必須フィールド(id、検索キー)、まれな属性の「尾」-オプション。
4.配列寸法とネストを拘束します(インデックスとRAM用)。
5.バックグラウンドでの移行:'schemaVersion'、 shedulers、 back fillsによる更新。
例: 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ツリー(プライマリ)
複合:フィールドの順序は頻繁な述語とソートに対応します。
プレフィックスルール:プレフィックスオプションは'(tenantId、 playerId、 createdAt)'で動作します。
Sort:インデックスの最後にある'sort'を考えます(例えば'createdAt: -1')。
js db.bets.createIndex(
{ tenantId: 1, playerId: 1, createdAt: -1 },
{ name: "idx_bets_tenant_player_created_desc" }
);
部分的な/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 through fields and regex approachまたはAtlas Search。
インデックスのantipatterns
「すべて」インデックス→書き込み速度の低下。
部分的な→低い選択性のない低いcardinality。
複製された化合物。
巨大配列内のインデックスフィールドに制限はありません。
集約パイプライン: クイックスクリーンとレポート
'$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" }
} }
]);
トランザクション、コンシステンシー、idempotency
単一文書原子-自由な原子性;複雑な不変量-ドキュメントのパーティショニングを考える。
マルチドキュメントトランザクション(ACID)-レプリカセットで利用できますが、レイテンシが高くなります。ポイントワイズを適用します。
- 'w:クリティカルレコード(レイテンシコスト)のための'magazine';
- 'readConsidence:' magazine'は一貫して読むことができます。
- Idempotency: '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'を唯一のキー→「hot」シャードとして指定します。
- ハッシュ-レコードをより均等に配布します。
- 範囲は範囲クエリに適していますが、ホットテールに注意してください。
- 規制/ローカライズ(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" });
Antipatterns:
- 低いカーディナリティによるシャードキー('status')-シャードのスキュー。
- 1つのキーを同時に共有することなく、シャーディーコレクション間で頻繁に'$lookup'を実行します。
- 変更可能なシャードキー(変更が困難で高価)。
レプリカセット、読み取り、読み取り後のポリシー
レプリカセット=HAとトランザクションベース。
Preferenceを読む:- 'primary'(クリティカルな読み込み後の書き込み);
- 'primaryPreferred'/'secondary'-アナリティクス/非クリティカル。
- SLOとレイテンシーバジェットによる懸念座標の読み取り/書き込み。
ストリーム、CDC、統合の変更
ストリームの変更:挿入/更新/削除のサブスクリプション-次の場合に便利です:- キャッシュレイヤー同期(Redis)
- CRMトリガー/通知、
- OLAP (ClickHouse/Pinot)へのダウンロード、
- リアクティブスクリーン。
- アウトボックスパターン:クリティカルドメインの場合、イベントを別のコレクションにパブリッシュします。これにより、統合の予測可能性が向上します。
観測可能性とSLO
SLO: p99カード読書≤ 10-20 ms;イベントの挿入≤ 20-40ミリ秒;X%内のシャード間の合図差;99 ≥可用性。9%.
メトリクス:op-latency、キューの深さ、セカンダリあたりのアンプの%、キャッシュ/WT統計、ページフォルト、ロックウェイト、オープンカーソル/接続の数。
プロファイリング:'システム。profile'、'explain ("executionStats')'、collection/index locks。
アラート:WTキャッシュ圧力の増加、遅い操作、インデックスに含まれていないリクエストの増加、セカンダリリリクエストのバックログ、チャンク移行/バランサ。
パフォーマンスとチューニング
WiredTiger Cache:デフォルトでは~ 50% RAM-プロファイルの検証。
圧縮:コレクション用のsnappy/zstd、ログ用のzstd-CPU/IOバランス。
テレメトリー用のバッチインサートとbulkWrite。
「厚い」ドキュメントをドラッグしないように投影('{field: 1}')します。
Limit/Skip:大きな'skip'→カーソル/マーカーのページネーション('createdAt/_ id')を使用しないようにします。
「リング」ログのキャップコレクション。
安全性とコンプライアンス
Auth/RBAC:コレクション/データベース上のロール、必要最小限の権限。
トランジット中のTLS、ディスク上の暗号化(FLE/at-rest)。
PIIポリシー:マスキング/エイリアス、機密フィールド用の個別のコレクション。
マルチテナンシー:接頭辞/個々のデータベース/コレクション、'tenantId'によるフィルタ、アプリケーション内のRLS風のレイヤーを使用できます。
監査:重要なコレクションのオペレーションの監査を有効にします。
バックアップ、PITR、 DR
Point-in-Time Recoveryのボリュームのスナップショット+oplogバックアップ。
DR用の別の領域に設定されたレプリカ。定期的な回復演習。
挿入ピーク(PSP webhooks/tournaments)のoplog成長の制御。
シャードクラスタ-コンフィグサーバとの一貫したバックアップ。
他のアーキテクチャとの統合
CQRS:チームはSQL (money)、イベント→MongoDBのMaterialized Viewsをヒットしました。
イベントストリーミング:バスとしてのKafka/Pulsar、 Mongo-コネクタと変更ストリームを介してシンク/ソース。
Redis:超低レイテンシーレイヤー(キャッシュ/カウンタ)として近くにあります。
OLAP: ClickHouse/Pinotにアップロードして、長いスキャンとBIを実行します。
実装チェックリスト
1.ドメインを修正:Mongoで何が起こっているか(柔軟性/高TPS/投影)、 SQLに残っているもの。
2.スキーマ契約の定義:JSONスキーマ検証、'schemaVersion'。
3.実際のクエリのためのインデックスを設計します。ノイズの多いデータのTTLを追加します。
4.シャードキーを選択します(高いカーディナリティ、均一性)。必要に応じて-ゾーンシャーディング。
5.SLOのためのレプリカセット、読む/書く心配をセットアップして下さい;read-after-writeポリシー。
6./WT キャッシュ/oplogインデックスへの監視とプロファイル、アラートを有効にします。
7.バックアップ+PITR、 DRクラスタ、通常の演習を整理します。
8.Change Streams/Outboxを接続してキャッシュとバスを同期させます。
9.ドキュメントのサイズとネストを制限する。カーソルによるページネーションを実装します。
10.PII/テナント、暗号化、監査のための個別のポリシー。
アンチパターン
製品の「スキームなし」:検証とバージョンの欠如→カオス。
時間/単調なシャードキー-ホットシャードと不安定なp99。
インデックス/ペジネーションなしの巨大なセットでJoynes'$lookup'。
あらゆる場所でトランザクションを使用-生産性の低下。
ログのTTL/リテンションの欠如→ボリュームとコストの増加。
重要な金融不変量を厳格な特権なしでMongoにのみ保存します。
[結果]
MongoDBは柔軟なiGamingドメインのための強力なツールです:プロファイル、ディレクトリ、テレメトリー、投影とパーソナライズ。成功の鍵は、契約スキームと検証、思慮深いインデックス作成、適切に選択されたシャードキー、意識的な読み書き懸念、統合と厳格な運用規律(オブザビリティ、バックアップ、DR)の変更ストリームです。SQLコアとストリーミングバスを組み合わせることで、プラットフォームに高速なインターフェイスとトーナメントピークの安定性を提供します。