智慧的老鸟

一个程序员需要有一棵Gank的心,Dota能培养我。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

方法一:

 

环境:win7+sqlserver2008

工具:bcp

测试效率:

新闻数据库,10 000 000行,25.8G

导出时间:约2个小时

每秒约1326

 

 

方法二:

 

用循环执行sql语句,分段写入文件。

 

 

 


 

 

 

1 Bcp介绍

bcp 实用工具可以在 Microsoft SQL Server 实例和用户指定格式的数据文件间大容量复制数据。 使用 bcp 实用工具可以将大量新行导入 SQL Server 表,或将表数据导出到数据文件。 除非与 queryout 选项一起使用,否则使用该实用工具不需要了解 Transact-SQL 知识。 若要将数据导入表中,必须使用为该表创建的格式文件,或者必须了解表的结构以及对于该表中的列有效的数据类型。 

(1) 导入。

这个动作使用in命令完成,后面跟需要导入的文件名。 

(2) 导出。

这个动作使用out命令完成,后面跟需要导出的文件名。 

(3) 使用SQL语句导出。

这个动作使用queryout命令完成,它跟out类似,只是数据源不是表或视图名,而是SQL语句。 

(4) 导出格式文件。

这个动作使用format命令完成,后而跟格式文件名。 

下面介绍一些常用的选项: 

-f format_file 

format_file表示格式文件名。这个选项依赖于上述的动作,如果使用的是inoutformat_file表示已经存在的格式文件,如果使用的是format则表示是要生成的格式文件。 

-x 

这个选项要和-f format_file配合使用,以便生成xml格式的格式文件。

-F first_row 

指定从被导出表的哪一行导出,或从被导入文件的哪一行导入。 

-L last_row 

指定被导出表要导到哪一行结束,或从被导入文件导数据时,导到哪一行结束。 

-c 

使用char类型做为存储类型,没有前缀且以"\t"做为字段分割符,以"\n"做为行分割符。 

-w 

-c类似,只是当使用Unicode字符集拷贝数据时使用,且以nchar做为存储类型。 

-t field_term 

指定字符分割符,默认是"\t"。 

-r row_term 

指定行分割符,默认是"\n"。 

-S server_name[ \instance_name] 

指定要连接的SQL Server服务器的实例,如果未指定此选项,bcp连接本机的SQL Server默认实例。如果要连接某台机器上的默认实例,只需要指定机器名即可。 

-U login_id 

指定连接SQL Sever的用户名。 

-P password 

指定连接SQL Server的用户名密码。 

-T 

指定bcp使用信任连接登录SQL Server。如果未指定-T,必须指定-U-P。 

-k 

指定空列使用null值插入,而不是这列的默认值。 

部署与流程

详细设计

3.1 Sqlserver数据导出到临时文本阶段

Log

BcpSqlserver

JdbcStream

SqlserverToTxt

(代码见SVN-SqlserverToHive

此阶段的是根据自定义每个导出文件中的数据行数进行分文件导出,一个导出成果如下:

导出效率分析:

测试一个文件1000,10000,100000条数据,比较完成时间:

文件数据行数 = 1000 start:1359102390172 end:1359102452310 time use :62138ms

文件数据行数 = 10000 start:1359102452310 end:1359102461626 time use :9316ms

文件数据行数 = 100000 start:1359102461626 end:1359102462997 time use :1371ms

文件数据行数 = 1000000 start:1359102577696 end:1359102578501 time use :805ms

所以,用bcp导数据,文件越少效率越高,这是bcp内部的sql优化导致的。但是,考虑到实际需要,如果需对一个文件有控制,则可以自己设定文件大小。

 

3.2 临时文本导入到hive/hdfs阶段

3.2.1 导入hive

创建符合行列规则的hive

CREATE TABLE table1 (a STRING, b STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ESCAPED BY '\\'
STORED AS TEXTFILE; 

 

Jdbc连接hive,执行load语句

LOAD DATA LOCAL INPATH '/home/admin/test/test.txt' OVERWRITE INTO TABLE test_1 

 

或者直接创建外表指向hdfs中的数据文件

 

create external table IF NOT EXISTS mytest (ID string,Symbol string) LOCATION '/tmp/sqltohdfs

 

 

 

3.2.2 导入hdfs

多线程每个线程处理一个文件导入到hdfs

参考代码

import java.io.IOException;

import java.net.URI;

import java.io.FileInputStream;   

  

import org.apache.hadoop.conf.Configuration;  

import org.apache.hadoop.fs.FileSystem;  

import org.apache.hadoop.fs.FSDataOutputStream;  

import org.apache.hadoop.fs.Path;  

import org.apache.hadoop.io.IOUtils;

 

 

public class LocalToHDFS {

// s 为本地文件路径

// d 为hdfs绝对路径

public static void uploadLocalFile2HDFS(String s, String d)

throws IOException {

Configuration conf = new Configuration();

FileSystem hdfs = FileSystem.get(URI.create(d), conf);

FileInputStream in = null;

FSDataOutputStream out = null;

try {

in = new FileInputStream(s);

out = hdfs.create(new Path(d));

IOUtils.copyBytes(in, out, 4096, false);

finally {

IOUtils.closeStream(in);

IOUtils.closeStream(out);

}

 

}

}

 


posted on 2013-01-29 17:40  智慧的老鸟  阅读(6183)  评论(0编辑  收藏  举报