实习第三周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();
}
}