数字货币交易系统架构设计
交易系统是一个读写请求频率都很高的系统,优化读请求比较轻松,优化写请求是难点,往往很难做到无限扩展。
首先尽可能按照业务逻辑进行分区,其次要兼顾持久化、数据一致性和性能各方面的要求,甚至要在其中进行权衡,比如数据的最终一致性。
好在业务层面大家已经习惯了异步的处理机制,发起请求和请求执行结果是异步的,这使得我们可以采用流水线架构提高吞吐量。
流水线
下单
下单是个无状态的Web服务,冻结资产成功后把请求转发给撮合引擎。撮合引擎
撮合引擎需要维护一个持久化的OrderBook。撮合后输出成交记录和订单状态变更。清算
根据成交结果修改用户资产。行情分发
根据成交记录计算K线、深度、最近成交等行情数据。撮合引擎首先可以按照币对分区,但是单个币对的请求基本上需要顺序执行。具体实现用关系数据库(比如postgresql的plpgsql)吞吐量可以做到每秒上万比成交,并且持久化和可用性方面都不用担心。
性能上要再上一个数量级只能自己在内存实现,需要自己处理好数据持久化,容错容灾等机制,一般来说每秒几十万比成交都还比较轻松。
清算的关键点在于多币种资产系统的设计,在确保资金安全的前提下提升性能。资金对账可以参考复式记账法。另外对系统钱包、手续费账户等热点系统账户特殊处理,避免性能瓶颈。
行情分发里面K线的处理稍微麻烦点,逻辑上K线就是对成交记录的一次聚合查询:
但是不停的全量扫描肯定不行,使用continuous aggregates机制,持续的对增量数据进行聚合,一些专门的时序数据库都支持这种操作,postgresql的 timescaledb 扩展也可以。 另外只有1分钟的k线需要直接从成交记录里聚合,其他k线可以从低纬度的k线数据聚合而成。
系统整体性能取决于短板,短板往往出现在数据库操作并且数据量大的时候,成交记录和订单记录的插入和变更,对于这种插入为主的时序数据,使用 timescaledb 可以轻松处理上百万插入tps。
看到很多因为使用方式不佳造成关系数据库性能底下的案例,比较可惜,现在Postgresql的可玩性已经很强,尤其大量扩展,搭配其他组件一起使用,应对大部分的业务压力都是问题不大的,同时又能保留关系数据库的便利。
交易系统还有许多其他模块(比如钱包)以及很多细节问题(比如高可用、对账等),后面的文章再慢慢聊。
本人目前自由职业,可以提供技术方面的咨询服务,有这方面需要的朋友,欢迎联系。
发表回复