Logo GH

PostgreSQL:最佳實踐和索引

(部分: 技術和基礎設施)

簡短摘要

PostgreSQL是金錢,KYC和iGaming中具有法律意義的條目的「真相核心」。它提供ACID保修、強大的SQL和可擴展性。為了抵禦錦標賽和PSP webhook的高峰,關鍵是:素養方案,索引,派對,自動休假,WAL調音和可觀察性。下面-實踐和模板設計師。

1)體系結構和SLO

PostgreSQL角色:寫入+復制副本的領導者;熱屏幕-緩存/投影(Redis/實例化視圖)。

SLO示例: p99 「INSERT/UPDATE」錢包≤ 25-40毫秒;p99讀取余額≤ 10-15毫秒;復制副本≤ 2-5 c;可用性≥ 99。9%.

Read-after-write policy:自定義的交易後屏幕從領導者處讀取或等待復制時差。

2)電路設計

貨幣核心(錢包,ledger)規範化+非規範化(CQRS/投影)。
嚴格的限制是:「NOT NULL」,「CHECK」,「UNIQUE」,帶有有針對性的「ON DELETE/UPDATE」(RESTRICT/SET NULL/NO ACTION)的FK。
模式轉換:上下/下移,功能標誌;避免在熱時中斷重命名。
標識符:「BIGINT」+序列(或分布ULID/UUIDv7)。對於熱插件-單獨的tablespace/WAL卷中的序列。

3)索引: 什麼,在哪裏以及如何

3.1 B樹(默認值)

時間:FK上的精確匹配,範圍,排序,「JOIN」。
模式:「WHERE player_id=?」,「ORDER BY created_at DESC LIMIT 100」。

實踐:
  • 多項索引-與條件的順序匹配。
  • Covering: `INCLUDE (...)` для index-only scan.
  • 在'ORDER BY……DESC在「磁帶」上。
sql
CREATE INDEX idx_tx_player_created_desc
ON tx (player_id, created_at DESC) INCLUDE (amount_cents, status);

3.2 GIN (JSONB,數組,全文)

時間:JSONB按鍵/路徑搜索,標簽數組,FTS。
變體:trigram的「gin_trgm_ops」,「jsonb_path_ops」/「jsonb_ops」。
練習:嚴格限制搜索字段,思考基數。

sql
CREATE INDEX idx_profile_jsonb_gin
ON player_profile USING GIN (data jsonb_path_ops);

-- Search by email/name with typos
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE INDEX idx_player_trgm ON player USING GIN (email gin_trgm_ops);

3.3 GiST(地理/範圍/簽名)

時間:地理定位(IP地理,半徑),間隔,近鄰。
較少用於金錢核心,有利於地理約束/負責任的遊戲。

3.4 BRIN(大型「appendix」-按時間排列)

時間:數十億行,自然時間相關性(投註/事件日誌)。
優點:小尺寸,便宜的服務。
缺點:粗略的選擇性→與黨派結合。

sql
CREATE INDEX idx_bets_brin ON bets USING BRIN (created_at) WITH (pages_per_range = 64);

3.5 Hash

很少需要:在沒有範圍的情況下,每個列相等;B-Tree更常見。

3.6部分和表達式

分區索引:加速熱子集(活動,「status='pending」)。
Expression index:預測密鑰('lower (email)'、'(data->>'psp_tx')')。

sql
CREATE INDEX idx_withdraw_pending ON withdrawals (player_id)
WHERE status = 'pending';

CREATE INDEX idx_tx_psp_tx ON tx ((data->>'psp_tx'));

3.7指數的反模式

「所有索引」:過多的索引會抑制記錄和VACUUM。
重復索引(相同的列集/順序)。
每個基數非常低的列的索引(例如,具有2個值的「狀態」)-做部分。

4)參與式

為什麼:減少斑點,加快VACUUM/掃描速度,促進撤回/存檔。
電路:投註日誌的日期(日/周)RANGE;大型用戶表的「player_id」 HASH;組合起來。
輪換練習:提前創建未來的派對,「ATTACH PARTITION」和舊的存檔-「DETACH」+移動。

sql
CREATE TABLE bets (
bet_id BIGINT PRIMARY KEY,
player_id BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL,
amount_cents BIGINT NOT NULL
) PARTITION BY RANGE (created_at);

