方法一:
環(huán)境: win7+sqlserver2008
工具: bcp
測試效率:
新聞數(shù)據(jù)庫, 10?000?000 行, 25.8G
導出時間:約 2 個小時
每秒約 1326 行
?
?
方法二:
?
用循環(huán)執(zhí)行sql語句,分段寫入文件。
?
?
?
?
?
?
1?Bcp 介紹
bcp? 實用工具可以在? Microsoft?SQL?Server? 實例和用戶指定格式的數(shù)據(jù)文件間大容量復制數(shù)據(jù)。?使用? bcp? 實用工具可以將大量新行導入? SQL?Server? 表,或?qū)⒈頂?shù)據(jù)導出到數(shù)據(jù)文件。?除非與? queryout? 選項一起使用,否則使用該實用工具不需要了解? Transact-SQL? 知識。?若要將數(shù)據(jù)導入表中,必須使用為該表創(chuàng)建的格式文件,或者必須了解表的結(jié)構(gòu)以及對于該表中的列有效的數(shù)據(jù)類型。 ?
(1)? 導入。
這個動作使用 in 命令完成,后面跟需要導入的文件名。?
(2)? 導出。
這個動作使用 out 命令完成,后面跟需要導出的文件名。?
(3)? 使用 SQL 語句導出。
這個動作使用 queryout 命令完成,它跟 out 類似,只是數(shù)據(jù)源不是表或視圖名,而是 SQL 語句。?
(4)? 導出格式文件。
這個動作使用 format 命令完成,后而跟格式文件名。?
下面介紹一些常用的選項:?
-f?format_file?
format_file 表示格式文件名。這個選項依賴于上述的動作,如果使用的是 in 或 out , format_file 表示已經(jīng)存在的格式文件,如果使用的是 format 則表示是要生成的格式文件。?
-x?
這個選項要和 -f?format_file 配合使用,以便生成 xml 格式的格式文件。
-F?first_row?
指定從被導出表的哪一行導出,或從被導入文件的哪一行導入。?
-L?last_row?
指定被導出表要導到哪一行結(jié)束,或從被導入文件導數(shù)據(jù)時,導到哪一行結(jié)束。?
-c?
使用 char 類型做為存儲類型,沒有前綴且以 "\t" 做為字段分割符,以 "\n" 做為行分割符。?
-w?
和 -c 類似,只是當使用 Unicode 字符集拷貝數(shù)據(jù)時使用,且以 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 數(shù)據(jù)導出到臨時文本階段
Log 類
BcpSqlserver 類
JdbcStream 類
SqlserverToTxt 類
(代碼見 SVN-SqlserverToHive )
此階段的是根據(jù)自定義每個導出文件中的數(shù)據(jù)行數(shù)進行分文件導出,一個導出成果如下:
導出效率分析:
測試一個文件 1000,10000,100000 條數(shù)據(jù),比較完成時間:
文件數(shù)據(jù)行數(shù)? =?1000?start:1359102390172?end:1359102452310?time?use?:62138ms
文件數(shù)據(jù)行數(shù)? =?10000?start:1359102452310?end:1359102461626?time?use?:9316ms
文件數(shù)據(jù)行數(shù)? =?100000?start:1359102461626?end:1359102462997?time?use?:1371ms
文件數(shù)據(jù)行數(shù)? =?1000000?start:1359102577696?end:1359102578501?time?use?:805ms
所以,用 bcp 導數(shù)據(jù),文件越少效率越高,這是 bcp 內(nèi)部的 sql 優(yōu)化導致的。但是,考慮到實際需要,如果需對一個文件有控制,則可以自己設定文件大小。
?
3.2? 臨時文本導入到 hive/hdfs 階段
3.2.1? 導入 hive
創(chuàng)建符合行列規(guī)則的 hive 表
CREATE?TABLE?table1?(a?STRING,?b?STRING)
ROW?FORMAT?DELIMITED?FIELDS?TERMINATED?BY?'\t'?ESCAPED?BY?'\\'
STORED?AS?TEXTFILE;
?
?
Jdbc 連接 hive ,執(zhí)行 load 語句
LOAD?DATA?LOCAL?INPATH?'/home/admin/test/test.txt'?OVERWRITE?INTO?TABLE?test_1?
?
或者直接創(chuàng)建外表指向hdfs中的數(shù)據(jù)文件
?
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);
}
?
}
}
?
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
