sqlserver數據導入hdfs和hive的解決方案


方法一:

 

環境: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);

}

 

}

}

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM