优化银行预计算固定查询成实时灵活查询

简介: W银行指标查询系统用于计算和展示各类汇总指标,支持银行经营决策。因数据量庞大,系统采用预计算方式,但随着指标数量激增,预计算方式逐渐成为瓶颈。文章详细介绍了系统面临的挑战及优化方案,包括列式存储、有序归并、多线程计算等技术,最终实现了从明细数据实时计算指标的目标,显著提升了系统性能。

问题描述
W银行指标查询系统用来计算、展现各项汇总指标,是银行经营指标体系的重要支撑工具。由于明细数据量过大,指标查询系统一直采用预计算方式。但是,随着指标体系的不断发展,预计算方式无法满足指标数量急剧增长的需要,逐步成为制约经营指标体系的瓶颈。

预计算方式,是应对明细数据量巨大的无奈之举。W银行的客户有几千万,每天产生几千万条存款明细,几百万条贷款明细。这些明细数据保存在数据库中,业务人员提出指标计算需求,由软件工程师编写SQL语句完成计算。SQL很多很复杂,要计算的明细数据量又很大,如果白天提交给数据库计算,会造成数据库负担过重,甚至无法响应正常业务请求。因此,指标查询系统是把写好的SQL语句保存下来,每天晚上批量提交给数据库执行。执行的结果存入指标结果表,第二天上班的时候,业务人员就可以快速查询了。

d3b6d279e9454103c4199ab752601f75_1593414811373100.png

随着指标越来越多,预计算方式已经无法满足需要。以贷款余额为例,按照五级分类维度,会衍生出五个指标:“一级贷款余额、二级贷款余额…”。再加上四类担保,又会衍生出二十个指标:“一级、A类担保余额、一级B类担保余额…三级C类担保余额…”。再加上十种客户、四种放款方式,会衍生出800个指标。再加上币种、分支机构、日期、客户年龄段、学历等等,衍生出来的指标数量特别巨大。这还只是贷款,还要考虑存款、客户等等。如果这些指标都要预汇总的话,算出来的指标结果,根本无法全部保存!

21a200d241e4551f824d764f76f8ce70_1593414811867100.png

有没有什么办法能够直接从明细数据实时计算出需要的各种指标呢?

基于明细数据实时计算,面临的最大的难点是性能问题。指标计算涉及到大表关联、条件过滤、分组汇总、去重计数等多种混合运算。以“某日存款去重客户数”为例,客户表有两千万条记录,当日存款明细表有三千万条记录。两个表通过客户号关联之后,过滤选出符合两个固定条件,多个动态条件的记录,再按照客户号去重计数。固定条件是“多个分支机构和币种”,动态条件是存款类型、客户年龄段、性别、学历、产品等等。仅仅是这一个指标给数据库去算,就需要较长时间。

实际上,用户通过指标查询系统灵活定义的一个页面,就可能包含几十到几百个这样的指标,如下图:

28ca3264922cf7aed0b9b61d52d3a13d_05da2937117d4138b910f0de80226bb8_1.png

以图中下方的“近12个月变化趋势”这个“指标块”为例,每个月月末一天(加上当日)都要计算“逾期90天贷款、逾期贷款、不良贷款和非应计贷款”四种指标,每种都要计算余额、笔数、去重用户数三个指标,合计就是13×4×3=156个指标。上面的四个“指标块”也有4×2×4=32个指标,整个页面共有188个指标需要计算。考虑到多个用户并发查询这个页面的情况,十个用户查询就会有近两千个指标需要同时计算出来。

几千个指标同时由数据库去算,意味着对几千万条记录的大表要关联、过滤、去重、汇总计算几千次。数据库会不堪重负、业务人员要长时间等待查询结果,这是银行方面无法接受的。

W银行的服务器是主流配置的虚拟机, 64核CPU、256G内存、1T硬盘。单节点数据库显然无法满足几千个指标的同时计算。那么数据库集群是否可行呢?假设有20个用户并发访问,就要同时计算4000个指标,而且要秒级响应。如果每个数据库节点分担100个指标计算的话,总共也需要40台服务器。这样规模的集群仅仅为这么一个指标查询业务服务,建设和维护成本是W银行无法接受的。

分析解决
面对性能问题,需要仔细分析数据和计算的特征,定位性能关键点,通过改变数据的存储方式和计算方法逐步优化。

性能优化一,经过估算和验证,一天的数据装入内存就需要30G以上空间,所以全内存的方案不可行。要采用存贷款明细、客户等大表外存,机构、员工等小维表内存的存储方案。

以存款为例,数据有几十列,计算一个指标时,只用到其中几列。由于查询不会涉及全部列,考虑采用列式有序存储,如下图:

1fdddc60bfc9efcbd0a4d0652cb3e965_1593414806058100.png

采用列存可以避免整个文件的读取,只要读取需要的列即可。列存使得客户号字段的各个值相邻,有序又会有很多重复,有利于提高压缩比。高压缩比可以减少数据占用的磁盘大小,减少读取文件所用的时间。

