sqoop學習2(數據導入與導出)


最近學習了下這個導數據的工具,但是在export命令這里卡住了,暫時排不了錯誤。先記錄學習的這一點吧

sqoop是什么

sqoop(sql-on-hadoop):是用來實現結構型數據(如關系型數據庫)和hadoop之間進行數據遷移的工具。它充分利用了mapreduce的並行特點以及批處理的方式加快數據的傳輸,同時也借助mapreduce實現了容錯。

sqoop架構

1)sqoop目前有兩個版本sqoop1(1.4.x)和sqoop2(1.99.x),這里安裝的是sqoop1版本

2)sqoop1是由client端直接接入hadoop,任務通過解析生成對應的mapreduce執行

3)sqoop1架構圖

image

4)導入(import)與導出(export)
導入:往hdfs上導數據
導出:從hdfs上導出去

導入流程:
1)讀取要導入數據的表結構
2)讀取參數,設置好job
3)調用mapreduce執行任務
----a 首先要對數據進行切分
----b 寫入范圍,以便讀取
----c 讀取范圍參數(第二步中設置的參數)
----d 創建RecordReader並從數據庫中讀取數據
----e 創建map
----f 執行map

導出流程:導入過程的逆向過程

sqoop常用命令

命令初步認識

[root@spark1 ~]# sqoop import --connect jdbc:mysql://spark1:3306/wujiadong --username root --table stud_info --target-dir 'hdfs://spark1:9000/user/sqoop_test'

注釋:
sqoop:表示sqoop命令
import:表示導入
--connect jdbc:mysql://spark1:3306 :表示告訴jdbc,連接mysql的url。這個是在hive的hive-site.xml中設置的
wujiadong:表示mysql數據庫中的一個數據庫  
--username root: 連接mysql的用戶名
--password xxx: 連接mysql的密碼,我這里省略了
--table stud_info: 從mysql要導出數據的表名稱
--fields-terminated-by '\t': 指定輸出文件中的行的字段分隔符,我這沒有寫
-m 1 表示復制過程使用1個map作業,如果不寫的話默認是4個map
注:因我安裝mysql時沒有設置密碼,所以沒有加密碼項

我導數據時候有時遇到導入不成功,報10020端口連接不上,試試在namenode上執行命令:
mr-jobhistory-daemon.sh start historyserver 之后再去導數據

1)version:顯示sqoop版本

查看安裝的sqoop版本
[root@spark1 ~]# sqoop version

2)help:查看sqoop幫助信息

[root@spark1 ~]# sqoop help

3)list-databases:打印出關系數據庫所有的數據庫名

顯示出mysql數據庫下所有數據庫名
[root@spark1 sqoop]# sqoop list-databases --connect jdbc:mysql://spark1:3306 --username root

image

數據庫連接參數

–connect <jdbc-uri> :Jdbc連接url,示例如--connect jdbc:mysql://spark1:3306

–connection-manager :指定要使用的連接管理類

–driver :指定jdbc要使用的驅動類

-P :從控制台讀取輸入的密碼,注意P是大寫的

–password :Jdbc url中的數據庫連接密碼

–username :Jdbc url中的數據庫連接用戶名

–verbose :在控制台打印出詳細運行信息

–connection-param-file :一個記錄着數據庫連接參數的文件

4)list-tables:打印出關系數據庫某一數據庫的所有表名

顯示mysql數據庫中wujiadong這個數據庫中所有的表名
[root@spark1 ~]# sqoop list-tables --connect jdbc:mysql://spark1:3306/wujiadong -username root

image

5)import:將數據庫表的數據導入到hive中,如果在hive中沒有對應的表,則自動生成與數據庫表名相同的表

–append : 數據追加到HDFS上一個已存在的數據集上

–as-avrodatafile : 將數據導入到一個Avro數據文件中

–as-sequencefile : 將數據導入到一個sequence文件中

–as-textfile : 將數據導入到一個普通文本文件中,生成該文本文件后,可以在hive中通過sql語句查詢出結果

–boundary-query : 邊界查詢,也就是在導入前先通過SQL查詢得到一個結果集,然后導入的數據就是該結果集內的數據,格式如:–boundary-query ‘select id,creationdate from person where id = 3’,表示導入的數據為id=3的記錄.注意查詢的字段中不能有數據類型為字符串的字段,否則會報錯:java.sql.SQLException: Invalid value for

