1. 数据存储层
我们介绍过,金融交易系统具有海量数据的特点,但是也并发每种类型的数据都是海量的,而且不同数据对于数据的延时要求不同,即使对于同一种类型的数据,由于使用场景的不同,也会对数据的延时性要求有很大的差异。
基于上述的特点,造成了金融数据的存储方式也存在很对的差别(待完善)。
数据名称 | 使用场景 | 延时要求 | 数据量 | 存储方式 |
---|---|---|---|---|
3年内行情 | 亚秒 | 70亿条/15T | Ignite | |
3年内行情 | 曲线拟合 | 秒级 | 50亿条/8T | Cassandra |
3年内行情 | 策略验证/回测 | 分钟级 | 50亿条/8T | Cassandra |
3年外行情 | 存档 | -- | 千亿条 | Hive |
报价 | 做市报价 | 亚秒 | 亿条/3T | Ignite |
监控数据 | 监控大屏 | 分钟级 | Hive | |
风控数据 | 风控数据展示 | 秒级 | Hive/Mysql | |
利率曲线 | 亚秒 | Ignite | ||
收益率曲线 | 亚秒 | Ignite | ||
市场参考数据 | 亚秒 | Ignite | ||
市场交易数据 | < 3ms | Ignite | ||
权限数据 | < 1ms | 本地缓存:caffine |
从上表可以看到,由于数据访问时的延时要求不同,数据量的不同,消息体大小的不同,我们需要分类采用不同的存储方案。
2. 哪些场景需要缓存
对于需要亚秒级响应的数据需要进行缓存。
另外,交易系统之外的应用如果需要访问,则需要提供网关服务。外部应用主要的请求行情数据和交易数据,例如请求交易数据来完成清算工作。
外部服务请求的数据比较集中,如果让外部请求直接穿透,会造成交易系统的负载过高,因此,会将请求的结果进行缓存,避免请求频繁到达交易系统的应用。
3. 缓存中间件选型
redis是业界比较常用的缓存中间件,单节点吞吐量能达到3-4万/s,延时在100-200us左右。而且,搭建集群环境后,可以通过横向扩展来提高吞吐量,并提高数据的存储能力,具有高扩展性。但是,基于key-value模式的redis,有很多场景无法满足。
3.1 BigKey问题
由于 redis 只使用单核,所以平均每一个核上 redis 在存储小数据时具有优势。而在 100k 以上的数据中,redis的性能会严重受损。但是,金融交易系统中,大消息体的消息普遍存在,例如,excel报价数据,一个消息体的大小就在3-5M。
3.2 消息过滤问题
redis是基于key-value模式的缓存,只能通过key来进行消息的查询,无法建立索引来进行更精细的过滤查询。
以行情为例,根据交易所,产品分类,产品子类,行情来源等字段进行联合筛选的情况普遍存在。有人会说,那么将这些字段按一定的规则生成一个key来进行消息的缓存不久解决了吗?这一方面会导致key的字段过长,而且会导致查询过滤的组合严重受限,不利于扩展。
3.3 多级缓存问题
redis没有本地缓存的概念,如果需要配合本地缓存来实现多级缓存,那么必须选择另一种本地缓存的缓存框架,导致架构体系变得复杂。
3.4 数据丢失问题
redis是无法保证数据完全不丢失的。在交易系统中,有些场景严格限制延时性,比如涉及交易的行情数据要求延时在3ms以下,而行情数据的处理过程中涉及填充市场参考数据,如果参考数据在缓存中没有,就需要穿透到数据库进行查询,延时性就很可能达不到了。为了保证行情数据的延时性能达标,必须保证市场参考数据在缓存中不过期,不丢失。
3.5 字段读写问题
redis对于value是作为一个整体进行操作的,value不能在细化处理了。在交易系统中,很多缓存对象非常大,字段数有时候达到成千多万,如果每次都全量读取,或者全量替换,会造成网络和CPU(序列化/反序列化)的瓶颈。
基于上述原因,我们并没有采用redis来作为缓存框架,而是采用了ignite来作为缓存中间件。
对比项 | Redis | Ignite |
---|---|---|
吞吐量 | 3-4w | 3-4w |
延时 | 100-200us | 100-200us |
支持建立索引,按索引进行过滤查询 | N | Y |
多线程处理 | N | Y |
支持near cache | N | Y |
数据丢失 | Y | N |
按字段读写 | N | Y |
GC(存在一定的性能风险) | N | Y |
4. 缓存面临的问题及解决方案
4.1 高性能
(1)极高性能要求的数据不使用分布式缓存
如权限数据,直接使用本地缓存。
(2)预加载
对于交易时间段会使用到的数据进行预加载,并且对于热点数据不设置过期时间。比如市场参考数据,它的变更频率非常低,有的甚至几年都不会变动,我们只需要在每天的非交易时间段预先加载好即可。
(3)冷热分离
针对交易频繁的产品(如债券)和交易不频繁的产品(如黄金)分不同的缓存topic,设置不同的缓存参数,来达到最高的性能。
数据一致性
HotKey
BigKey
缓存穿透
缓存击穿
缓存雪崩
多级缓存
1.4 HotKey和BigKey问题严重
对于热点交易品种,容易造成HotKey问题;权限也跟着容易照成HotKey问题。聚合行情,报价数据容易造成BigKey问题。
- 高性能,高并发解决方案
5.3 按需存储到不同数据存储组件
冗余