CREATE TABLE bets_2025_11_05 PARTITION OF bets
FOR VALUES FROM ('2025-11-05') TO ('2025-11-06');

5)最小碎片的插入/更新

HOT更新:在熱桌上保留「fillfactor」(例如90),以便在頁面上留空。
TOAST:大型JSONB/文本-保持緊湊;將笨重的字段存儲在單獨的表中。
UPSERT:使用'ON CONFLICT……DO UPDATE具有偶數邏輯。

sql
INSERT INTO wallet (player_id, balance_cents, updated_at)
VALUES ($1, $2, now())
ON CONFLICT (player_id) DO UPDATE
SET balance_cents = wallet. balance_cents + EXCLUDED. balance_cents,
updated_at = now();

6)交易、鎖定和競爭

隔離級別:大多數路徑的「READ COMMITTED」;「REPEATABLE READ」/「SERIALIZABLE」點點(報告,離線蹦床)。不要讓他們長時間。
鎖定類型:row-level(悲觀的「FOR UPDATE」),table level(DDL),用於分布式mutex的咨詢鎖。
Deadlocks:短交易,單一實體更新順序,時間表(「lock_timeout」,「statement_timeout」)。
任務隊列:「SKIP LOCKED」用於分布式工具池。

sql
-- batch processor removes work without racing
SELECT id FROM jobs
WHERE status='pending'
FOR UPDATE SKIP LOCKED
LIMIT 100;

7) Autovacum,統計數據和bloat

VACUUM/ANALYZE:保持最新統計數據(「default_statistics_target」),在熱表上調節AV(觸發閾值如下)。
註意wraparound(age(txid)<20億),「vacuum_freeze_min_age」。
bloat控制:定期reindex/CLUSTER在高峰以外的重指數;參與減少問題的規模。

策略示例(表格設置):
sql
ALTER TABLE tx SET (
autovacuum_vacuum_scale_factor = 0. 05,
autovacuum_analyze_scale_factor = 0. 02,
autovacuum_vacuum_cost_limit = 4000
);

8)內存,支票和WAL

內存

「shared_buffers」:RAM的20-25%(取決於配置文件)。
'work_mem':通過操作!以保守方式(例如,8-64MB)進行配置,並逐點提升報告角色。
「maintenance_work_mem」:主要索引/恢復(任務512MB-2GB)。

WAL和Checkpoints

NVMe for WAL,一個單獨的卷;'wal_compression=on'。

"checkpoint_timeout" 10-15分鐘,"max_wal_size"在更改量下,"checkpoint_completion_target ≈ 0。9`.

對於插入峰值,是batch插入和組commites。

9)復制和容錯能力

引導復制:同步至最接近(半同步)的RPO≈0 -30秒;異步讀取/分析。
促銷和召集:Patroni/復制經理;排除「雙重領導者」。
Hot standby: 'hot_standby_feedback'謹慎(bloat生長),最好在副本上馴服冗長的事務。

10)Bacaps和PITR

完整+增量備份,離網副本;WAL的「archive_command」。
PITR:在展位上檢查恢復時間點;規範RPO/RTO(錢包-分鐘,logi-幾十分鐘)。
DR演習(遊戲日):定期恢復檢查。

11) JSONB和「靈活電路」模型"

JSONB-非常適用於很少閱讀/可變屬性(KYC元數據,PSP參數)。
嚴格驗證關系列中的必填字段;JSONB-用於「尾巴」細微差別。

索引: 按所用路徑逐點GIN;避免「一個巨大的GIN對一切。」

sql
-- partial GIN index only for documents with the desired key
CREATE INDEX idx_kyc_docnum ON kyc USING GIN ((data->'doc'->'number'))
WHERE data? 'doc';

12)全文和fuzzy搜索

內置FTS:「tsvector」+GIN;對於錯字-「pg_trgm」。
對於繁重的Log/Game搜索-外賣到搜索引擎(ES/OpenSearch),並在PG中存儲鏈接/元數據。

13)可觀察性和分析

