【墨夜拎月·web3.0·数字货币交易所】撮合系统设计调研(1)

952 阅读28分钟

撮合交易系统现状

撮合交易是指卖方在交易市场委托销售订单、买方在交易市场委托购买订单,交易市场按照一定的原则(可以是价格优先或时间优先等)确定双方成交的价格并生成电子交易合同,并按照交易订单指定的交割仓库进行实物交割的交易方式。

撮合价格的计算是建立在买入价格PB必须大于或等于卖出价格PS的基础上的:

当PB等于PS时,成交价格即按照PB (PS)制定

当PB大于等于PS时,若前一笔成交价PP小于PS则按照PS定价,若PP大于PB则按照PB定价

主流金融交易撮合系统

美国道富 Currenex

Currenex交易平台在订单撮合以及流动性狙击方面釆用了创新的专利技术,可以帮助用户将可以从多达六十多家银行的流动性聚集到先进的电子订单管理系统中。Currenex系统的特点如下:

撮合引擎平均速度低于850微秒

 采用低延时的先入先出优先顺序的订单撮合

健壮的订单管理功能安全性高

香港交易所Genium INET

 Genium INET系统的特点如下:

交易能力明显提升

改进了清算过程减少了运行时间

支持通过中心网关的订单处理超低延时架构

最大程度向上兼容

 支持很多新功能(如量身定做的订单组合等)

告诉消息总线提供低延时订单交易

 降低了会员方的硬件成本

ICAP 公司 EBS Spot Ai

 ICAP公司的EBS Spot AiP6]是可以提供客户交易系统与市场之间的直接两路接口的自动化交易工具,它使用了支持釆用XML或FIX协议在服务提供商(ICAP)以及服务使用方(EBS Spot Ai客户)之间双向消息交换接口。EBS Spot Ai主要用于数学模型、套利模型、风险管理模型与流执行价格等场景。釆用EBS Spot Ai的好处主要有:

高效自动的全时区全币种全天候自动化交易

最大化的交易机会

消除机构在无人工干预情况下的风险

为全局市场带来流动性增长

伦敦 Liffe Connect

 由伦敦国际金融期货期权交易所(Liffe)设计和开发的Liffe Connect交易系统是一个兼具高速执行和高度灵活的电子交易系统。Liffe Connect的主要特性为:

对大容量的复杂品种交易的支持度高

对多种交易规则都有支持

 对多种价格算法都有支持

可发布实时市场行情信息

开放式架构以及前后端一体化接口

使用自动行情系统,可以用工业标准模式为选择的合约产生最新指导价

支持对订单流的人工动态干预

 可扩展性好,易于实现系统升级

金融交易撮合系统的技术发展

    电子金融交易中的撮合交易,主要釆用撮合引擎来提供交易场地,通过买卖双方生成相应买卖订单,提交至撮合引擎,由撮合引擎执行撮合算法实现订单的撮合,并将生成订单提交至清算系统进行清算与交割。

    由对国内外金融撮合系统的发展趋势可以看出,电子金融交易发展至今,撮合技术主要是从数据库撮合技术向内存撮合技术发展,这是因为数据库撮合技术越来越无法满足金融交易对于高可靠性、高性能、强安全性、可扩展性以及易维护性的需求。

基于数据库的撮合方式

 在电子交易系统发展初期,撮合处理一般都在数据库中进行,这样做的好处是数据库非常易于理解与实现。当交易方下单后,撮合系统从数据库中读取交易方的资金及持仓信息,然后再从数据库中査找可以与之匹配的另一买卖方订单,并判断成交数量并生成交易记录直到当前订单全部撮合完毕或不能继续成交。

 这种撮合技术的优势就是数据一致性高,但是缺点就是可靠性差、处理速度慢并且无法满足当今日益增长的大量用户请求。

基于内存的撮合方式

    基于内存的撮合方式是指在撮合过程中,交易系统所涉及到的所有数据都存储在撮合引擎的内存中,并且交易过程中减少数据库访问,撮合结果与中间数据也完全存储在内存中,而且可以降低系统的输入输出过程。基于内存撮合可以大大提高撮合速度。

对比分析

核心技术