–columns : 指定要導入的字段值,格式如:–columns id,username

–query,-e<statement> : 從查詢結果中導入數據,該參數使用時必須指定–target-dir、–hive-table,在查詢語句中一定要有where條件且在where條件中需要包含$CONDITIONS,示例:–query ‘select * from person where $CONDITIONS ‘ –target-dir /user/hive/warehouse/person –hive-table person

–split-by<column-name> :表的列名,用來切分工作單元,一般后面跟主鍵ID

–table <table-name> :關系數據庫表名,數據從該表中獲取

–target-dir <dir> :指定hdfs路徑



增量導入

–check-column (col):用來作為判斷的列名,如id
–incremental (mode):append:追加,比如對大於last-value指定的值之后的記錄進行追加導入。lastmodified:最后的修改時間,追加last-value指定的日期之后的記錄
–last-value (value):指定自從上次導入后列的最大值(大於該指定的值),也可以自己設定某一值

數據從mysql導入到hdfs

實例1:將mysql中wujiadong數據庫中的表stud_info表中的數據導入到hdfs(--target-dir)

[root@spark1 ~]# sqoop import --connect jdbc:mysql://spark1:3306/wujiadong --username root --table stud_info --target-dir 'hdfs://spark1:9000/user/sqoop_test'   如果這個目錄存在會報錯。
[root@spark1 ~]# hadoop fs -lsr /user/sqoop_test 導入成功后查看
[root@spark1 ~]# hadoop fs -cat /user/sqoop_test/part* 可以直接查看導入的數據。這里出現了中文亂碼暫時不管,后面解決

如果執行之后不成功可以試試在命令后加上-m 1 只啟動一個map

image

image

實例2:在1的基礎上繼續往這個文件中導入數據(append)

[root@spark1 ~]# sqoop import --connect jdbc:mysql://spark1:3306/wujiadong --username root --table stud_info --append --target-dir 'hdfs://spark1:9000/user/sqoop_test'  可以看到比原來的多了解一個文件

image

實例3:在1基礎上刪除已存在文件並導入數據(--delete-target-dir)

[root@spark1 ~]# sqoop import --connect jdbc:mysql://spark1:3306/wujiadong --username root --table stud_info --target-dir 'hdfs://spark1:9000/user/sqoop_test'   --delete-target-dir

實例4:增量導入數據到hdfs


實例5:指定條件導入(注意不能含中文)

[root@spark1 ~]# sqoop import --connect jdbc:mysql://spark1:3306/wujiadong --username root --table stud_info --target-dir 'hdfs://spark1:9000/user/sqoop_test' -m 1 --where "stud_gend='M'" --append 

模糊查詢
[root@spark1 ~]# sqoop import --connect jdbc:mysql://spark1:3306/wujiadong --username root --table stud_info --target-dir 'hdfs://spark1:9000/user/sqoop_test' -m 1 --where "stud_code like '%201510%'" --append 

image

實例6:啟用壓縮

[root@spark1 ~]# sqoop import --connect jdbc:mysql://spark1:3306/wujiadong --username root --table stud_info --target-dir 'hdfs://spark1:9000/user/sqoop_test' -m 1 --where "stud_gend='M'" --append -z
默認Gzip壓縮;其它壓縮方式用--compression-codec xxx

使用text命令查看壓縮文件
[root@spark1 ~]# hadoop fs -text   /user/sqoop_test/part-m-00001.gz

image

image

實例7:導入空值(NULL)處理

字符串類型
[root@spark1 ~]# sqoop import --connect jdbc:mysql://spark1:3306/wujiadong --username root --table stud_info --target-dir 'hdfs://spark1:9000/user/sqoop_test' -m 1 --where "stud_gend='M'" --append --null-string "**"
非字符串類型
[root@spark1 hive_test]# sqoop import --connect jdbc:mysql://spark1:3306/wujiadong --username root --table stud_info --target-dir 'hdfs://spark1:9000/user/sqoop_test' -m 1 --where "stud_gend='M'" --append --null-string "**" --null-non-string "##"

實例8:sql導入



數據從mysql導入到hive

