问题背景: 在帆软报表的使用中,我们发现报表平台在满足用户大量明细数据导出的需求时存在性能瓶颈,尤其是在处理一些特殊导出需求(如:业务数据不可分批导出且数据的时间跨度以年为单位,总数据量高达40W+条)时常常出现内存不足问题。换言之,这类需求的存在变成了报表平台的隐患,为此我们也曾饱受折磨。
解决思路: 经过分析,我们发现报表在执行大量明细数据查询时,花费大量资源来渲染表格,而对用户来说,他们只需要导出数据,而不需要查看表格。也就是说,如果能够跳过表格渲染,直接让用户获得Excel文件,则不仅能够加快用户获取数据的效率,同时也能大大减轻报表平台的压力。
为此,我们前后设计了3套方案:
方案一:利用报表平台的定时任务,后台导出Excel并通过邮件的方式发送给用户。这样可以避免用户在报表使用的高峰期将服务器拖垮。 在数据量不太大的情况下,这种方案是奏效的,但是一旦数据量过大,则会面临两个问题:①服务器空闲时间也没有足够资源导出相关数据(服务器配置已经不低了) ②导出的Excel文件过大,邮件无法发送。因此该方案不可取。
方案二: 利用Vertica数据库的导出命令,在服务器上写python脚本,通过paramiko操纵数据库导出CSV文件(由于VSQL不支持Excel的导出方式,只要采用CSV)。这种方法最初极为奏效,因为40W条数据用VSQL命令导出只需要2秒,非常神奇。但是这种方案对数据质量有着极高的要求,一旦数据中出现逗号、竖线等特殊字符,极易出现错行问题。由于数据量极大,错行问题难以排查,因此导出的数据对用户来说没有价值。
方案三: 利用Pandas(python的大数据处理工具)的大数据特性,将数据通过SQL查询出来存放到Pandas的 dataframe里面,然后利用pandas的 toExcel()方法将数据写到Excel文件中。经实验,此方案能够奏效,虽然速度比方案二慢了不少,但由于dataframe本身就是二维结构的,因此可以有效避免错行问题。更重要的是,这个方案为我们提供了巨大的想象空间。
在确定了第三套方案以后,我们在方案的基础上做了一系列的完善工作:
1、利用Flask框架将方案三中的处理逻辑做成Restful API的形式,为该方案与帆软报表进行集成提供了可能。
2、在帆软报表中,通过参数面板的开发,加入“直接导出”按钮,并在按钮事件中加入ajax代码,将用户在参数面板上选择的参数传递给API。
3、对集成方式进行进一步优化,实现“直接导出”功能的组件化开发,报表开发人员
只需要将样例模板中的相关组件复制过去,并根据实际需求进行简单修改即可完成该功能的无缝植入。
总结:
这套方案实现了对帆软现有平台功能短板的完美补充,对于大量数据导出的需求,合不合理是一回事,能不能满足是另外一回事。况且,在企业信息化逐步完善的过程中,将明细数据导出进行手工处理的场景短时间内是难以避免的,因此该方案在相当长的实际内仍存在价值。 编辑于 2018-1-22 16:40
|