逻辑时钟

    在分布式系统中设置全局唯一的时钟,事件同步就可以很方便的解决,因为根据全局唯一的时钟可以方便的判断分布式系统中事件的先后顺序,从而帮助子系统确定一致的事件顺序,为解决这一问题逻辑时钟应运而生。所谓逻辑时钟,是指能为本地启动的所有活动,赋予一个编号的机制,类似于用一个计数器给所有进程编号。在系统中,每一个事件都拥有自己的逻辑时钟C。如果一个事件Ai先于Bj发生,那么相应的逻辑时钟C(i,A)<C(J,B),其中i,j是A,B所在的物理进程。为了满足上述条件,必须遵循以下规则:

根据事件发生的先后,赋予每个事件唯一的逻辑时钟值。

若事件A是进程i发送的一条消息m,消息m中应包含一个时间邮戳T(m)=C(i,A),当接收进程j在收到消息m时,如果其逻辑时钟CG,B)<C(i,A),则应当重置CG,B)使其大于或等于C(i,A)。

    逻辑时钟一般作为消息中间件层存在于分布式系统中,用于给消息确定逻辑时间截

远程过程调用RPC

    RPC和C/S编程模式类似,在建立RPC服务以后,客户端的调用参数通过底层的RPC传输通道,可以是UDP,并根据传输前所提供的目的地址及RPC上层应用程序号转至相应的服务器端,且此时的客户端处于等待状态,直至收到应答或超时信号。当服务器端收到请求消息,则会根据注册RPC时告诉RPC系统的例程入口地址,执行相应的操作,并将结果返回至客户端。

可靠多播

    在进程失败的情况下的原子多播的可靠多播特性就能保证消息要么就被发送给所有的进程,要么就不向任何进程发送此外还可以保证所有的消息都按相同的顺序发送给所有的进程。在撮合引擎集群采用多机热备份的状态机复制模型之后,系统需要采用可靠的多播来使撮合引擎集群可以可靠接收消息。新的订单总是采用原子多播的形式向所有副本进行多播,然后在本地执行。多播的情况下消息排序通常有以下四种排序方法:

无排序

先入先出排序

因果关系排序

完全排序

事件队列管理(虚拟同步模型)

     运行在网络中的程序以进程组的形式管理自己,并且可以向进程组发送消息,而不是向特定的进程发送消息。每个消息都会被以完全相同的顺序递交给进程组的成员,即使两个消息时同时被不同发送方发送的也可以保证这样的特性。

     虚拟同步模型具有代表性的有:

        1) 康奈尔大学的Isis,Horus,Ensemble系统

        2) 耶路撒冷希伯来大学的Transis系统

        3) 约翰霍普金斯大学的Spread系统

        4) Corosync公司的Corosync系统

现有系统的问题

    当前作为交易中心的主力撮合系统的数据库撮合技术主要存在的问题有:

交易速度低(约为10笔/秒)

系统延时大(约为100毫秒/笔)

系统容错性较差

撮合系统设计目标

    1) 系统具有高容错能力

    2) 高速订单撮合算法

    3) 低延时实时撮合

    4) 快速故障检测

    5) 快速备份切换

    6) 一致性数据库写入

系统总体设计

系统架构

(1) 用户:终端用户委托报价与数量,生成订单发送至交易平台。

(2) 网关:负责收集用户订单,并将其派发给撮合引擎。

(3) 撮合引擎:交易系统中的核心部分,用于接收订单并根据业务逻辑实现订单撮合同时生成交易记录,随后给予用户交易结果反馈。

(4) 数据库:用来存放交易过程中的订单和交易记录,实现数据持久化。

撮合交易算法

   撮合引擎的核心业务模块就是撮合交易算法,撮合交易算法的任务一方面是完成对客户所下订单进行公平合理的排列和撮合功能,也要保证撮合算法的公平性、高效性以及扩展性等。

   1) 订单队列

   撮合交易的重要组成部分就是买卖订单,通过对买卖订单进行撮合最后形成交易记录。所以对无法立刻完成撮合的订单,需要有买入队列和卖出队列保存订单。队列按照“价格优先、同价格下时间优先”的原则。买入队列按照委托价格从低到高的顺序,卖出队列则按照委托价格从低到高的顺序排列。

   2) 撮合顺序

 

   撮合引擎接收到新的买入订单,则会到卖出队列的头部查找是否存在符合价格规则的卖出订单,如果存在卖出价格小于或等于买入价格的订单,则从队列中取出此订单并撮合成一笔交易;如果卖出队列为空或队列头部不满足价格关系,则将买入订单插入买入队列中,由于买入队列是按照价格与时间先后进行排序,所以新插入的订单会经过一次排序插入到买入队列的相应位置。