性能优化二,客户和存款通过客户号关联,我们看作是主子关系,可以通过有序归并的方式提速,如下图:

0a3edb59a135a8d1137fd5ecb4fa41fd_1593414806249100.png

主子表都按照客户号有序存储,按顺序归并,一次遍历即可实现连接,复杂度M+N。而关系数据库是采用哈希法连接,复杂度SUM(Ni*Mi)。相比之下,有序归并性能要好很多。

有序归并也可以放在每天晚上跑批时完成,将客户数据冗余到明细数据中,生成归并好的数据文件。查询时省去有序归并的时间,性能更好。

性能优化三,存款和客户有序归并的结果,还是对客户号有序的,采用有序去重的方式快速计数,如下图:
b9e9454cedf5a698ba08377056953bb0_1593414806484100.png

对客户去重计数,只要比较相邻的客户号即可,一次遍历就可以完成计算。

性能优化四,一个机构会包括n个分支机构(营业网点),统计一个机构的指标需要对明细数据的机构代码做IN条件判断。如果用一般的方法,逐条记录做IN计算,n较大时,性能较差。我们要预先将n个分支机构计算为布尔维序列,如下图:

2b7670d01e1d030a13aa7a3928a6091a_1593414806674100.png

查询时分段遍历存款文件。第1条记录,用dept字段的值3,找到布尔维序列中第3个成员,值为true,因此第1条客户记录满足条件。如果值为false,则不满足条件。其他记录以此类推。

布尔维序列将值比较转换为序号引用,有效的减少了计算时间。IN计算时间和IN枚举值的多少n无关,不会随着枚举值的增加而增加。

性能优化五,由于服务器有多核CPU,我们用多线程计算单指标,如下图:
b386d28422e2818a33d29d12b73c9ff8_1593414806862100.png

用4个线程同时计算一个指标,速度会提高2-3倍。

性能优化六,币种、机构号等数据量不是很大,采用整形存储,比字符串方式存储量少,计算速度也更快。我们可以预先在内存中生成所有的小整数对象集,从0到65535,如下图:

d2e815dcc6edd47a205161362ee12d4a_1593414807328100.png

币种、机构号等都小于65536,从硬盘上读入的时候,不再对象化,而是引用内存中预先生成的小整数对象,可减少对象化的时间。同时也减少内存的占用。

性能优化七,去重客户数指标需要有客户号、明细号字段,余额和笔数指标则不需要这两个字段。而客户号和明细号太多是计算量巨大的主要原因。

我们采用部分预汇总的方式,预先将客户和存款表关联,用客户号、明细号之外的其他字段分组汇总,生成新的数据文件,用来统计余额和笔数指标。新文件比原明细文件小很多,计算速度也快很多。而且,还可以使用本文第四步到第九步的优化方法。

需要注意的是,新数据文件要增加一个笔数字段,记录预汇总的笔数之和。后续的笔数统计就不能用计数,而要用求和了。

性能优化八,统计全行指标时,需要统计所有营业网点的明细数据,也就是说,所有的明细数据都是满足机构条件的。所以,不需要再计算机构号的IN判断条件。在代码中加一个判断,如果是全行指标,就去掉机构号的过滤条件,可以减少大量的计算,提高性能。

性能优化九,应用服务器和数据计算服务器之间是通过网络通信的。用户界面上有几十到几百个指标需要计算,都需要建立网络连接调用。多用户并发时,大量的网络请求、连接就会成为瓶颈。

所以,我们将应用服务器以指标为单位建立连接,调整为以“指标块”为单位建立连接,如下图:
24bc58e315cdc5251c619ccb18624a0e_a1d8551bcda84a8d894869ca3ae59a26_2.png

可以看到,这个页面本来要建立188个连接。调整之后只需要建立5个连接了。应用服务器是多线程并行建立的5个连接,数据计算服务器在每个连接中又是多线程并行计算多个指标的,所以调整后整个页面的指标依然是并行计算的。

实际效果
根据计算特征拟定了优化方案后,需要选择一个合适的计算工具。通过上面的分析,关系数据库是不可行的,SQL过于粗线条,无法描述如此细致的优化算法。选择Java等常规高级语言没有问题,但需要编写大量代码,实现周期过长,容易出现代码错误隐患,也很难调试和维护。我们采用了开源的集算器SPL语言来实现,SPL提供有丰富底层算法支持,能让我们快速实现这种个性化的高性能计算。

经过几天时间的编程、调试和测试,直接从明细数据实时计算指标的效果非常好。单台服务器测试,以存款余额、笔数、去重客户数等为例,单指标计算时间100-200毫秒,包括前端页面的请求和统计图表展现。并发执行2000个指标只要3秒。如果需要支持更大的并发数,只需多机集群部署即可。集算器的集群能力很强,使用便捷,不用很复杂的配置就可以搭建起来,管理也很方便。

