分布式与负载平衡

分布式与负载平衡

我们现在已经对由一系列独立的组件构成的高频交易系统有了一个大致的印象,在这个系统中,每个组件都有其独特的功能并且能够运作良好:其中的一个组件会监听并重新发布市场数据,另一个组件则会在市场数据中寻找alpha (也就是能带来盈利的交易信号) ,还有一个组件负责下单交易,诸如此类。整个系统就是这样被组件化,或者用软件工程的语言来说被分布化了。你会把一项庞大的任务交给10个组件还是20 个组件去完成?这个问题的答案是:模块化的程度不能太低,以致某些模块因为太过庞大而效率低下;同时也不能过高,以致由于模块间的通信压力太大而降低了整个系统通讯机制的效率。接下来会具体地说说这个问题。

我们已经提到的这种任务分配的概念是功能性的(例如,将一项大的任务分解为一系列更小的任务)。另一个与高频交易系统的设计相关的分配问题是,当有一系列相同类型的工作需要完成时,如何在系统的各个组件之间平衡地分配计算量。举个例子: 当需要计算你的资产组合中的每一只股票的价格的时候,你很可能会决定开发一个组件,这个组件除了读取每只股票的各种参数,用一些复杂的数学计算把这些参数转换成股票价格并输出之外,别的什么也不干。但是,如果你有3000 只股票的价格需要计算,你就得好好考虑一下需要一次实例化多少个并行工作的组件对象了。很显然, 仅仅一个组件对象是远远不够的,因为这会导致一长串的任务队列等待处理,你决不会希望看到这种情况出现。当然,你也不需要3 000 个组件对象,如果这么做,它们在大多数时间都会处于闲置状态, 而实例化这么多对象所占用大量的CPU 和内存资源会大大降低你的系统效率。你需要做几次试验,然后确定一个合适的实例化组件的数目。

除了计算任务的分配,机器资源的分配也提出了另一个任务分配与平衡的难题。每一台服务器所能处理的任务量是有限的( 对内存和处理器来说也是如此),如果任务量超过限度,它们就会停滞下来而无法工作。一旦你决定了模块化功能组件的方式以及每个组件对象需要的实例数目,最后的任务就是分配这些服务器上的处理器资源了。同样,通过计划和试验,你可以得到一个合适的分配结果。

这个游戏最后看起来很像是在比赛开一家快餐店。对于一次交易,有一张委托单需要处理,这个过程就像圆面包等着用肉饼和其他的配料填满,薯条等着油炸、包装,饮料等着装进可乐杯,配料等着从仓库里面取出来一样。一个员工显然不足以应付所有这些事情,但是你显然也没必要为每一项任务都分配一个员工专门负责,这些都属于功能性的分配。接下来你还得确定需要的收银机和炸薯条的油锅之类的设备的数目,这些就属于负荷分配的范畴了。最后你还需要确定在快餐店里设几条食品流水线,如果只有一条流水线,你的店里显然会排起长队,人们也不愿意等那么久;但是如果流水线太多,它们的固定成本会太高,大多数时候却是闲置着的,这会让你因为承担了太高的成本而不得不向顾客提价,很多不愿意付更多钱的顾客就会被挤走。