性能优化就像挤出海绵中的水,能挤出多少,主要取决于海绵中的水分有多少

e4e0d380a0176e5459de17aa9a55f3a1.jpeg

@图片:2022年9月拍摄于北京中关村 @摄影师:刘先生

01

背景介绍

有这样一种业务场景,业务计算完成之后,会产生上百万的数据,而这百万级的数据如何入库保存,成了让人头疼的问题。

数据库是MySql,由于数据库超时时间限制和单次提交的数据量的限制,百万级数据不可能一次性入库,于是采用分批提交的方式,尽管数据能够成功入库保存,但时间慢的有些让人难以接受。本地开发主机由于程序和数据库在同一台电脑,硬盘是固态硬盘,保存耗时30秒,服务器由于网络及硬盘速度的影响,百万数据保存耗时在2分钟左右。

下面分享一下在不改变硬件及现有基础技术框架的前提下,仅靠修改代码逻辑,如何将百万数据保存耗时降到0.6秒,速度提升50倍,内存减少50%。

02


处理逻辑

第一步:合并数据

这个问题的本质是:数据量大,而优化的首个出发点是,如何减少数据量。按照这个思路,将数据按照数据主体进行汇总合并,多条数据合并成一条,以JSON形式,存储在一个字段中,减少入库数据量,最终,数据条数降低了100倍,现在需要处理的就是万级数据的入库问题,问题难度一下子降低了。

如下图所示,进行数据合并之后,BenchmarkDotNet测试结果,平均耗时从27.6秒降到4.6秒。

e12d6360db989301431c5aa380d2fe72.png

第二步:压缩数据,减少数据大小

经过上一步数据合并之后,数据的数量减少了,但数据空间大小并没有改善,这百万数据占用空间在100M左右,这一步从减小数据空间的角度,采用GZip压缩JSON数据,减少网络传输,及数据磁盘写入压力。

从下图的测试结果看,执行效率略有提升,重要的是数据大小从100M减低到30M,减少70%空间占用。

50723b4871f73e6d3a0ac85dbc9834fd.png

第三步:自定义序列化

JSON格式是最常用的一种序列化格式,但是否是最好的,考虑到具体的业务场景,是否可以用一种更简单的序列化格式进行取代呢,在这一步中,便进行了一次尝试,由于数据都是key-value形式,而value都是值类型,自定义序列化也变得非常简单。

JSON序列化后的数据

1ca66408bf7fa4abf8268c3a4e475b80.png

自定义序列化的数据

4a7e02266a2f650c272f19d4dce8d536.png

采用自定义序列化比采用JSON序列化,数据空间减少17%,尽管处理速度并没有明显提升,但内存耗用降低了50%。如下图所示

6d0af376d0b4043350b3f0a3f2726ee8.png

第四步:优化反射性能

上一步自定义序列化的过程中使用到了反射,由于数据量大,反射的性能问题被放大,这一步采用委托优化反射性能。

相较于上一步,速度提升近1倍,但内存耗用也增加了1倍,如下图

bd7468bcc49e5ecb6a1ab5960ad651ac.png

第五步:多线程并行处理

经过以上几步,执行速度降到了2秒,但这个速度我依然不够满意,于是祭出性能优化的终极杀器:多线程处理。有关多线程编程可以参考我之前的文章。

至此:处理速度为0.59秒,性能提升近50倍(49.23倍)内存占用减少50%。

e961a02f6d593cfa4b580905958240a0.png

用一张MySql数据库仪表盘的截图,直观展示两段逻辑执行时的性能差异:

0409c0ae6d00ae5d63dc12979a5986dd.jpeg

03


思路总结

1.减少数据数量:合并数据项

2.减小数据空间:GZip压缩

3.优化反射性能:创建属性访问委托,提升属性读写速度

4.多任务并行:信号量控制并发数量,加锁控制临界资源访问,留意多线程下异常处理,任务取消

04


再啰嗦几句

起初优化的目标是性能提升100倍,显然有点高了,最终提升了50倍,当然目前还有一定优化空间,比如:有些小伙伴可能已经看到了,计算结果数据大部分的是0,这些为0的数据,其实是不需要保存的,这样即可以进一步减小数据量。

另外考虑到数据增量,每次有几百万数据入库,一年产生的数据将近5亿,这样大的数据量,在MySql中处理压力是很明显的,因此,引入分布式数据库才是长久的解决办法。

-

技术群:添加小编微信并备注进群

小编微信:mm1552923   

公众号:dotNet编程大全    

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