资产中心重构分享

it2023-06-24  68

资产中心重构分享

     第一章 资产中心简介

第一节 资产中心的定位

资产中心目前提供的数据是和收益成本相关的指标,并不提供实时的资产和份额数据;

如果按照目前的功能命名,收益中心更合适;

只不过命名要具有前瞻性,要看到未来的事情。如果还不能说服你,你就问一问自己鱼香肉丝它有鱼吗?

对于一个投资者来说,比较关心的数据:收益,所以资产中心的访问比较频繁;

第二节 资产中心处理流程简介

如何计算收益?

计算基金的收益需要的数据:成本、份额、分红、市值;

成本、份额、分红如何获取?

通过交易记录中获取这些数据;

市值如何获取?

有了每天的基金的份额,有了最新净值就可以算出市值;

资产中心计算收益流程(缩减)

 

每天17点左右,会处理当天确认的交易记录,根据交易记录计算出成本、份额、分红等数据;

(通常会往前多算几天,如果前几天交易记录有变化)

当天交易记录处理完成,才会进行净值更新的处理;

净值和外部的对接方式选择?

dblink 肯定是不行,文件实时性堪忧,并且净值变化比较频繁,当天净值会有更新、删除操作;

净值更新要具有实时性:选择mq实时接收和处理净值;

交易记录和外部的对接方式选择:

交易记录所在的系统:后台(中台),oracle库,表结构和业务都有可能变化;

收益份额清算:清算收益份额,需要有参照物清算;

同步:清算通过后的数据,同步到表中,展示给用户;

总结:要计算收益,基本的模块:交易记录处理,净值更新处理,清算同步模块;

     第二章 资产中心重构

为何要进行资产中心的重构,有一些不得不解决的痛点,不是闲的没事,是势在必行,不重构不行了;

第一节 老资产中心的痛点

痛点一:外部业务依赖严重

资产中心和外部系统的对接方式,数据的获取大部分是通过dblink方式获取;情况如图:

过多的通过dblink这种方式获取数据,无论是对系统本身,还是对外部系统都是极其不稳定的因素;对于数据库的管理也是一个难题;外部被依赖的系统如果更改数据库表结构或逻辑,不一定能考虑到依赖方的需求,更改结构还好,会报错发现,最不好处理的是改了表之前的业务,导致之前处理数据的逻辑不对;

通过dblink从外部的表中获取数据,对外部的业务依赖较多,对接成本大,需要了解外部业务;如果外部业务表发生变化,相应的可能需要调整;业务耦合很大;

老的资产中心交易记录跑批,依赖后台的日终完成,如果后台当天有人工干预,当天的日终就会延迟,历史上只要后台日终推迟,收益跑批就会延迟,对用户体验不好;

痛点二:过多的使用存储过程

大量的复杂业务逻辑处理,通过存储过程实现,不易维护;开发调试成本高;不能应用缓存,或处理缓存;

最致命的一个缺点是,不支持集群,数据库服务器无法水平扩展,数据库水平、垂直切割也复杂;

因为老的资产中心,数据库使用的是oracle,数据库的性能较高,对存储过程的支持还是不错。而新的资产中心数据库使用的是mysql,数据库服务器本身的性能不如之前,如果使用存储过程,性能会很差;

痛点三:无法全量跑批

虽然除了第一次跑批,需要全量跑批,不是每天都需要全量跑批,但是系统不能不支持,实际上,前期灰度阶段,对全量跑批的需求还是比较旺盛,如果系统不支持全量跑批或者很慢,全量跑一次要两三天,对于灰度的时间会延迟不少;要想解决一个问题,必须要分析产生的原因;新资产中心,前期灰度期间,其实全量跑批也是不顺利,跑批一次需要一两天时间,并且有时会卡住,中途失败,又要重新跑,现在看下来就是没有提前想好之前为何不能全量跑批的原因;

老的系统全量跑批一次,需要处理的交易记录大概在3,4千万,通过dblink从外部数据获取数据,然后通过存储过程处理;通过这个描述,已经看出来一些问题:数据量巨大,通过dblink获取无论是性能还是稳定性都会是个问题,而通过存储过程处理交易记录,无法水平扩展,不支持集群;正是这些阻碍导致了全量跑批的失败;

下图是老资产中心交易记录处理的流程图,方便大家理解。

痛点四:数据库压力较大

处理交易记录,份额、收益清算及同步,都是通过数据库进行处理,并且跑批集中的18点之后,造成了数据库压力过大,历史上就有过几次,因为数据库压力过大,导致数据迟迟不能同步成功,造成的现象就是收益更新缓慢;

第二节 如何干掉这些痛点

