前言
背景
今天被妹子问到一个问题,往mysql中导入1000W条数据,哪种方式比较快,我居然被问到了,说实话我还真心不知道。
那就找数据呗,搞数据研发的好处就是,数据肯定是很多的,正好还有测试集群。开始在线上找数据。
由于我们很多mysql的表会通过sqoop抽到hdfs中,所有就直接在hdfs中把数据提出来了,不给线上mysql什么压力了。
对比实验
现在使用两种方式分别往mysql数据库中插入数据。
- 一种是load data的形式,
- 一种使用sqoop从hdfs中抽。
数据
- 200W+条数据
- 12个字段,int居多
- 1.2G
- ENGINE=InnoDB
测试环境
测试时,集群本身没什么数据,也没有任何任务,基本可以看成纯净的测试环境。
- 5台hadoop集群,标准8G内存,1T硬盘,cdh5.4.7,各种组件齐全。
- 1台单独mysql服务器。
用两种测试方法,分别使用独自的新表,互不影响。但是是在同一台mysql中。
MySQL load data
使用mysql自带的load工具
LOAD DATA INFILE '/tmp/dante/part-m-00000' INTO TABLE dante.tablename FIELDS TERMINATED BY ',';
1
结果
执行完成总共用了14分钟,感觉还能不错哦。
Query OK, 2106860 rows affected, 65535 warnings (14 min 7.19 sec)
Records: 2106860 Deleted: 0 Skipped: 0 Warnings: 4213720
1
2
遇到的错误信息
错误一
我是直接再hdfs中拿的数据,数据就是通过sqoop从mysql抽出来的,结果还是报了这个错误
ERROR 1406 (22001): Data too long for column 'is_receive' at row 1
1
其实这次此时我不太关注什么数据类型,那就把出问题的数据类型改成varchar。
错误二
ERROR 1261 (01000): Row 1 does not contain data for all columns
1
在 MySQL 中使用 load data infile 命令导入数据文件到 MySQL 数据库中的时候,如果遇到 MySQL 错误:“ERROR 1261 (01000)”,则很可能是由于数据文件中的列数跟 MySQL 数据表字段数目没有完全匹配,并且 sql_mode 设为 strict 模式的缘故。要想在这种情况下继续导入数据到 MySQL 表中,则需要设置 MySQL sql_mode 变量。
mysql> show variables like 'sql_mode';
+---------------+--------------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------------+
| sql_mode | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
1
2
3
4
5
把它改成了ANSI就行了。
set @@sql_mode=ANSI;
1
sqoop
从sqoop导入到mysql之前已经把数据放在了hdfs的/tmp/dante/test
中。
sqoop-export --connect jdbc:mysql://mysql:3306/dante --username root --password root --table tablename --export-dir /tmp/dante/test --input-fields-terminated-by ','
1
结果
sqoop明显要比mysql自身的导入方式要多了,六七分钟就完成了导入。
错误
错误一
16/04/01 19:17:23 ERROR manager.SqlManager: Error executing statement: java.sql.SQLException: null, message from server: "Host 'test' is not allowed to connect to this MySQL server"
java.sql.SQLException: null, message from server: "Host 'test' is not allowed to connect to this MySQL server"at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:959)at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:898)at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:887)at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1038)at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2254)at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2285)at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2084)at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:795)at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:44)at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)at java.lang.reflect.Constructor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15