在编程难度方面,SPL做了大量封装,提供了丰富的函数,内置了上述优化方案需要的基本算法和存储方案。实际编写的代码很短,开发效率很高。比如单指标查询代码只有这么几行:

56cd171ac3155e22bdbeb3423f447770_1593414810764100.png

后记
解决性能优化难题,最重要的是设计出高性能的计算方案,有效降低计算复杂度,最终把速度提上去。因此,一方面要充分理解计算和数据的特征,另一方面也要熟知常见的高性能算法,才能因地制宜地设计出合理的优化方案。本次工作中用到的基本高性能算法,乾学院有各种详尽资料,有兴趣的同学可以参考。
很遗憾的是,当前业界主流大数据体系仍以关系数据库为基础,无论是传统的MPP还是HADOOP体系以及新的一些技术,都在努力将编程接口向SQL靠拢。兼容SQL确实能让用户更容易上手,但受制于理论限制的SQL却无法实现大多数高性能算法,眼睁睁地看着硬件资源被浪费,还没有办法改进。SQL不应是大数据计算的未来。
有了优化方案后,还要用好的程序语言来高效地实现这个算法。虽然常见的高级语言能够实现大多数优化算法,但代码过于冗长,开发效率过低,会严重影响程序的可维护性。开源的集算器SPL是个很好的选择,它有足够的算法底层支持,代码能做到很简洁,还提供了友好的可视化调试机制,能有效提高开发效率,以及降低维护成本。

正在为 SQL 性能优化头疼的同学们,可以来乾学院和我们一起探讨!

相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps 
相关文章
|
1月前
|
消息中间件 存储 缓存
十万订单每秒热点数据架构优化实践深度解析
【11月更文挑战第20天】随着互联网技术的飞速发展,电子商务平台在高峰时段需要处理海量订单,这对系统的性能、稳定性和扩展性提出了极高的要求。尤其是在“双十一”、“618”等大型促销活动中,每秒需要处理数万甚至数十万笔订单,这对系统的热点数据处理能力构成了严峻挑战。本文将深入探讨如何优化架构以应对每秒十万订单级别的热点数据处理,从历史背景、功能点、业务场景、底层原理以及使用Java模拟示例等多个维度进行剖析。
54 8
|
4月前
|
存储 算法 大数据
指标类需求问题之在商品开发和运营过程中,减少指标计算以节省人效要怎么操作
指标类需求问题之在商品开发和运营过程中,减少指标计算以节省人效要怎么操作
|
3月前
|
存储 JSON 物联网
查询性能提升 10 倍、存储空间节省 65%,Apache Doris 半结构化数据分析方案及典型场景
本文我们将聚焦企业最普遍使用的 JSON 数据,分别介绍业界传统方案以及 Apache Doris 半结构化数据存储分析的三种方案,并通过图表直观展示这些方案的优势与不足。同时,结合具体应用场景,分享不同需求场景下的使用方式,帮助用户快速选择最合适的 JSON 数据存储及分析方案。
查询性能提升 10 倍、存储空间节省 65%,Apache Doris 半结构化数据分析方案及典型场景
|
2月前
|
SQL 缓存 分布式计算
C#如何处理上亿级数据的查询效率
C#如何处理上亿级数据的查询效率
40 1
|
4月前
|
存储 监控 Serverless
函数计算发布功能问题之用户在使用主流函数计算产品的日志服务时可能会遇到使用成本的问题如何解决
函数计算发布功能问题之用户在使用主流函数计算产品的日志服务时可能会遇到使用成本的问题如何解决
|
5月前
|
SQL 分布式计算 DataWorks
享受成本分析自由,体验账单数据订阅及查询分析功能
使用DataWorks进行账单数据订阅和查询分析,您可以有效地管理和可视化您的阿里云消费数据。本指南提供了详细步骤和示例,帮助您快速入门实现账单数据的高效分析。
719 8
享受成本分析自由,体验账单数据订阅及查询分析功能
|
4月前
|
SQL 缓存 数据挖掘
数据平台问题之复合指标生成中维度能力如何处理
数据平台问题之复合指标生成中维度能力如何处理
|
7月前
|
算法
深度解析:用户增长插件的计费规则与使用技巧
深度解析:用户增长插件的计费规则与使用技巧 随着互联网的快速发展,用户增长成为了各类企业面临的重要问题。如何高效地获取并圈选目标用户,提升用户活跃度,成为了企业运营的核心竞争力。盛通教育的用户增长插件,内置高性能营销场景化算法,可以根据企业的运营目标,智能圈选海量用户,并通过智能短信的方式触达目标用户。那么,这款插件的计费规则又是怎样的呢?
57 1
|
vr&ar 开发工具 图形学
Unity引擎更新收费模式:从收入分成转向游戏安装量,将会有哪些影响呢
Unity引擎更新收费模式:从收入分成转向游戏安装量,将会有哪些影响呢
下一篇
DataWorks