干掉痛点一:干掉对外部业务的强依赖

这里说的干掉外部依赖,不是说不需要外部,而是解耦和外部业务形成强绑定;举个例子:外部进行了一次业务升级,资产中心获取的数据不受影响;

新资产中心,通过对接文件获取所需的数据,通过统一的文件处理模块;这样资产中心只关心自己所需的数据,并不需要了解外部系统的数据库表结构这些东西,外部进行了业务的调整,只要双方之前约定的对接文件,就不会受到影响,解耦了对外部系统的业务强依赖,系统稳定性,扩展性大大提高;

不过大家也要看到,可以这样做,是需要依赖的外部系统的支持,双方约定好提供的数据及文件的格式等;这些都是要和外部方商定好的事项;

干掉痛点二:干掉存储过程

数据库使用mysql,进行了分库,对于之前存储过程处理的部分,改成通过程序方式进行处理;采用分布式计算框架,支持集群,系统的性能和扩展性大大提升;

干掉痛点三:支持全量跑批

通过上面两点的改造,系统减轻了数据库的压力,支持集群,采用分布式计算框架,最终达到了一个一致性的状态;灰度阶段支持了每天一次的全量跑批,耗时在10h左右;并且可以通过增加集群中机器数量,提高计算速度来满足日益增长的数据;

注意点:

1.每个主要模块要采用分布式计算框架,这样可以控制计算单元范围,方便处理,后续对于日益增长的数量,可以通过水平扩展集群规模提升计算速度;

2.要保证系统的最终一致性:CAP原则,选择了AP,和最终一致性;

干掉痛点四:缓解数据库压力

去掉之前使用存储过程进行处理的部分,数据库不做计算,只是作为存储介质;前端接口部分采用缓存+DB结构,减轻查询的压力;数据库设计成分库模式,并且随着日益增长的数据量,可以继续水平扩展;程序的设计流程上,也尽可能的减轻数据库的瓶颈,尽量提前批量查询好数据,然后再做业务处理,最后批量的做更新或插入操作;需要注意的是,对于mysql来说,有的时候批量更新的性能,可能不如先查询再更新;

其他方面的改善:

1.系统的可扩展性大大提高:

业务上:底层的计算指标标准化,是最不可分割单位,方便快速业务拼接;

系统上:方便快速接入新产品:标准化的对接文件模块,定制接入产品的内容读取格式即可;数据库和服务器都支持水平扩展,主要的处理模块都采用分布式计算框架;

2.解决了缓存key较多,不易维护的难题:

老的系统,缓存结构的设计,没有提前规划好,导致缓存key较多,跑批的时候管理起来复杂,容易遗漏,并且前端查询接口新增缓存key的时候,后端跑批管理缓存key的部分就要做相应的更改,耦合性较高;

新的资产中心缓存采用redis的hash结构存储数据,跑批时批量删除缓存key;这样前端新增缓存的时候,后端不需要做相应的更改,方便,简单,前后端耦合较低;缓存的数据结构如下图所示:

3.解决了单产品的累积收益曲线,需要提前预热存储or实时计算对系统的压力:

累积收益曲线,跑批时存储在ES中;前端使用的时候,直接从ES中查询,不需要预热存储到关系型数据库or实时计算,减轻了系统的压力和存储成本;

第三节:设计经验分享

1.重构系统神器:数据对比

对于重构系统来说,是存在两套新老系统,同样的业务情况下,业务的调整有限,在这种情况下,对新老系统做数据对比,就可以有效的发现问题,提高系统的质量;特别对于业务场景复杂的系统,在有限的测试资源情况下,通过新老系统数据之间的对比,大大提升了发现问题的速度;

一般数据对比的时候,最好设计一个可以容忍的误差范围,这样做是因为新老系统之间虽然只是一个进位规则的调整,都有可能带来一个误差,更不要说整个系统的重构,必然会造成一定的误差,设定一个误差范围,很有必要;

通过数据对比,对于重构系统的质量、可以上线的时间表,都提供了一个量化的指标,做决策的时候,提前就知道了影响的范围,当前重构系统可能影响的用户范围,可以具体到每个用户,也方便客服提前准备;

回顾整个重构的时间点,在灰度阶段花费的时间比较久,从4-20号进行灰度一直到7-20号左右才全部正式对外。

灰度阶段,通过对比,发现了问题主要有两类:

1.程序处理上有问题;

2.交易记录数据问题;

对于第一类问题,通过修改程序算法,可以一次解决一批数据;造成这个问题主要是因为:测试阶段场景不充分,造的数据不全;数据不对,没有对比也没发现问题;算法程序处理上的bug;通过数据对比,可以方便定位到问题数据,进行分析;

