行情丢失导致无法撮合成交【重点】

还是来看这张图:

由于此前redis分布式锁超时事故,所以中间那个线程池设置为有界队列,并配置了放弃策略,故当disruptor消费者不给力时,经阻塞模式的disruptor逆推到生产者阻塞,导致堆积的线程超出队列上限被放弃

那为什么消费者会不给力?

在消费者中,消费频率大约是一个合约每秒4次,在250毫秒中,对同一个合约的多空两个方向各进行一次rangebyscore redis io(撮合、止盈止损使用redis zset触发股票成交) ,又由于是多消费者:(多行情消费者(多线程)两次并发事故)需要(io密集型,10个消费线程,redis在10连接下达到最大性能80%——redis 压力测试与pqs监控中的结论)

如果单引擎,则可使用ConcurrentHashMap.putifabsent(合约+人id+多/空)来加锁避免并发重复成交

但考虑可用性,部署多个进程,则要使用redis putifabsent来防治集群下的重复成交

这2个操作可同步在消费者中处理的,也可异步

同步:一个合约250ms内2次rangebyscore redis io + 2次putifabsent io

异步:一个合约250ms内2次rangebyscore redis io 

后决定异步到MQ,由消费者单点成交,排重

Jedis 压力测试与qps监控,认定redis rangebyscore为4.8w qps

               250ms io/合约            1s io/合约(redis qps)         

TD 总共3个合约

异步               2                                  8                    24          

 A股总共3000个合约

异步               1                                  4        12000                           只能做多

美股7679 

异步       2           8         62000

港股1800

异步       2             8         15000  

期货20个合约

异步       2             8         160

需要共9w qps

远超过redis 4.7w qps,考虑redis分四片,对合约hash取模

原文地址:https://www.cnblogs.com/silyvin/p/11738130.html