【删除】撮合引擎二 无状态【yet】
https://mp.weixin.qq.com/s/kmuG5azJnqjKRYlkiVHWqQ?poc_token=HA31umijtk8JqRdMNKY-tN-3a0ir5a2ktLoCjscv
正因为应用是有状态的,所以需要通过Disruptor提升单机的性能和吞吐量。
为什么撮合应用不设计成无状态的?
在学习或者实际做架构设计时,一般大多数情况都建议将应用设计为无状态的,可以通过水平扩展,实现应用的高可用、高性能。而有状态的应用一般有单点故障问题,难以通过水平扩展提升应用的性能,但是做架构设计的时候,还是需要从实际的场景出发,而撮合应用场景很显然更适合设计成有状态的。在数字加密货币交易平台,每一种数字加密货币都是由唯一的“交易对”去标识的,类似股票交易中的股票代码,针对不同交易对的买卖交易单是天然隔离的,而同种交易对的买卖交易单必须是在同一个应用去处理的,否则匹配撮合的时候是有问题的。如果使用无状态的设计,那么所有的交易对都必须在一个集群内处理,而且每个应用都必须要有全量交易对的订单数据,这样就会存在两个问题:多个应用撮合匹配结果不一致,以哪个为准、热点交易对如何做隔离,所以解决方案就是根据交易对维度对订单做分片,同一个交易对的订单消息路由到同一个撮合应用进行处理,这样其实就是将撮合应用设计成有状态的。每一种交易对每个时刻有且只有一个应用能处理,然后再通过k8s的Liveness和Readiness探针做自动故障转移和恢复来解决单点故障的问题,最后通过本地缓存Caffeine+高性能队列Disruptor提升单pod的吞吐量。16C64G的配置在实际业务场景压测的结果是,单机最大TPS在200w/s左右,对于整个交易系统而言性能瓶颈已经不在撮合应用,因为极端情况下可以配置成一个pod处理一个交易对。
https://juejin.cn/post/7477871457738375218工作十年,谈谈我的100W QPS高可用架构和系统设计经验
为什么要无状态?
1 高可用
2 可伸缩
3 高性能
无状态的撮合引擎难点:
假设把状态外移到redis跳表
| 节点1 | 节点2 |
| remove 买1卖1 | |
| 部分成交 | remove 买2卖2 |
| add | |
| remove买1卖1,这个剩下的买1应该早于隔壁节点2的买2撮合 |
假如要设计代码无状态随时可扩容
| 节点1 | 节点2 |
| remove 买1卖1,锁节点2的访问,分布式锁 | |
| 部分成交 | remove 被锁 |
| add,释放锁 | |
| 取得锁 remove 买1卖1 |
代码是无状态了,可以解决高可用,但是锁的介入给性能带来毁灭性的影响,比如CPU缓存,网络io开销
不无状态(不用锁)有没有别的方式可以搞定?
1 高可用
可以主备架构不一定要并行,但心跳要设计好,未必能依靠k8s探针
2 可伸缩
对合约hash分片也可以
3 高性能
hash分片
节点内优化,gc,数据结构,等
现在回过头看下什么叫无状态
节点1在接流量,这时如果切到节点2,最终数据保持一致,就是无状态
浙公网安备 33010602011771号