内存撮合

      内存撮合技术,通过最大程度去除与数据库的交互过程,将整个错和逻辑放在内存中进行

      提高内存撮合技术可靠性可采用多机热备份及分布式一致性技术作为补充,从而获得内存撮合技术的高性能以及数据库撮合技术的数据持久性。

多机热备份

     多机热备份技术,将一组撮合引樂部署成互为备份的撮合引擎集群,并且在同一时间内只有一台撮合引擎提供服务。当其中运行这的一台撮和引擎出现故障无法继续正常工作 ,撮合引擎猫群会迅速检测到这个故障,并选举出一个备份撮合引擎接管故障撮合引舉的任务从而保证整个撮合系统的正常运行.

 

内存状态机复制

      多台互为热备份的难点是保证服务器之间的数据一致。

      内存状态机复制即将撮合算法视作一个确定性状态机,将其复制多份并部署到撮合系统中的多台撮合引擎中。每个撮合引擎副本从相同的初始状态开始运行,当撮合系统收到网关发来的订单时,系统中的每个撮合引擎都会撮合这个订单,并依次产生交易记录,同时更新确定性撮合算法状态机的独立状态。通过这样的方式,当撮合系统正常运转时,每个撮合引擎副本都会具有相同的结果状态;当撮合系统出现故障或异常时,撮合引擎就会出现状态的不一致情况,换句话说一旦撮合系统的结果或状态出现了不一致的情况就可以断定系统出现了异常。

关键技术点

     1) 将确定性撮合算法状态机服务部署到多个独立撮合引擎

     2) 接收网关订单,并作为确定性撮合算法状态机的输入

     3) 根据撮合算法需求,选择一种订单排序方式

     4) 每个撮合引擎对按照排序方式排序过的订单进行撮合

     5) 将确定性撮合算法状态机输出的交易记录作为给用户或数据库的响应

     6) 监控撮合引擎副本的状态或输出的差别

解决方案

    1) 采用原子多播解决撮合引擎订单的可靠多播与全局有序性

    2) 采用基于无锁订单队列的流水线撮合技术提供快速的订单撮合

    3) 采用异步一致性持久化技术实现与数据库的交互

    4) 采用失效备援技术对撮合引擎集群进行状态监控并保证系统的容错能

    5) 采用进度追赶技术解决将故障撮合引擎的恢复或新撮合引擎的加入

系统架构

硬件架构

     通过对产品集群进行扩充,增加撮合引擎数量,可以增强产品集群的可靠性。将不同金融产品转发到不同的撮合产品集群中可以实现多产品高效并行撮合。

软件架构

        核心部分业务层主要由撮合引擎集群组成,每个撮合引擎采用原子多播将订单定序后进行撮合处理,并结合无锁订单队列实现高效流水线撮合,最后结果写入本地日志。整个业务流程由消息传递总线将消息反馈给转发层。转发层则根据产品转发规则将订单转发给相应撮合引擎集群;而撮合引擎将本地日志中的交易记录读取到异步持久化代理进程中,并进而与数据层的异步持久化写入进程通信,并最终持久化到数据库中。本地日志增强了撮合系统数据的可靠性,在出现故障后,数据仍就可以从本地日志屮恢复;而界步的持久化机制则提高了数据的持久化吞吐率。

 

撮合引孳架构

(1) 交易订单接收线程:负责从网关接收订单,并完成原子多播定序流程。

(2) 交易订单发送线程:将定序完成的订单发送给相关撮合业务线程。

(3) 交易信息发送线程:将订单交易状态反馈给网关。

(4) 外围业务逻辑线程:进行撮合数据的准备处理,更新内存订单数据。

