方法一:
環境: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表示格式文件名。這個選項依賴於上述的動作,如果使用的是in或out,format_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值插入,而不是這列的默認值。
2 部署與流程
3 詳細設計
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);
}
}
}