对于第二类问题,只能通过修改数据修正。造成第二类问题的主要原因:老新系统取数据的数据源不同,老资产中心取的是后台确认的交易记录,新资产中心取的是中台的交易记录;历史遗留问题比较多,当时定的策略是第一次初始化数据从中台取数据,如果发现有问题,人工修复;现在回头看,还是这样做还是比较耗时的;时间花费较多的地方是在处理交易记录,人工修复起来比较慢,批量修复的时候又会引发别的问题;

回头来看:

开发和测试时间被压缩,导致出现第一类问题,开发耗时在两个月左右,大概的时间段是2020-1月至2020-2月,夹杂春节和疫情的影响;测试时间也比较仓促,大概在一个月左右,再加上资产中心场景复杂;现在看来,可以在第二类问题上缩短时间,后面我也验证过,从后台获取问题用户的初始化数据,大大减少了交易记录的数据问题;在设计阶段耗时也比较久,但是产出不大,后面很多模块的设计,都被修改的面目全非,当初花费时间和精力设计都浪费了;

2.灰度模块:重大上线必备的功能

对于一个产线的系统,每次重大上线,是需要一个灰度的模块来控制影响范围;通过逐步的放开灰度范围,观察用户的反馈情况,降低对用户的影响,降低风险;

需要注意的一点就是,最好设计一个开关,这样可以一键切灰度,而不用手动添加灰度用户,不可能一个系统没有新的用户进来;

 

3.监控:产线重要系统都需要有一套完整的监控

配置监控,提前发现问题;提示每天关键节点的跑批进度,降低人工运维成本;监控的方式灵活,可以采用ELK,数据库层面也可以配置监控sql;

4.灾备恢复:提前规划好,如果出现问题,怎么快速让系统恢复

首先:系统设计上要支持重跑;主要的模块,都要支持重跑,重跑参数配置化,并提供触发入口;其次:备份系统的前一个一致状态,需要的数据,表结构维护;最后备份的数据也要做到定期删除;有条件最好上线之前演练一次,提前验证一下是否支持恢复,避免真的需要恢复的时候慌乱;

第四节:数据情况简单统计

主要简单介绍一下,新资产中心的数据情况,方便大家对系统的规模有个简单的了解

1.对接外部文件的情况

可以看到份额对账文件,每天的数据量是比较大的,采用mysql存储,mysql数据库服务器的配置只是一般的配置,前期灰度阶段也是出现比较多的问题,导致文件导入异常缓慢,问题不断,后面也是进行了重构,去掉了需要数据库层面进行的计算,全部改用程序,分批次处理,数据库只是作为最终的存储介质,不进行任何的操作;不断的重试导入失败文件,最终达到一致;

2.ES累积收益数据:单基金

 

3.ES累积收益数据:组合

4.交易记录处理部分耗时情况统计:

交易记录处理部分,灰度阶段也是发现问题较多,导致跑批缓慢,后面也是把需要数据库层面进行的更新操作,全部改用程序处理,改单机架构为分布式计算框架,分单位分批计算,最终达到一致状态的方法进行了重构;

可以看到新资产中心基本上在18点就已经进行完交易记录的处理,而老的资产中心可能还没开始,因为老的资产中心需要后台日终,确认的交易记录不再变化才会开始进行处理;历史上经常因为后台日终较晚,导致收益迟迟不更新;实际上当天确认的交易记录,如果走中台文件对接,并不需要依赖后台是否日终;

5.净值更新耗时情况统计:

 

可以看到98%左右的净值更新收益计算在一分钟以内完成,并且采用分布式计算模块,支持系统水平扩展,完全可以支持日益增长的用户量;净值更新收益这块,并发比较高,高峰时间段,一分钟要计算的用户都在6位数,分布式计算框架和程序流程上的设计,支持高并发,快速的更新收益;

第三章 未来规划

1.继续接入高端、储蓄罐、定期保险等的收益;

2.更简单方便的支持数据库水平扩展,减轻现有系统的负担;(比如采用路由表等)

3.接入了所有资产的收益后,用户总累积收益曲线做到实时更新,使用ES存储,提高查询性能和降低存储成本;

4.满足份额资产的实时性需求的探讨;

5.历史交易记录的修复

 

总结

 

附件:

系统业务架构图

系统架构图

 

数据库架构

 

作者简介:

张星,华东理工大学毕业,本硕,计算机专业,曾就职于大智慧、东方财富;

参与过大智慧财经资讯、云操盘等项目开发;东方财富choice金融数据终端,东方财富证券线上开户,东方财富数据行情数据风险监控等项目开发;

有丰富的金融系统和高并发开发经验;

 

最新回复(0)