(5) 撮合业务逻辑线程:根据确定性撮合算法撮合接收的订单。

(6) 交易行情发布线程:处理内存行情信息并发布给网关。

(7) 同步日志写线程:将订单撮合产生的交易记录同步持久化到本地日志文件。

(8) 异步持久化代理进程:异步将日志文件中的数据读取并持久化到数据库。

(9) 订单信息:存储订单的相关价格、数量、用户、限制、类型和状态等信息

(10) 交易行情信息:撮合交易过程中的交易行情信息。

内存状态机复制关键技术

原子多播

问题描述

    输入的订单顺序由于网络传输发生了乱序

    导致

状态机模型 

    原子多播通讯框架在原子多播层进行消息的排序和同步操作,将消息接收和排序抽象成为确定性有限状态机,根据下图所示状态机进行状态迀移,实现在多次原子多播中保证消息完全排序之后投递给应用程序层

 

    该有限状态自动机可以分为消息发送方状态以及消息接收方状态。

    对于消息发送方来说主要分为以下几步:

    1) 广播消息到进程组中的其他成员

    2) 接收来自接收方的消息确认信息

    3) 确定消息最终的序列号

    4) 将决定出的最终序列号广播给其他成员

    对于消息接收方来说主要分为以下几步:

    1) 接收来自发送方的广播消息

    2) 将消息放入消息队列,并标记当前消息为不可投递状态

    3) 回复消息发送方确认消息

    4) 接收来自发送方的最终消息序列号,修改当前消息序列号并标记当前消息为可投递,然后投递当前消息

消息发送方内部实现

    原子多播在消息发送方的工作方式

     消息发送方首先将消息多播到消息接收方,并将多播消息记录在发送队列中,当接收到返回确认消息后确定最大序列号,并作为最终序列号再次广播到接收方。

消息接收方内部实现

    原子多播在消息接收方的内部架构

流水线撮合技术

     采用流水线式撮合,可以明显提高具有多种独立业务的撮合系统的吞吐率。而实现撮合软件流水线的关键技术在于提高各流水线级别之间的订单消息传递方式。

 

     撮合流水线的关键技术就是不同流水线级别之间的消息队列的设计。由于普通的消息队列是采用加锁来保证其数据的一致性,但是在金融交易系统中由于交易发生频率非常高,频繁的加锁和解锁操作降低了系统的处理速度和效率,无法实现流水线的要求。

     在无锁队列中采用了三个指针标记数据可读可写和刷新的位置。读操作将会从队列头部开始读取单位长度的数据,并将读指针向缩短队列长度的方向移动一位;写操作在队列的尾部进行附加操作,同时将写指针向增加队列长度的方向移动一位。但是当一个元素被写入无锁队列中时,如果不对队列进行刷新操作,那么是无法将其读取出来的。通过将读写操作放在不同的线程中进行,同时釆用CAS原子操作来完成刷新和读取时的操作,这样可以保证线程安全以及无锁特性。

异步一致性持久化

问题描述

 (1) 同步持久化,即撮合引擎生成交易记录之后直接将其写入数据库,待其返回写入成功后再执行下一条交易记录的持久化

  (2) 异步持久化,即撮合引擎生成交易记录之后接将其提交数据库处理,只要数据库确认收到该交品记录就开始下一条订单的持久化

系统实现

         优化的三个部分:撮合引擎端、数据库端和撮合引擎集群的IP迁移

         在撮合引擎端如下图所示,首先将撮合结果交易记录釆用同步写入到保存在本地磁盘系统的日志文件,以保证数据的可靠存储。然后通过独立的进程监视并不断从日志中的文件句柄位置开始读取数据并保存至内存;随后数据库代理进程则与数据库端连接,获得数据库己经写成功的交易记录编号,并将内存中的后续交易记录信息以数据库拉的形式进行传递,并从内存中抹去写成功的记录。

         在数据库端如下图所示,由数据库写入进程负责与撮合引擎对应的TP连接,通过将当前己经写成功数据库的交易记录序号作为冗余信息发送给主撮合引擎,来获取后续的交易记录信息。在得到批量交易记录信息之后,数据库端进程对其进行解析并批量写入数据库。

 

        在撮合引繁集群IP迁移端如下图所示,通过给主抛合引擎配置虚拟IP,当主引舉出现故障时进行虚拟IP迁移,保证撮合引攀策群提供可靠地将数掘持久化到数掘库。

