多线程导入GB数据到MySQL

Description: 1千万数据导入MySQL
Mac OSX 10.8 + MySQL5.6.3 + Eclipse4.x
MySQL采用Brew安装

首先创建表结构student(id,name)

1
2
3
4
create table student(
    id int,
    name varchar(10)
);

Java程序随机产生1千万条记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.test;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 
 * 此类描述的是:用来生成student,score表的模拟数据
 * @author: dmnrei@gmail.com
 * @version: 2013-10-17 下午3:52:09
 */
public class LX1017 {
    /**
     * 表记录数,默认一千万
     */
    static int recordNum = 10000000;

    public static void main(String[] args) throws IOException {
        // 生成学生表的sql文件
        generateStudent();
    }

    public static void generateStudent() throws IOException {
        FileWriter fileWriter2 = new FileWriter("student.sql", false);  
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter2);  

        StringBuffer sb = new StringBuffer(1024*1024);
        for(int i=1; i<=recordNum; i++) {
            String str = "insert into student values(" + i+ ", '" + i + "');";
            sb.append(str);
            sb.append("\n");

            if(i%10000 == 0) {
                bufferedWriter.write(sb.toString());
                bufferedWriter.flush();
                sb = new StringBuffer(1024*1024);
            }
        }
        bufferedWriter.close();
    }
}

Mysqldump导入数据库 (耗时30min)

1
2
3
4
5
now=$(date +"%T")
echo "Current time : $now"
mysql -u username -ppwd test < student.sql
now=$(date +"%T")
echo "Current time : $now"

由于耗时过长,尝试多线程导入 (耗时15min)
线程数目1k
每个线程处理10k条记录

0) 线程启动应该间隔启动,50ms, 一下子起来会死的好惨

1) 每个线程一次处理1k个sql插入,采用batch插入,每次处理也让线程休息下,中途数据库操作类不要关闭连接,直到完成手动释放连接。

2) MySQL的最大连接数1k个,/usr/local/Cellar/mysql/5.6.13/my.cnf在[mysqld]修改max_connections=2000,重启mysql即可
alias restart-mysql=“/usr/local/Cellar/mysql/5.6.13/support-files/mysql.server restart”
alias stop-mysql=“/usr/local/Cellar/mysql/5.6.13/support-files/mysql.server stop”
alias start-mysql=“/usr/local/Cellar/mysql/5.6.13/support-files/mysql.server start”
进入mysql,利用命令查看show variables like ‘max%’,可以验证是否修改成功。

3) Eclipse4.x运行程序,经常内存不足
修改Run Configurations (此方法可行)
在代码上右键,依次点击Run As -> Run Configurations,在Arguments 参数中的VM arguments:
中填入如下值即可。
-Xms512m -Xmx1024m

最后尝试了mysql导入脚本,首先mysqldump出student表结构数据,然后重新导入(耗时1min,惊呆了~~)
0) 上锁
Lock Table ‘student’ Write
insert………..
Unlock ‘student’

1) Batch插入
insert into student values(1,‘1’),(2,‘2’)……,一条insert语句含有6万条记录。

做一件事情,先做好,在做精