订单匹配系统设计:如何设计高效安全的加密账户系统

Order Matching System Design : how to design an efficient and secure crypto account system

提问人:vicxu 提问时间:7/25/2022 最后编辑:vicxu 更新时间:8/4/2022 访问量:225

问:

上下文

我在一家加密货币交易所公司担任后端工程师。最近,我们的匹配系统面临性能问题。当用户的订单匹配时,系统将扣除或添加订单金额到他们的账户中。此过程将使用数据库写锁锁定用户帐户。

问题

如果用户在短时间内过于频繁地下单,大量订单会试图锁定同一条记录。在这种锁争用情况下,数据库事务将超时并重试,直到完成匹配过程。同时,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 用于存储用户的余额和匹配流程:

  1. 如果用户的订单在btc/usdt交易对上匹配,系统首先执行此sql。SELECT btc, btc_trade, usdt, usdt_trade, balance_checksum FROM user_accounts WHERE user_id = ? FOR UPDATE
  2. 使用金额值和校验和来验证用户余额的正确性。此校验和值可以防止直接通过 db 操作修改余额。
  3. 如果余额验证通过,系统会根据更新的金额生成新的校验和,并执行更新SQL。UPDATE user_accounts SET btc_trade=?, usdt=?, balance_checksum=? WHERE user_id = ?

可能的解决方案

经过一番头脑风暴,我们提出了一些想法。

  1. 重新设计数据库架构: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或其他法定货币。因此,我提出了第二种解决方案。

  1. 摆脱校验和机制

如果我们从数据库模式中删除校验和值,我们可以使用 SQL 更新余额 .使用此更新 SQL,事务不需要锁。我们可以完全解决锁争用问题。UPDATE user_accounts SET btc_trade=btc_trade-?, usdt=usdt+? WHERE user_id = ? AND btc_trade >= ?

此解决方案的问题之一是我必须找到校验和值的替代方案。有没有更好的方法来防止直接通过数据库操作修改余额,或者更好的方法来监控非法余额修改操作。

性能 加密货币 系统设计 ReadWriteLock 争用

评论


答:

0赞 ares0x 8/4/2022 #1

你有没有考虑过为redis引入一个管道?

评论

0赞 Community 8/7/2022
您的答案可以通过额外的支持信息得到改进。请编辑以添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何写出好答案的更多信息。