`
zengloveyuan
  • 浏览: 12245 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

大数据量下载解决方案

    博客分类:
  • java
 
阅读更多

问题描述:              

最近遇到一个很棘手的问题,信用卡网上支付的交易越来越多了,日平均交易数量很大,并且这个数据还处在一个上升的阶段,但这仅仅是个开始。我们这边的系统负责给柜员提供一系列报表,数据量比较大,时不时的会time out,或者会om掉。

原因分析:

Time out超时现象:这个是我们系统跨另外一个系统获取数据,我们所用技术的框架有个超时设置,即一般不能超过60秒。这样设置也合情合理,换作我是客户,我也不愿意在页面提交个请求后,要等很长时间才给我个结果。

这个问题瓶颈在于我们访问后台的时间瓶颈,即我们不能耗时太长,也就是说根本不可能要求修改框架设定的超时时间。

那么怎么解决呢?我们只有要求后台分批返回这些数据。

Outof Memory内存溢出现象:这个问题是当数据量比较大的时候,下载时这些大数据占用太多内存,JAVA虚拟机报出的错误。有个直接的但不长久的解决方法,就是增大JAVA虚拟机的内存设置,但随着数据量的增长,这个解决方法就会被淘汰。

解决方案分析:

Time out问题可以和提供接口方商讨,按照分页的方式即可解决。

我们重点关注一下OM的问题吧。这里有几种解决方案:

1.      用POI或JXL

POI是apache公司的一个子项目,主要提供一组windows文档的Java API;

JXL是Java Excel的简称,一个开放源码的项目,通过它Java开发人员可以操作Excel        文件的内容,可能它更专注些,比如名字就叫做java(不包含其他编程语言)的excel(不处理windows的其他文件),所以数据量稍大时效率以及在消耗内存方面,略胜前者一筹,这里我就不再赘述两者之间的差别了,在网络上大家可以搜索到一大箩筐关于此信息。

数据量 POI/JXL  加载时间(ms) 总耗时(ms)  

 1千条:746K   POI 499 515 JXL 203 359  

 1万条:7.3M   POI 1716 1731 JXL 390 1108  

 5万条:36.8M   POI 7878 7925 JXL 2309 5711 

 





我们来说说稍微好些的插件JXL的处理方式,JXL是将每个单元格生成一个Cell对象,每一个对象都要消耗一定的内存空间,每个对象的大小不同,也会影响内存的使用,所以很容易导致内存溢出。

2.用数据流的方法

从消耗内存的原因出发,既然上述表现较好的JXL由于生成大量的对象导致,我们就采用避免java创建太多的对象,就不用jxl了。用数据流的方法解决。

可以直接写txt文本文件,可以用”/t”来分割内容的话,用户就可以直接把txt生成的内        容直接复制到excel中去。

也可以用流的方式写成.csv格式,写入方式和写txt文件类似,可以用流的方式追加,只要在每列之间以固定标示符进行间隔,不存在内存和格式问题。这种格式可以让用户直接以exl方式打开,而不用复制进去了。

3.HTML方式

其实我们就是用页面元素的属性设置,来达到和xls相互转换,所以可以先写HTML,这样内存不会溢出,写好后,用xls方式打开即可。

不妨你可以试一试,打开一个xls,选择另存为网页,可以查看下这个经过转换后的html的源码,直接把这个HTML文件后缀改为xls,打开后效果和刚刚的那个xls一样。  



这种方式正是我们现在项目所采用的方式,但我们采用的是jsp默认的输出数据到页面,并没有通过java的io程序来实时控制,当数据量比较大的时候,进行适当的flush。所以目前的项目中这种方式,也存在着潜在的OM的可能。



实践验证:

数据流方式csv生成:

public class CSVUtils {

    /** 

     * 导出为CVS文件    

     * @param exportData 

     */ 

    public static File createCSVFile(List exportData, LinkedHashMap rowMapper, String outPutPath) {  

        File csvFile = null;  

        BufferedWriter csvFileOutputStream = null;  

        try {  

            csvFile = File.createTempFile("temp", ".csv", new File(outPutPath));  

            // GB2312使正确读取分隔符","  

            csvFileOutputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(csvFile), "GB2312"),  

                    1024);  

            // 写入文件头部  

            for (Iterator propertyIterator = rowMapper.entrySet().iterator(); propertyIterator.hasNext();) {  

                java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator.next();  

                csvFileOutputStream.write("/"" + propertyEntry.getValue().toString() + "/"");  

                if (propertyIterator.hasNext()) {  

                    csvFileOutputStream.write(",");  

                }  

            }  

            csvFileOutputStream.newLine();  

            // 写入文件内容  

            for (Iterator iterator = exportData.iterator(); iterator.hasNext();) {  

                Object row = (Object) iterator.next();  

                for (Iterator propertyIterator = rowMapper.entrySet().iterator(); propertyIterator.hasNext();) {  

                    java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator.next();  

                    csvFileOutputStream.write("/"" 

                            + BeanUtils.getProperty(row, propertyEntry.getKey().toString()).toString() + "/"");  

                    if (propertyIterator.hasNext()) {  

                        csvFileOutputStream.write(",");  

                    }  

                }  

                if (iterator.hasNext()) {  

                    csvFileOutputStream.newLine();  

                }  

            }  

            csvFileOutputStream.flush();  

        } catch (Exception e) {  

            e.printStackTrace();  

        } finally {  

            try {  

                csvFileOutputStream.close();  

            } catch (IOException e) {  

                e.printStackTrace();  

            }  

        }  

        return csvFile;  

    }      

}



用html方式:



/**

*html方式导出数据

*

*这个格式怎样得到呢?方法是这样: 

*你先建一个excel文件,如a.xls。填上两条伪数据。然后另存为网页,即htm格式,如a.htm。  

*然后,用记事本打开htm格式的a.htm,这样excel文件格式代码就暴露在你面前。     

*剩下的事,就是把a.htm源代码的伪数据部分,替成数据库里的数据,然后把替换后的整个a.htm源代码,用java的io写成一个后缀为xls的文件。就打完收工了。   

*

*注意:

*为了不给内存增加压力,要把a.htm源代码分成三部分:头(伪数据部分 前的代码) + 伪数据部分 + 尾(伪数据部分 后的代码)。   

*先把 头 写到文件,并flush。

*然后是 伪数据部分 ,替一条数据库里的记录就写到文件里,并flush。

*最后把 尾 写到文件,并flush。  

*/

public class htmlAndExcel {

   

    public static void exportToExcel(OutputStream out) throws Exception{  

 

        String str = "<html xmlns:o='urn:schemas-microsoft-com:office:office'"+  

            "xmlns:x='urn:schemas-microsoft-com:office:excel'"+  

            "xmlns='http://www.w3.org/TR/REC-html40'>"+  

            "<head>"+  

            "<meta http-equiv=Content-Type content='text/html; charset=gb2312'>"+  

            "<meta name=ProgId content=Excel.Sheet>"+  

            "<meta name=Generator content='Microsoft Excel 11'>"+  

            "<link rel=File-List href='1111.files/filelist.xml'>"+  

            "<link rel=Edit-Time-Data href='1111.files/editdata.mso'>"+  

            "<link rel=OLE-Object-Data href='1111.files/oledata.mso'>"+  

            "<!--[if gte mso 9]><xml>"+  

             "<o:DocumentProperties>"+  

              "<o:Created>1996-12-17T01:32:42Z</o:Created>"+  

              "<o:LastSaved>2010-03-17T06:50:36Z</o:LastSaved>"+  

              "<o:Version>11.5606</o:Version>"+  

             "</o:DocumentProperties>"+  

             "<o:OfficeDocumentSettings>"+  

              "<o:RemovePersonalInformation/>"+  

             "</o:OfficeDocumentSettings>"+  

            "</xml><![endif]-->"+  

            "<style>"+  

            "<!--table"+  

                "{mso-displayed-decimal-separator:'//.';"+  

                "so-displayed-thousand-separator:'//,';}"+  

            "@page"+  

                "{margin:1.0in .75in 1.0in .75in;"+  

                "mso-header-margin:.5in;"+  

                "mso-footer-margin:.5in;}"+  

            "tr"+  

                "{mso-height-source:auto;"+  

                "mso-ruby-visibility:none;}"+  

            "col"+  

                "{mso-width-source:auto;"+  

                "mso-ruby-visibility:none;}"+  

            "br"+  

                "{mso-data-placement:same-cell;}"+  

            ".style0"+  

                "{mso-number-format:General;"+  

                "text-align:general;"+  

                "vertical-align:bottom;"+  

                "white-space:nowrap;"+  

                "mso-rotate:0;"+  

                "mso-background-source:auto;"+  

                "mso-pattern:auto;"+  

                "color:windowtext;"+  

                "font-size:12.0pt;"+  

                "font-weight:400;"+  

                "font-style:normal;"+  

                "text-decoration:none;"+  

                "font-family:宋体;"+  

                "mso-generic-font-family:auto;"+  

                "mso-font-charset:134;"+  

                "border:none;"+  

                "mso-protection:locked visible;"+  

                "mso-style-name:常规;"+  

                "mso-style-id:0;}"+  

            "td"+  

                "{mso-style-parent:style0;"+  

                "padding-top:1px;"+  

                "padding-right:1px;"+  

                "padding-left:1px;"+  

                "mso-ignore:padding;"+  

                "color:windowtext;"+  

                "font-size:12.0pt;"+  

                "font-weight:400;"+  

                "font-style:normal;"+  

                "text-decoration:none;"+  

                "font-family:宋体;"+  

                "mso-generic-font-family:auto;"+  

                "mso-font-charset:134;"+  

                "mso-number-format:General;"+  

                "text-align:general;"+  

                "vertical-align:bottom;"+  

                "border:none;"+  

                "mso-background-source:auto;"+  

                "mso-pattern:auto;"+  

                "mso-protection:locked visible;"+  

                "white-space:nowrap;"+  

                "mso-rotate:0;}"+  

            "ruby"+  

                "{ruby-align:left;}"+  

            "rt"+  

                "{color:windowtext;"+  

                "font-size:9.0pt;"+  

                "font-weight:400;"+  

                "font-style:normal;"+  

                "text-decoration:none;"+  

                "font-family:宋体;"+  

                "mso-generic-font-family:auto;"+  

                "mso-font-charset:134;"+  

                "mso-char-type:none;"+  

                "display:none;}"+  

            "-->"+  

            "</style>"+  

            "<!--[if gte mso 9]><xml>"+  

             "<x:ExcelWorkbook>"+  

              "<x:ExcelWorksheets>"+  

               "<x:ExcelWorksheet>"+  

                "<x:Name>Sheet1</x:Name>"+  

                "<x:WorksheetOptions>"+  

                 "<x:DefaultRowHeight>285</x:DefaultRowHeight>"+  

                 "<x:CodeName>Sheet1</x:CodeName>"+  

                 "<x:Selected/>"+  

                 "<x:Panes>"+  

                  "<x:Pane>"+  

                   "<x:Number>3</x:Number>"+  

                   "<x:ActiveRow>4</x:ActiveRow>"+  

                   "<x:ActiveCol>4</x:ActiveCol>"+  

                  "</x:Pane>"+  

                 "</x:Panes>"+  

                 "<x:ProtectContents>False</x:ProtectContents>"+  

                 "<x:ProtectObjects>False</x:ProtectObjects>"+  

                 "<x:ProtectScenarios>False</x:ProtectScenarios>"+  

                "</x:WorksheetOptions>"+  

               "</x:ExcelWorksheet>"+  

               "<x:ExcelWorksheet>"+  

                "<x:Name>Sheet2</x:Name>"+  

                "<x:WorksheetOptions>"+  

                 "<x:DefaultRowHeight>285</x:DefaultRowHeight>"+  

                 "<x:CodeName>Sheet2</x:CodeName>"+  

                 "<x:ProtectContents>False</x:ProtectContents>"+  

                 "<x:ProtectObjects>False</x:ProtectObjects>"+  

                 "<x:ProtectScenarios>False</x:ProtectScenarios>"+  

                "</x:WorksheetOptions>"+  

               "</x:ExcelWorksheet>"+  

               "<x:ExcelWorksheet>"+  

                "<x:Name>Sheet3</x:Name>"+  

                "<x:WorksheetOptions>"+  

                 "<x:DefaultRowHeight>285</x:DefaultRowHeight>"+  

                 "<x:CodeName>Sheet3</x:CodeName>"+  

                 "<x:ProtectContents>False</x:ProtectContents>"+  

                 "<x:ProtectObjects>False</x:ProtectObjects>"+  

                 "<x:ProtectScenarios>False</x:ProtectScenarios>"+  

                "</x:WorksheetOptions>"+  

               "</x:ExcelWorksheet>"+  

              "</x:ExcelWorksheets>"+  

              "<x:WindowHeight>4530</x:WindowHeight>"+  

              "<x:WindowWidth>8505</x:WindowWidth>"+  

              "<x:WindowTopX>480</x:WindowTopX>"+  

              "<x:WindowTopY>120</x:WindowTopY>"+  

              "<x:AcceptLabelsInFormulas/>"+  

              "<x:ProtectStructure>False</x:ProtectStructure>"+  

              "<x:ProtectWindows>False</x:ProtectWindows>"+  

             "</x:ExcelWorkbook>"+  

            "</xml><![endif]-->"+  

            "</head>"+  

            "<body link=blue vlink=purple>";  

        str += "<table x:str border=0 cellpadding=0 cellspacing=0 width=144 style='border-collapse:collapse;table-layout:fixed;width:108pt'>"+  

             "<col width=72 span=2 style='width:54pt'>";  

        int count = 1000;  

        while (count>0) {  

            str += "<tr height=19 style='height:14.25pt'>"+  

              "<td height=19 align=right width=72 style='height:14.25pt;width:54pt' x:num>"+count+"</td>"+  

              "<td width=72 style='width:54pt'>"+"仅仅为了测试,^_^"+"</td>"+  

             "</tr>";  

            count--;

        }  

        str += "<![endif]>"+  

            "</table>"+  

            "</body>"+  

            "</html";  

        System.out.println(str);  

        out.write(str.getBytes());  

        out.close();    

    } 

}



结论:

综合上述几种分析,由于项目的特点,暂时采用读取内容到csv文件中,用户可以用xls方式打开。2003版本的excel单sheet是只能65535行,



我们在程序中判断,当达到10000条数据时,就要new sheet.

 

分享到:
评论

相关推荐

    大数据量处理的解决方案

    大数据量处理的解决方案主要聚焦在如何有效地管理和分析海量数据,以提供实时的商业洞察。Style Intelligence的敏捷商业智能平台在这一领域展现出了显著的优势。该平台通过创新的技术,如内存数据库、高速分布式存储...

    appendData异步加载大数据量分片加载数据和增量渲染的解决方案

    "appendData异步加载大数据量分片加载数据和增量渲染的解决方案"是Echarts为优化性能提供的一种高效策略,尤其适用于展示百万级甚至千万级的数据集。本文将深入探讨这一高级进阶技巧。 首先,我们来理解"appendData...

    企业数据要素平台解决方案[32页PPT].pptx

    企业数据要素平台解决方案 企业数据要素平台解决方案旨在为企业提供高效、安全、合规的数据管理方案,帮助企业更好地管理和利用数据要素。该解决方案由多个部分组成,包括数据采集与存储、数据整合与治理、数据挖掘...

    用友主数据管理解决方案.ppt

    用友主数据管理解决方案 用友主数据管理解决方案是企业级的主数据管理解决方案,旨在帮助企业解决主数据管理问题,提高业务效率和决策效率。该解决方案通过集成多个系统和数据库,提供统一的主数据视图,帮助企业...

    WCF大数据量传输解决方案

    2. 解决方案 解决WCF在网络传输中的大数据量问题: A. 需要把相关数据序列化成字节流,再对字节流进行压缩,再进行传输,到了客户端再做反向操作便可获得原始数据。 B. 如果压缩后的数据仍然较大时,可以再压缩流...

    MySQL千万数据解决方案

    缺点:有优化瓶颈,数据量过亿就玩完了。 方案二:升级数据库类型,换一种100%兼容mysql的数据库。优点:不影响现有业务,源程序不需要修改代码,你几乎不需要做任何操作就能提升数据库性能,缺点:多花钱 方案三...

    105页数据安全治理解决方案V4.1.pptx

    随着数据量的增加和数据使用的广泛化,数据安全风险也在增加。例如,数据泄露、数据误用、数据滥用等问题变得越来越严重。 然后,本方案提出了一系列的解决方案,涵盖了数据安全的多个方面。第一,数据分类分级,...

    数据备份管理解决方案

    沃天路数据备份管理方案是...该解决方案主要采用了基于SAN和LAN的网络备份技术,整合了多家厂商的软硬件平台,为客户量身定制数据备份和恢复解决方案,帮助客户保障数据安全、实现业务的持续稳定运行、提高维护效率。

    poi大量数据读取gc内存溢出解决方案

    poi读取大量数据会造成gc内存溢出的报错,由于垃圾回收机制无法将大量的对象及时的回收,而这些对象又会保存在内存中,会导致内存不够用的情况,这时候我们就需要使用新的方法,读取...此解决方案可支持千万数据的传输不报错

    mysql数据库大数据量导入导出多种方法

    mysql数据库大数据量导入导出多种方法,该文档详述SELECT * INTO和mysqldump导出方法。导入方法中包括导入sql,txt文件和load data三种方法

    Informatica精益数据管理解决方案

    Informatica的精益数据管理解决方案是一种高效且可持续的策略,旨在应对生产和非生产环境中日益膨胀的数据量问题。随着数据年增长率高达65%,其中大部分(约80%)被视为休眠数据,管理和维护这些数据变得既费时又...

    大客户数据管理系统解决方案

    越来越多的企业管理部门采用信息管理系统通过办公室的一台计算机完成复杂的日常业务处理,减少工作量从而提高...在此版本基础上,可增加更人性化的一些管理功能,从而提供一套完整的计算机辅助大客户数据管理解决方案。

    Redis大数据量Key存储需求及解决方案.docx

    Redis 大数据量 Key 存储需求及解决方案 对于 Redis 大数据量 Key 存储需求,解决方案的关键点在于如何高效地存储和管理大量的 Key-Value 对和 Hash 表数据。在此解决方案中,我们将讨论以下几个方面的技术挑战和...

    2020版非结构化数据管理解决方案白皮书精品报告2020.pdf

    根据《2020版非结构化数据管理解决方案白皮书》的内容,我们可以了解到非结构化数据的定义、特征、发展历程以及管理体系等多个方面的知识点。 非结构化数据是指不符合传统数据库表格结构的数据,例如文本、图片、...

    大数据量报表展现系统建设方案详细.pdf

    大数据量报表展现系统建设方案是针对互联网环境下,企业面临海量数据处理挑战的一种解决方案。系统的主要目标是构建一个数据集散中心、报表处理中心和决策辅助支持中心,将分散的业务数据整合,提供高效的数据提取、...

    海量数据存储解决方案.pdf

    海量数据存储解决方案 海量数据存储解决方案主要解决了企业在海量数据时代面临的挑战,即如何高效地存储、处理和分析大量的结构化和非结构化数据。解决方案基于数据湖的概念,将所有类型的数据存储在一个统一的平台...

    plsql大数据量导出工具

    在Oracle数据库环境中,...综上所述,"plsql大数据量导出工具"结合了SQL*Loader、PL/SQL以及大数据处理的最佳实践,旨在提供一个高效、安全且灵活的解决方案,帮助用户在Oracle环境中轻松处理大规模数据的导出需求。

    华为数据中心灾备解决方案.pptx

    华为数据中心灾备解决方案 华为数据中心灾备解决方案是指建立在数据中心内的一整套灾备系统,旨在保护数据中心免受自然灾害和人为事故的影响。灾备系统的建设是基于灾备设计方法的,旨在于提供一个可靠的数据保护...

    Oracle数据仓库解决方案.pptx

    Oracle 9i引入了许多新特性,如分区、并行执行和资源管理,以优化大数据量的处理。 2. **Warehouse Builder**:这是一个ETL(抽取、转换、加载)工具,负责从各种源系统中提取数据,进行清洗、转换,并加载到数据...

Global site tag (gtag.js) - Google Analytics