失效备援

   金融交易系统对于可靠性的要求使得撮合引擎系统要可以在很短的时间内快速检测到系统故障并釆用相应的应对措施达到失效备援的目的,如用心跳包监控撮合引擎的正常运行的方式进行设计实现,出现异常时釆用IP漂移的方式掩盖故障,从而持续提供可靠服务

网关失效备援

       网关间隔固定时间,发送含有特定内容的心跳数据包到撮合引擎,若连续若干次没有接收到心跳反射,则暂时判定此撮合引擎出现故障,同时将该撮合引擎排除到原子多播集群之外。当活动的撮合引擎总数低于警戒线时,则触发报警动作,当低于可运行下限时,则整个系统停止运转,并触发致命报警动作

数据库失效备援

      数据库通过配置在撮合引繁奥群上的IP拉取数据,当拥有该IP的撮合引擎出现故障时,系统将IP漂移到同 也在运行的热备份撮合引擎上,数据库迎过和运行在撮合引擎上的代理进程通信继续数据拉取。

进度追赶

     进度追赶发生在新的撮合以及发生过故障的撮合引擎新加入集群时。在加入染群时广播一个加入消总,接收到的热备份撮合引擎选举出一个作为其响应节点,新加入集群的节点根据其收到的第一个订单序号首先到本地交易记录中检查是否可以衔接得上,如果出现断档则到响应节点上检查并获取断档区间的交易记录,如果发现响应节点依旧存在断档则可以采用阻塞机制等待响应节点继续运行直至断档区间的交易记录完全生成,此时将断档部分的数据附加至本地结果日志尾部,将运行状态转变为继续运行。通过这种无阻塞式进度追赶可以在不影响系统正常运行的情况下使新加入的撮合引擎追赶上正常运行的进度。

总结

系统测试及结果分析

测试模型设计

     每个金融产品业务区分配台撮合引擎,它负贵执行对当前金融产品的全部撮和工作,其模型架构如下图所示。

     为了保证系统的可靠性,在撮合过程中,撮和引擎需要多次同步的将订单或交场记录持久化到数据库屮。

该模型的订单撮和流程主要包括以下步骤:

     1) 用户生成委托订单并发送至网关

     2) 网关接收不同用户的请求,然后将订单派发给相应产品的撮合引擎

     3) 撮合引擎接受订单,将其同步存入数据库订单表中,然后根据内存中动态变化的买卖队列和指定撮合算法进行撮合

     4) 一旦撮合成功生成交易记录,将其同步持久化到数据库交易记录表中,随后将交易成功消息反馈给网关以及用户

 

     测试中采用的高可靠高性能撮合模型,通过在每个金融产品业务分区中采用多台撮合引擎组成集群。如下图所示,

     设计保证撮合引擎的输入一致,撮合业务逻辑也是一致的确定性算法,从而保证撮合结果的完全一致。服务器之间互为备份,每一时刻仅存在一个通过Paxos算法选举出的主撮合引擎,承担与数据库的交互任务。与此同时,交易记录并非直接同步写入数据库,而是通过先持久化至本地日志文件后采用异步方式持久化至数据库的方式。

     该模型的订单撮合流程主要包括以下步骤:

     1) 用户生成委托订单并发送至网关

     2) 网关接收不同用户的请求,然后将订单派发给相应产品的撮合引努.

     3) M关与撮合引繁通过原子多播确定订难发送顺序,使得同一个集群的所有撖合引擎所保存的订单顺序视图完全一致。接收到订单的撮合引擎按照相同的确定性算法进行撮合,生成交易记录并顺序序列化保存至本地日志文件。随后将交易成功消息回执反馈给网关与用户

    4) 撮合集群中的主撮合引擎上有一个独立进程根据远程数据库的线程持久化进程的请求从本地日志文件中读取相应条数的交易记录并批量存入远程数据库屮,从而完成了整个撮合及持久化过程。

 测试过程

