简体   繁体   English

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

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

Context语境

I am working in a crypto exchange company as backend engineer.我在一家加密货币交易所公司担任后端工程师。 Recently, we are facing a performance issue in our matching system.最近,我们的匹配系统面临性能问题。 When user's order got match, system will deduct or add order's amount to their account.当用户的订单匹配时,系统将扣除或添加订单金额到他们的账户。 This process will lock user's account with database write lock.此过程将使用数据库写锁锁定用户的帐户。

Problem问题

If users make order too frequently in a short time, lots of order will try to lock the same record.如果用户在短时间内下单过于频繁,大量的订单会尝试锁定同一条记录。 Under such lock contention situation, DB transaction will timeout and retry until finishing matching process.在这种锁竞争的情况下,数据库事务将超时并重试,直到完成匹配过程。 Meanwhile db CPU usage increase quickly.同时 db CPU 使用率迅速增加。 We are trying to fix this lock contention problem.我们正在尝试解决此锁定争用问题。

Present System Design目前的系统设计

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 '',
  ....
)

Above db schema is used to store user's balance and matching flow is that:上面的 db schema 用于存储用户的余额,匹配流程是:

  1. If user's order got match on btc/usdt trading pair, the system execute this sql firstly.如果用户的订单在btc/usdt交易对上匹配,系统首先执行这个sql。 SELECT btc, btc_trade, usdt, usdt_trade, balance_checksum FROM user_accounts WHERE user_id =? FOR UPDATE
  2. Using amount value and checksum to verify correctness of user's balance.使用金额值和校验和来验证用户余额的正确性。 This checksum value can prevent from modifying balance directly by db operation.这个校验和值可以防止db操作直接修改余额。
  3. If balance verification pass, the system generate new checksum based on updated amount and execute update SQL.如果余额验证通过,系统会根据更新的金额生成新的校验和,并执行更新 SQL。 UPDATE user_accounts SET btc_trade=?, usdt=?, balance_checksum=? WHERE user_id =?

Possible Solutions可能的解决方案

After some brainstorming, we came out some of ideas.经过一番头脑风暴,我们得出了一些想法。

  1. Redesign account_balances db schema:重新设计account_balances数据库架构:

Current schema store all currencies in the same record, however the system only use two currencies during matching process.当前模式将所有货币存储在同一记录中,但是系统在匹配过程中仅使用两种货币。 Some of developer present new db schema like:一些开发人员提出了新的数据库架构,例如:

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 '',
  ....
)

This solution might reduce some lock contention situation, however most of order require trading USDT or other fiat currencies.这种解决方案可能会减少一些锁定竞争的情况,但是大多数订单需要交易 USDT 或其他法定货币。 Therefore, I proposed the second solution.因此,我提出了第二种解决方案。

  1. Get rid of checksum mechanism摆脱校验和机制

If we remove checksum value from db schema, we can update balance by using SQL UPDATE user_accounts SET btc_trade=btc_trade-?, usdt=usdt+? WHERE user_id =? AND btc_trade >=?如果我们从 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 >=? . . With this update SQL, the transaction does not require the lock.通过此更新 SQL,事务不需要锁定。 We can solve lock contention problem completely.我们可以彻底解决锁竞争问题。

One of problem of this solution is that I have to find out a alternative for checksum value.该解决方案的一个问题是我必须找到校验和值的替代方案。 Is there better way to prevent from modifying balance directly by db operation or better way to monitor illegal balance modification operation.有没有更好的方法来防止直接通过db操作修改余额或更好的方法来监控非法余额修改操作。

Have you considered introducing a pipeline for redis?您是否考虑过为 redis 引入管道?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM