[英]Order Matching System Design : how to design an efficient and secure crypto account system
語境
我在一家加密貨幣交易所公司擔任后端工程師。 最近,我們的匹配系統面臨性能問題。 當用戶的訂單匹配時,系統將扣除或添加訂單金額到他們的賬戶。 此過程將使用數據庫寫鎖鎖定用戶的帳戶。
問題
如果用戶在短時間內下單過於頻繁,大量的訂單會嘗試鎖定同一條記錄。 在這種鎖競爭的情況下,數據庫事務將超時並重試,直到完成匹配過程。 同時 db CPU 使用率迅速增加。 我們正在嘗試解決此鎖定爭用問題。
目前的系統設計
CREATE TABLE `user_accounts` (
`user_id` bigint(20) unsigned NOT NULL,
`btc` decimal(65,0) NOT NULL DEFAULT '0' COMMENT 'btc balance',
`btc_trade` decimal(65,0) NOT NULL DEFAULT '0' COMMENT 'trading btc amount',
`eth` decimal(65,0) NOT NULL DEFAULT '0',
`eth_trade` decimal(65,0) NOT NULL DEFAULT '0',
`usdt` decimal(65,0) NOT NULL DEFAULT '0',
`usdt_trade` decimal(65,0) NOT NULL DEFAULT '0',
`sol` decimal(65,0) NOT NULL DEFAULT '0',
`sol_trade` decimal(65,0) NOT NULL DEFAULT '0',
`balance_checksum` VARCHAR(255) NOT NULL DEFAULT '',
....
)
上面的 db schema 用於存儲用戶的余額,匹配流程是:
SELECT btc, btc_trade, usdt, usdt_trade, balance_checksum FROM user_accounts WHERE user_id =? FOR UPDATE
UPDATE user_accounts SET btc_trade=?, usdt=?, balance_checksum=? WHERE user_id =?
可能的解決方案
經過一番頭腦風暴,我們得出了一些想法。
account_balances
數據庫架構:當前模式將所有貨幣存儲在同一記錄中,但是系統在匹配過程中僅使用兩種貨幣。 一些開發人員提出了新的數據庫架構,例如:
CREATE TABLE `new_user_accounts` (
`id` bigint(20) unsigned NOT NULL,
`user_id` bigint(20) unsigned NOT NULL,
`currency` VARCHAR(50) NOT NULL DEFAULT '',
`amount` decimal(65,0) NOT NULL DEFAULT '0',
`lock_amount` decimal(65,0) NOT NULL DEFAULT '0',
`balance_checksum` VARCHAR(255) NOT NULL DEFAULT '',
....
)
這種解決方案可能會減少一些鎖定競爭的情況,但是大多數訂單需要交易 USDT 或其他法定貨幣。 因此,我提出了第二種解決方案。
如果我們從 db 模式中刪除校驗和值,我們可以使用 SQL UPDATE user_accounts SET btc_trade=btc_trade-?, usdt=usdt+? WHERE user_id =? AND btc_trade >=?
UPDATE user_accounts SET btc_trade=btc_trade-?, usdt=usdt+? WHERE user_id =? AND btc_trade >=?
. 通過此更新 SQL,事務不需要鎖定。 我們可以徹底解決鎖競爭問題。
該解決方案的一個問題是我必須找到校驗和值的替代方案。 有沒有更好的方法來防止直接通過db操作修改余額或更好的方法來監控非法余額修改操作。
您是否考慮過為 redis 引入管道?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.