原子多播测试

订单完全排序功能测试

     功能测试通过模拟网络延时导致订单传递乱序的场景,对三台抛合引擎接收到的订单队列进行验证,用于验证原子多播对多播保证撮合引擎复本中的订

单顺序完全一致的功能。如下图所示,网关A和网关B使用原子多播广播订单a和订单b给撮合引擎副本1和副本2,通过控制程序10可以实现撮合引擎副本1收到的订单顺序为订单a和订单b,同时撮合引擎副本2收到的订单顺序为订单b和订单a,本实验就是将经过原子多播排序过的订单队列进行对比验证,观察其是否会出现订单乱序。

延时测试

     通过部署一个原子多播订单发送服务器与两个接收服务器,当接收服务器将订单消息投递给应用程序后用socket通信告知订单发送服务器,并由订单服务器记录下记录订单的发送时间与确认时间,从而获得原子多播延时性能。

系统整体测试

     在一小时测试时间内,网关不断模拟用户生成订单并发送到三台撮合引擎构成的集群。集群中主节点与数据库进程交互,将撮合结果写入数据库中。

原子多播

订单排序

 

多播延时

     经过如测试过程中所描述的测试流程,原子多播的延时性能数据如下图所示,原子多播的延时稳定在460微秒级别,可以在保证可靠复制订单并多播的功能的站础上,提供非常高的实时性。

系统测试

     撮合系统的高性能主要涵盖两方面,可以在短时间内并发处理大量订单,尽可能降低每一笔订单完成的延时;

     撮合系统的可靠性是指当撮合系统的主要部件出现故障时,系统仍旧可以正常工作。

     因此系统测试主要针对系统吞吐率、系统延时测试来反映其性能水平,对系统故障恢复时的吞吐率进行测试来反映系统在出现故障时依旧可以进行正常撮合工作。

系统吞吐率

     由于订单和交易记录皆可作为衡量系统吞吐率的指标,但交易记录因为涉及到订单撮合成功与否的因素,除了单纯的系统吞吐率之外还引入了订单生成算法的因素,为了更直观的反映系统的吞吐率,测试中采用订单作为衡量吞吐率的主要指标。系统吞吐率指标主要反映了原子多播的高效的订单复制性能。

     由以上实验数据可见,撮合系统的订单撮合速度随网关数量的增加而增长,促增长速度快速放缓,当网关数达到三个时,系统订单撮合速度稳定在约2500笔每秒,基本达到测试环境下的撮合系统的性能瓶颈。

 

系统延时

     系统延时指的足从网关将订单发送至撮合引擎集群开始,到订单完成撮合并且交易记录被持久化到本地日志文件,系统将撮和成功信息反馈给网关的时

间。根据一般统计管理,通过将95%的订单处理延时集中在某个范围内进行衡量。系统延时指标主要反映了原子多播、无锁消息队列撮合流水线撮合与异步一致性持久化关键技术的整体性能提升

系统恢复能力测试

高可靠高性能撮合模型的一个新功能就是系统出现故障时可以快速响应并提供高可用的服务,主要反映了撮合系统失效备援关键技术的功能。系统恢复

能力流程为在三台撮合引擎的集群中通过手动模拟故障,顺序杀死两个撮合引擎进程,观察系统性能吞吐率数据。其中0到180秒为稳定运行阶段(第一阶

段),180秒时一台撮合引擎出现故障,180到240秒为第一次故障后恢复稳定运行阶段(第二阶段),240秒另一台撮合引擎出现故障,240到300秒为第二次故障后恢复稳定运行阶段(第三阶段)。

 

由以上实验数据可以看出,系统在180秒和240秒的时刻发生故障时,系统处理能力在故障时刻出现下降,但由于网关可以在配置的超时时间和超时次数之后将故障撮合引擎标记为失效,从而将其从原子多播集群成员视图中删除,保证系统继续工作。系统重新恢复工作后吞吐率升高的原因是因为在撮合引擎数量减少时会降低原子多播对订单定序过程的开销。在两次系统故障发生之后,高可靠高性能撮合模型可以快速检测和掩盖故障,从而保证系统的高可靠特性,满足金融交易业务需求。