pg_stat_statements:最慢的/頻繁的查詢,正常化。
EXPLAIN (ANALYZE, BUFFERS):閱讀計劃,在熱軌上搜索seq掃描。
度量標準:TPS、p95/p99、checkpoints、「replication_lag」、deadlocks、bloat、AV循環、cache-hit ≥ 95%。
Alerts: lags增長,「idle in transaction」,意想不到的seq scan, WAL風暴。

14)連接池和準備好的查詢

Puller(PgBouncer)在Web流量的「交易」模式下;「會議」在長光標/後臺。
預置狀態/參數化→較少的解析,穩定計劃。
將最大貝肯德數('max_connections'低;池由閥門接管)。

15)安全和合規性

過境中的TLS,磁盤加密,KMS/外鍵。
RBAC:最低權利,閱讀/寫入/管理角色劃分。
RLS(Row-Level Security)用於多影子腳本。
PII:掩碼/別名,保留期。
審計:關鍵表上的「pgaudit」/審計觸發器(錢包/ledger)。

16)iGaming的典型模板

16.1 錢包和ledger(嚴格一致性)

Индексы: `wallet(player_id PK)`, `ledger(player_id, ts DESC)` + `INCLUDE (delta_cents, reason)`.

事務更新資產負債表並寫入ledger;半同步復制;緩存僅作為投影。

16.2投註歷史(高TPS,按玩家/時間閱讀)

每天/每周派對,BRIN計時+B-Tree'(player_id,created_at DESC)'。
通過「DETACH PARTITION」重建→在OLAP中存檔。

16.3個PSP Webhooks(burstami,retrai)

「原始」事件隊列(僅append-only),時間分期,「status='pending」部分索引。
「idempotency_key」/「psp_tx」(UNIQUE)的冪等性。

17)實施支票

1.確定SLO和read-after-write策略。
2.為實際查詢(查詢配置文件)設計關鍵索引。
3.在有重制/上標模式的地方啟用分期。
4.在熱桌上配置AV/ANALYZE, 請註意斑點/wraparound。
5.將內存、WAL和checkpoint調到高峰窗口。
6.設置連接池和「pg_stat_statements」;建立一個Alerta。
7.復制+DR+PITR-是強制性的;進行練習。
8.將JSONB和GIN限制為僅必要的路徑;使用partial indexes。
9.通過使用「SKIP LOCKED」來減少事務持續時間。
10.審計/PII/加密/角色扮演模型-在開始付款之前。

18)反模式

一個「通用」索引用於所有,並且沒有查詢分析。
冗長的「掛起」交易(「交易」)→鎖定/增長。
依靠副本進行閱讀後寫作,而不考慮滯後。
「以防萬一」將所有內容存儲在JSONB中,並將整個文檔索引為GIN。
零控制VACUUM/ANALYZE和缺乏滯後/支票監測。
高峰時段的大規模遷移/DDL。

19)有用的嗅探

請求計劃和緩沖區

sql
EXPLAIN (ANALYZE, BUFFERS, VERBOSE)
SELECT amount_cents
FROM ledger
WHERE player_id = $1
ORDER BY ts DESC
LIMIT 100;

對「重」查詢進行分析

sql
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
SELECT query, calls, total_exec_time, mean_exec_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;

政黨輪換(想法)

sql
-- create a party for tomorrow
CREATE TABLE bets_2025_11_06 PARTITION OF bets
FOR VALUES FROM ('2025-11-06') TO ('2025-11-07');

結果

PostgreSQL能夠在iGaming平臺上拉動「金錢和真相」,同時線性負載增加-如果對索引,分量,自動停機,WAL/內存,復制/DR和可觀察性進行了紀律處分。從查詢簡介和SLO開始,根據真實模式構建索引,隔離熱桌,包括嚴格的操作衛生-並且基礎可以預測地保持比賽和峰值支付。

Contact

與我們聯繫

如有任何問題或支援需求,歡迎隨時聯絡我們。我們隨時樂意提供協助!

Telegram
@Gamble_GC
開始整合

Email 為 必填。Telegram 或 WhatsApp 為 選填

您的姓名 選填
Email 選填
主旨 選填
訊息內容 選填
Telegram 選填
@
若您填寫 Telegram,我們將在 Email 之外,同步於 Telegram 回覆您。
WhatsApp 選填
格式:國碼 + 電話號碼(例如:+886XXXXXXXXX)。

按下此按鈕即表示您同意我們處理您的資料。