--hive-home <dir>:直接指定hive安裝目錄
--hive-import:使用默認分隔符導入hive
--hive-overwrite:覆蓋掉在hive表中已經存在的數據
--create-hive-table:生成與關系數據庫表的表結構對應的HIVE表。如果表不存在,則創建,如果存在,報錯
--hive-table <table-name>:導入到hive指定的表,可以創建新表
--hive-drop-import-delims:入數據到hive時,刪除字符串字段中的 \n, \r, and \01 
--hive-delims-replacement:用自定義的字符串替換掉數據中的\n, \r, and \01等字符


--hive-partition-key:創建分區,后面直接跟分區名即可,創建完畢后,通過describe 表名可以看到分區名,默認為string型
--hive-partition-value <v>:該值是在導入數據到hive中時,與–hive-partition-key設定的key對應的value值
--map-column-hive <map>:生成hive表時,可以更改生成字段的數據類型,格式如:–map-column-hive LAST_ACCESS_TIME=string
--fields-terminated-by:指定分隔符(hive默認的分隔符是/u0001)

實例1 :將mysql數據庫wujiadong1中的stud_info表中數據導入到hive總的stud_info1表中(該表未先創建)

[root@spark1 ~]# sqoop import --connect jdbc:mysql://192.168.220.144:3306/wujiadong1 --username root -table stud_info --hive-import -m 1 --hive-table stud_info1
沒有指定導入到哪個數據庫,默認導入到default數據庫中

實例2:將mysql數據庫wujiadong1中的stud_info表中數據導入到hive的sqoop_test數據庫的stud_info表中(該表未先創建)

在hive中創建數據庫sqoop_test
hive> create database sqoop_test;
使用sqoop創建表並導入表
[root@spark1 ~]# sqoop import --connect jdbc:mysql://192.168.220.144:3306/wujiadong1 --username root --table stud_info --hive-import -m 1 --hive-table sqoop_test.stud_info  #指定導入到那個數據庫中
進入hive查看是否導入成功
hive> use sqoop_test;
hive> show tables;
hive> desc stud_info;
hive> select * from stud_info;

image

實例3:在2的基礎上用--hive-overwrite覆蓋導入

[root@spark1 ~]# sqoop import --connect jdbc:mysql://192.168.220.144:3306/wujiadong1 --username root --table stud_info --hive-import -m 1 --hive-table sqoop_test.stud_info --hive-overwrite
只覆蓋數據,不覆蓋表結構

實例4:使用非默認分隔符“,”分隔hive表字段

[root@spark1 ~]# sqoop import --connect jdbc:mysql://192.168.220.144:3306/wujiadong1 --username root --table stud_info --hive-import -m 1 --hive-table sqoop_test.stud_info1 --fields-terminated-by "," 
hive> show create table stud_info1; 查看詳細信息

image

實例5:增量導入



數據從mysql導入到hbase(學完hbase再學)

文件輸出參數

–enclosed-by <char> : 給字段值前后加上指定的字符,比如雙引號,示例:–enclosed-by ‘\”‘,顯示例子:”3″,”jimsss”

–fields-terminated-by <char> : 設定每個字段是以什么符號作為結束的,默認是逗號,也可以改為其它符號

–lines-terminated-by <char> : 設定每條記錄行之間的分隔符,默認是換行,但也可以設定自己所需要的字符串

–delete-target-dir : 每次運行導入命令前,若有就先刪除target-dir指定的目錄


6)export:從hdfs中導出數據到關系數據庫中

--validate <class-name>:啟用數據副本驗證功能,僅支持單表拷貝,可以指定驗證使用的實現類

--validation-threshold <class-name>:指定驗證門限所使用的類

--direct:使用直接導出模式(優化速度)

--export-dir <dir>:導出過程中HDFS源路徑

--m,--num-mappers <n>:使用n個map任務並行導出

--table <table-name>:導出的目的表名稱

--update-key <col-name>:更新參考的列名稱,多個列名使用逗號分隔

--input-null-string <null-string>:使用指定字符串,替換字符串類型值為null的列

--input-null-non-string <null-string>:使用指定字符串,替換非字符串類型值為null的列

--staging-table <staging-table-name>:在數據導出到數據庫之前,數據臨時存放的表名稱

參考資料1:
sqoop中文手冊

參考資料2:
Sqoop導入關系數據庫到Hive

參考資料3:
sqoop安裝文檔

參考資料4:
Sqoop之導入導出操作


免責聲明!

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



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