实习第三周1
周一老大回来了,又和我还有PM一起开了一个会。当然先狠批了上周的数据库设计,虽然是我设计的,但项目有哪些需求都是PM跟我讲的,这很明显是PM和老大不能互相理解,然而PM让我每个数据库留下5个保留字段的设定我也不能理解,这当然又被老大狠狠的骂了。于是数据库交给PM返工,项目又加了另一个帮手(妹子)来研究需求和设计功能。最后在实现上又不能互相理解了,老大提出全部使用JSP来完成所有的功能,最后折衷选择了servlet来实现。
当然因为返工的问题,我暂时没什么活,老大给了我一个新任务,让我把日志文件导成数据库。
所有文件加起来有12GB,已经切片成了64个文件。
当然第一天我就写好读取文件,以及连接数据库,速度大概是一分钟3000行。
连接数据需要mysql-connector-java-5.1.36.jar,可以通过Intellij IDEA的工具从maven上搜索mysql下载
try { Class.forName("com.mysql.jdbc.Driver").newInstance(); con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/simz", "root", ""); statement = con.createStatement(); } catch (Exception e) { bufferWritter.write(e.toString()); //fileWritter.write(e.toString() + "\r\n"); }
当然一分钟3000行的速度实在太慢了,一次只插入一行是无法满足要求的。经过计算,插完这些数据需要10天,这完全不能接受。
然后只能想办法提高速度,想到了insert可以一次添加多行。但是这样会提高错误率,因为一次插入一行,统计插入错误是一件很简单的事,然而一次插入100行的话,有一行插入失败就会这100行都失败,只能在失败时把整句sql语句写入日志。这样插入速度差不多能提高100倍。
在大数据量操作时,使用String拼接字符串时会大量创建String对象,在内存使用以及GC时会产生大量压力。我在这里使用StringBuffer处理。
然而在实际操作时却发现在插入到300w行时会发生内存溢出、GC失败。提示在con.createStatement()的地方出错。这根本没法调错,我也没管那么那么多,就每过100w行关闭一次数据库连接,再连接一次数据库。
后来查了资料才知道Statement不会显式GC,但可以使用close方法关闭。当然这是几天之后的事了(程序无错误全部跑下来就好了
最后插入花了8个多小时,数据库有10GB多,产生错误日志好像有2M的样子。给老大汇报之后,我就不管了。
查询的时候需要等快5分钟,在给大部分字段加了索引之后,查询速度也基本没有提高(谁让数据库这么大呢,又不是Oracle
package com.read; import java.io.*; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class Main { public static void main(String[] args) throws IOException, SQLException, ClassNotFoundException { //simz0.txt String basepath = "E:\\sources\\simz"; String logpath = "E:\\sources\\log.txt"; //String basepath = "c:\\中控室西门子\\simz"; //S1tring logpath = "c:\\log.txt"; StringBuffer buffer = new StringBuffer(); StringBuffer tsql = new StringBuffer(); String temp = null; String todo = temp; char c = ' '; int cc; Dataintxt dataintxt = new Dataintxt(); File log =new File(logpath); if(!log.exists()){ log.createNewFile(); } FileWriter fileWritter = new FileWriter(log); BufferedWriter bufferWritter = new BufferedWriter(fileWritter); Date date = new Date(); DateFormat format = new SimpleDateFormat("EEE MMM d hh:mm:ss yyyy"); String time = format.format(date); bufferWritter.write("logstart:" + "\r\n" + time + "\r\n"); bufferWritter.flush(); Connection con = null; Statement statement = null; int count = 0; int insert = 0; String tosql = ""; try { Class.forName("com.mysql.jdbc.Driver").newInstance(); con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/simz", "root", ""); statement = con.createStatement(); } catch (Exception e) { bufferWritter.write(e.toString()); //fileWritter.write(e.toString() + "\r\n"); } /* Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/simz?user=root&password="); Statement statement = conn.createStatement(); */ for(int i = 1; i<=64 ;i++ ) { String filename = basepath+String.valueOf(i)+".txt"; File file = new File(filename); System.out.println(filename); if(file.isFile()&&file.exists()) { InputStreamReader reader = new InputStreamReader(new FileInputStream(file),"UTF-8"); BufferedReader bufferedReader = new BufferedReader(reader); while((cc = bufferedReader.read()) != -1) { if((char)cc == ';' ) { try { //todo = temp; todo = buffer.toString(); //temp = null; buffer.delete(0, buffer.length()); dataintxt.clear(); statement = con.createStatement(); tsql = tsql.append(Main.handle(todo, dataintxt)); insert++; if(insert == 100) { tosql = tsql.toString(); if(tosql.lastIndexOf(",") == tosql.length()-1) { tosql = tosql.substring(0,tosql.length()-1); } boolean rs = statement.execute("insert into data values " + tosql); tsql = new StringBuffer(); tosql = ""; insert = 0; } else { tsql.append(","); } count++; if(count == 1000000) { count = 0; con.close(); Class.forName("com.mysql.jdbc.Driver").newInstance(); con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/simz", "root", ""); statement = con.createStatement(); } } catch (Exception e) { bufferWritter.write("\r\n" + filename); bufferWritter.write("\r\n" + todo); bufferWritter.write("\r\n" + tsql); tsql = new StringBuffer(); tosql = ""; insert = 0; bufferWritter.write("\r\n" + e.toString()); bufferWritter.write("\r\n"); bufferWritter.flush(); //fileWritter.write(filename+"\r\n"); //fileWritter.write(todo); //fileWritter.write("\r\n" + e.toString()); //fileWritter.write("\r\n\r\n"); System.out.println(e); } } else { //temp += (char)cc; c = (char)cc; buffer.append(c); } } if(tsql.equals("")) { tosql = tsql.toString(); if(tosql.lastIndexOf(",") == tosql.length()-1) { tosql = tosql.substring(0,tosql.length()-1); } try { boolean rs = sql.execute("insert into data values " + tosql); tsql = new StringBuffer(); tosql = ""; } catch (Exception e) { bufferWritter.write("\r\n" + filename); bufferWritter.write("\r\n" + todo); bufferWritter.write("\r\n" + tsql); tsql = new StringBuffer(); tosql = ""; insert = 0; bufferWritter.write("\r\n" + e.toString()); bufferWritter.write("\r\n"); bufferWritter.flush(); System.out.println(e); } } } } try { date = new Date(); time = format.format(date); bufferWritter.write("logend:" + "\r\n" + time + "\r\n"); bufferWritter.flush(); bufferWritter.close(); //fileWritter.write("logstart"); //fileWritter.flush(); //fileWritter.close(); } finally { bufferWritter.close(); } }