Sqoop是一款開源的工具,主要用於在Hadoop(Hive)與傳統的數據庫(mysql、postgresql...)間進行數據的傳遞,能夠將一個關係型數據庫(例如 : MySQL ,Oracle ,Postgres等)中的數據導進到Hadoop的HDFS中,也能夠將HDFS的數據導進到關係型數據庫中。java
Sqoop項目開始於2009年,最先是做爲Hadoop的一個第三方模塊存在,後來爲了讓使用者可以快速部署,也爲了讓開發人員可以更快速的迭代開發,Sqoop獨立成爲一個Apache項目。mysql
Sqoop2的最新版本是1.99.7。請注意,2與1不兼容,且特徵不完整,它並不打算用於生產部署。linux
將導入或導出命令翻譯成mapreduce程序來實現。sql
在翻譯出的mapreduce中主要是對inputformat和outputformat進行定製。shell
安裝Sqoop的前提是已經具有Java和Hadoop的環境。數據庫
1) 下載地址:http://mirrors.hust.edu.cn/apache/sqoop/1.4.6/apache
2) 上傳安裝包sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz到虛擬機中app
3) 解壓sqoop安裝包到指定目錄,如:框架
$ tar -zxf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /opt/module/工具
Sqoop的配置文件與大多數大數據框架相似,在sqoop根目錄下的conf目錄中。
1) 重命名配置文件
$ mv sqoop-env-template.sh sqoop-env.sh
2) 修改配置文件
sqoop-env.sh
export HADOOP_COMMON_HOME=/opt/module/hadoop-2.7.2
export HADOOP_MAPRED_HOME=/opt/module/hadoop-2.7.2
export HIVE_HOME=/opt/module/hive
export ZOOKEEPER_HOME=/opt/module/zookeeper-3.4.10
export ZOOCFGDIR=/opt/module/zookeeper-3.4.10
export HBASE_HOME=/opt/module/hbase
拷貝jdbc驅動到sqoop的lib目錄下,如:
$ cp mysql-connector-java-5.1.27-bin.jar /opt/module/sqoop-1.4.6.bin__hadoop-2.0.4-alpha/lib/
咱們能夠經過某一個command來驗證sqoop配置是否正確:
$ bin/sqoop help
出現一些Warning警告(警告信息已省略),並伴隨着幫助命令的輸出:
Available commands:
codegen Generate code to interact with database records
create-hive-table Import a table definition into Hive
eval Evaluate a SQL statement and display the results
export Export an HDFS directory to a database table
help List available commands
import Import a table from a database to HDFS
import-all-tables Import tables from a database to HDFS
import-mainframe Import datasets from a mainframe server to HDFS
job Work with saved jobs
list-databases List available databases on a server
list-tables List available tables in a database
merge Merge results of incremental imports
metastore Run a standalone Sqoop metastore
version Display version information
$ bin/sqoop list-databases --connect jdbc:mysql://hadoop102:3306/ --username root --password 000000
出現以下輸出:
information_schema
metastore
mysql
oozie
performance_schema
在Sqoop中,「導入」概念指:從非大數據集羣(RDBMS)向大數據集羣(HDFS,HIVE,HBASE)中傳輸數據,叫作:導入,即便用import關鍵字。
1) 肯定Mysql服務開啓正常
2) 在Mysql中新建一張表並插入一些數據
$ mysql -uroot -p000000
mysql> create database company;
mysql> create table company.staff(id int(4) primary key not null auto_increment, name varchar(255), sex varchar(255));
mysql> insert into company.staff(name, sex) values('Thomas', 'Male');
mysql> insert into company.staff(name, sex) values('Catalina', 'FeMale');
3) 導入數據
(1)所有導入
$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--table staff \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"
(2)查詢導入
$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--query 'select name,sex from staff where id <=1 and $CONDITIONS;'
提示:must contain '$CONDITIONS' in WHERE clause.
若是query後使用的是雙引號,則$CONDITIONS前必須加轉移符,防止shell識別爲本身的變量。
(3)導入指定列
$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--columns id,sex \
--table staff
提示:columns中若是涉及到多列,用逗號分隔,分隔時不要添加空格
(4)使用sqoop關鍵字篩選查詢導入數據
$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--target-dir /user/company \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--table staff \
--where "id=1"
$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--table staff \
--num-mappers 1 \
--hive-import \
--fields-terminated-by "\t" \
--hive-overwrite \
--hive-table staff_hive
提示:該過程分爲兩步,第一步將數據導入到HDFS,第二步將導入到HDFS的數據遷移到Hive倉庫,第一步默認的臨時目錄是/user/atguigu/表名
$ bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--table company \
--columns "id,name,sex" \
--column-family "info" \
--hbase-create-table \
--hbase-row-key "id" \
--hbase-table "hbase_company" \
--num-mappers 1 \
--split-by id
提示:sqoop1.4.6只支持HBase1.0.1以前的版本的自動建立HBase表的功能
解決方案:手動建立HBase表
hbase> create 'hbase_company,'info'
(5) 在HBase中scan這張表獲得以下內容
hbase> scan ‘hbase_company’
在Sqoop中,「導出」概念指:從大數據集羣(HDFS,HIVE,HBASE)向非大數據集羣(RDBMS)中傳輸數據,叫作:導出,即便用export關鍵字。
$ bin/sqoop export \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--table staff \
--num-mappers 1 \
--export-dir /user/hive/warehouse/staff_hive \
--input-fields-terminated-by "\t"
提示:Mysql中若是表不存在,不會自動建立
使用opt格式的文件打包sqoop命令,而後執行
1) 建立一個.opt文件
$ mkdir opt
$ touch opt/job_HDFS2RDBMS.opt
2) 編寫sqoop腳本
$ vi opt/job_HDFS2RDBMS.opt
export
--connect
jdbc:mysql://hadoop102:3306/company
--username
root
--password
000000
--table
staff
--num-mappers
1
--export-dir
/user/hive/warehouse/staff_hive
--input-fields-terminated-by
"\t"
3) 執行該腳本
$ bin/sqoop --options-file opt/job_HDFS2RDBMS.opt
這裏給你們列出來了一部分Sqoop操做時的經常使用參數,以供參考,須要深刻學習的能夠參看對應類的源代碼。
序號 |
命令 |
類 |
說明 |
1 |
import |
ImportTool |
將數據導入到集羣 |
2 |
export |
ExportTool |
將集羣數據導出 |
3 |
codegen |
CodeGenTool |
獲取數據庫中某張表數據生成Java並打包Jar |
4 |
create-hive-table |
CreateHiveTableTool |
建立Hive表 |
5 |
eval |
EvalSqlTool |
查看SQL執行結果 |
6 |
import-all-tables |
ImportAllTablesTool |
導入某個數據庫下全部表到HDFS中 |
7 |
job
|
JobTool |
用來生成一個sqoop的任務,生成後,該任務並不執行,除非使用命令執行該任務。 |
8 |
list-databases |
ListDatabasesTool |
列出全部數據庫名 |
9 |
list-tables |
ListTablesTool |
列出某個數據庫下全部表 |
10 |
merge |
MergeTool |
將HDFS中不一樣目錄下面的數據合在一塊兒,並存放在指定的目錄中 |
11 |
metastore
|
MetastoreTool |
記錄sqoop job的元數據信息,若是不啓動metastore實例,則默認的元數據存儲目錄爲:~/.sqoop,若是要更改存儲目錄,能夠在配置文件sqoop-site.xml中進行更改。 |
12 |
help |
HelpTool |
打印sqoop幫助信息 |
13 |
version |
VersionTool |
打印sqoop版本信息 |
剛纔列舉了一些Sqoop的經常使用命令,對於不一樣的命令,有不一樣的參數,讓咱們來一一列舉說明。
首先來咱們來介紹一下公用的參數,所謂公用參數,就是大多數命令都支持的參數。
序號 |
參數 |
說明 |
1 |
--connect |
鏈接關係型數據庫的URL |
2 |
--connection-manager |
指定要使用的鏈接管理類 |
3 |
--driver |
Hadoop根目錄 |
4 |
--help |
打印幫助信息 |
5 |
--password |
鏈接數據庫的密碼 |
6 |
--username |
鏈接數據庫的用戶名 |
7 |
--verbose |
在控制檯打印出詳細信息 |
序號 |
參數 |
說明 |
1 |
--enclosed-by <char> |
給字段值前加上指定的字符 |
2 |
--escaped-by <char> |
對字段中的雙引號加轉義符 |
3 |
--fields-terminated-by <char> |
設定每一個字段是以什麼符號做爲結束,默認爲逗號 |
4 |
--lines-terminated-by <char> |
設定每行記錄之間的分隔符,默認是\n |
5 |
--mysql-delimiters |
Mysql默認的分隔符設置,字段之間以逗號分隔,行之間以\n分隔,默認轉義符是\,字段值以單引號包裹。 |
6 |
--optionally-enclosed-by <char> |
給帶有雙引號或單引號的字段值先後加上指定字符。 |
序號 |
參數 |
說明 |
1 |
--input-enclosed-by <char> |
對字段值先後加上指定字符 |
2 |
--input-escaped-by <char> |
對含有轉移符的字段作轉義處理 |
3 |
--input-fields-terminated-by <char> |
字段之間的分隔符 |
4 |
--input-lines-terminated-by <char> |
行之間的分隔符 |
5 |
--input-optionally-enclosed-by <char> |
給帶有雙引號或單引號的字段先後加上指定字符 |
序號 |
參數 |
說明 |
1 |
--hive-delims-replacement <arg> |
用自定義的字符串替換掉數據中的\r\n和\013 \010等字符 |
2 |
--hive-drop-import-delims |
在導入數據到hive時,去掉數據中的\r\n\013\010這樣的字符 |
3 |
--map-column-hive <arg> |
生成hive表時,能夠更改生成字段的數據類型 |
4 |
--hive-partition-key |
建立分區,後面直接跟分區名,分區字段的默認類型爲string |
5 |
--hive-partition-value <v> |
導入數據時,指定某個分區的值 |
6 |
--hive-home <dir> |
hive的安裝目錄,能夠經過該參數覆蓋以前默認配置的目錄 |
7 |
--hive-import |
將數據從關係數據庫中導入到hive表中 |
8 |
--hive-overwrite |
覆蓋掉在hive表中已經存在的數據 |
9 |
--create-hive-table |
默認是false,即,若是目標表已經存在了,那麼建立任務失敗。 |
10 |
--hive-table |
後面接要建立的hive表,默認使用MySQL的表名 |
11 |
--table |
指定關係數據庫的表名 |
公用參數介紹完以後,咱們來按照命令介紹命令對應的特有參數。
將關係型數據庫中的數據導入到HDFS(包括Hive,HBase)中,若是導入的是Hive,那麼當Hive中沒有對應表時,則自動建立。
1) 命令:
如:導入數據到hive中
$ bin/sqoop import \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 \ --table staff \ --hive-import |
如:增量導入數據到hive中,mode=append
append導入: $ bin/sqoop import \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 \ --table staff \ --num-mappers 1 \ --fields-terminated-by "\t" \ --target-dir /user/hive/warehouse/staff_hive \ --check-column id \ --incremental append \ --last-value 3 |
尖叫提示:append不能與--hive-等參數同時使用(Append mode for hive imports is not yet supported. Please remove the parameter --append-mode)
如:增量導入數據到hdfs中,mode=lastmodified
先在mysql中建表並插入幾條數據: mysql> create table company.staff_timestamp(id int(4), name varchar(255), sex varchar(255), last_modified timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); mysql> insert into company.staff_timestamp (id, name, sex) values(1, 'AAA', 'female'); mysql> insert into company.staff_timestamp (id, name, sex) values(2, 'BBB', 'female'); 先導入一部分數據: $ bin/sqoop import \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 \ --table staff_timestamp \ --delete-target-dir \ --m 1 再增量導入一部分數據: mysql> insert into company.staff_timestamp (id, name, sex) values(3, 'CCC', 'female'); $ bin/sqoop import \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 \ --table staff_timestamp \ --check-column last_modified \ --incremental lastmodified \ --last-value "2017-09-28 22:20:38" \ --m 1 \ --append |
尖叫提示:使用lastmodified方式導入數據要指定增量數據是要--append(追加)仍是要--merge-key(合併)
尖叫提示:last-value指定的值是會包含於增量導入的數據中
2) 參數:
序號 |
參數 |
說明 |
1 |
--append |
將數據追加到HDFS中已經存在的DataSet中,若是使用該參數,sqoop會把數據先導入到臨時文件目錄,再合併。 |
2 |
--as-avrodatafile |
將數據導入到一個Avro數據文件中 |
3 |
--as-sequencefile |
將數據導入到一個sequence文件中 |
4 |
--as-textfile |
將數據導入到一個普通文本文件中 |
5 |
--boundary-query <statement> |
邊界查詢,導入的數據爲該參數的值(一條sql語句)所執行的結果區間內的數據。 |
6 |
--columns <col1, col2, col3> |
指定要導入的字段 |
7 |
--direct |
直接導入模式,使用的是關係數據庫自帶的導入導出工具,以便加快導入導出過程。 |
8 |
--direct-split-size |
在使用上面direct直接導入的基礎上,對導入的流按字節分塊,即達到該閾值就產生一個新的文件 |
9 |
--inline-lob-limit |
設定大對象數據類型的最大值 |
10 |
--m或–num-mappers |
啓動N個map來並行導入數據,默認4個。 |
11 |
--query或--e <statement> |
將查詢結果的數據導入,使用時必須伴隨參--target-dir,--hive-table,若是查詢中有where條件,則條件後必須加上$CONDITIONS關鍵字 |
12 |
--split-by <column-name> |
按照某一列來切分表的工做單元,不能與--autoreset-to-one-mapper連用(請參考官方文檔) |
13 |
--table <table-name> |
關係數據庫的表名 |
14 |
--target-dir <dir> |
指定HDFS路徑 |
15 |
--warehouse-dir <dir> |
與14參數不能同時使用,導入數據到HDFS時指定的目錄 |
16 |
--where |
從關係數據庫導入數據時的查詢條件 |
17 |
--z或--compress |
容許壓縮 |
18 |
--compression-codec |
指定hadoop壓縮編碼類,默認爲gzip(Use Hadoop codec default gzip) |
19 |
--null-string <null-string> |
string類型的列若是null,替換爲指定字符串 |
20 |
--null-non-string <null-string> |
非string類型的列若是null,替換爲指定字符串 |
21 |
--check-column <col> |
做爲增量導入判斷的列名 |
22 |
--incremental <mode> |
mode:append或lastmodified |
23 |
--last-value <value> |
指定某一個值,用於標記增量導入的位置 |
從HDFS(包括Hive和HBase)中獎數據導出到關係型數據庫中。
1) 命令:
如:
$ bin/sqoop export \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 \ --table staff \ --export-dir /user/company \ --input-fields-terminated-by "\t" \ --num-mappers 1 |
2) 參數:
序號 |
參數 |
說明 |
1 |
--direct |
利用數據庫自帶的導入導出工具,以便於提升效率 |
2 |
--export-dir <dir> |
存放數據的HDFS的源目錄 |
3 |
-m或--num-mappers <n> |
啓動N個map來並行導入數據,默認4個 |
4 |
--table <table-name> |
指定導出到哪一個RDBMS中的表 |
5 |
--update-key <col-name> |
對某一列的字段進行更新操做 |
6 |
--update-mode <mode> |
updateonly allowinsert(默認) |
7 |
--input-null-string <null-string> |
請參考import該相似參數說明 |
8 |
--input-null-non-string <null-string> |
請參考import該相似參數說明 |
9 |
--staging-table <staging-table-name> |
建立一張臨時表,用於存放全部事務的結果,而後將全部事務結果一次性導入到目標表中,防止錯誤。 |
10 |
--clear-staging-table |
若是第9個參數非空,則能夠在導出操做執行前,清空臨時事務結果表 |
將關係型數據庫中的表映射爲一個Java類,在該類中有各列對應的各個字段。
如:
$ bin/sqoop codegen \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 \ --table staff \ --bindir /home/admin/Desktop/staff \ --class-name Staff \ --fields-terminated-by "\t" |
序號 |
參數 |
說明 |
1 |
--bindir <dir> |
指定生成的Java文件、編譯成的class文件及將生成文件打包爲jar的文件輸出路徑 |
2 |
--class-name <name> |
設定生成的Java文件指定的名稱 |
3 |
--outdir <dir> |
生成Java文件存放的路徑 |
4 |
--package-name <name> |
包名,如com.z,就會生成com和z兩級目錄 |
5 |
--input-null-non-string <null-str> |
在生成的Java文件中,能夠將null字符串或者不存在的字符串設置爲想要設定的值(例如空字符串) |
6 |
--input-null-string <null-str> |
將null字符串替換成想要替換的值(通常與5同時使用) |
7 |
--map-column-java <arg> |
數據庫字段在生成的Java文件中會映射成各類屬性,且默認的數據類型與數據庫類型保持對應關係。該參數能夠改變默認類型,例如:--map-column-java id=long, name=String |
8 |
--null-non-string <null-str> |
在生成Java文件時,能夠將不存在或者null的字符串設置爲其餘值 |
9 |
--null-string <null-str> |
在生成Java文件時,將null字符串設置爲其餘值(通常與8同時使用) |
10 |
--table <table-name> |
對應關係數據庫中的表名,生成的Java文件中的各個屬性與該表的各個字段一一對應 |
生成與關係數據庫表結構對應的hive表結構。
命令:
如:
$ bin/sqoop create-hive-table \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 \ --table staff \ --hive-table hive_staff |
參數:
序號 |
參數 |
說明 |
1 |
--hive-home <dir> |
Hive的安裝目錄,能夠經過該參數覆蓋掉默認的Hive目錄 |
2 |
--hive-overwrite |
覆蓋掉在Hive表中已經存在的數據 |
3 |
--create-hive-table |
默認是false,若是目標表已經存在了,那麼建立任務會失敗 |
4 |
--hive-table |
後面接要建立的hive表 |
5 |
--table |
指定關係數據庫的表名 |
能夠快速的使用SQL語句對關係型數據庫進行操做,常常用於在import數據以前,瞭解一下SQL語句是否正確,數據是否正常,並能夠將結果顯示在控制檯。
命令:
如:
$ bin/sqoop eval \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 \ --query "SELECT * FROM staff" |
參數:
序號 |
參數 |
說明 |
1 |
--query或--e |
後跟查詢的SQL語句 |
能夠將RDBMS中的全部表導入到HDFS中,每個表都對應一個HDFS目錄
命令:
如:
$ bin/sqoop import-all-tables \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 \ --warehouse-dir /all_tables |
參數:
序號 |
參數 |
說明 |
1 |
--as-avrodatafile |
這些參數的含義均和import對應的含義一致 |
2 |
--as-sequencefile |
|
3 |
--as-textfile |
|
4 |
--direct |
|
5 |
--direct-split-size <n> |
|
6 |
--inline-lob-limit <n> |
|
7 |
--m或—num-mappers <n> |
|
8 |
--warehouse-dir <dir> |
|
9 |
-z或--compress |
|
10 |
--compression-codec |
用來生成一個sqoop任務,生成後不會當即執行,須要手動執行。
命令:
如:
$ bin/sqoop job \ --create myjob -- import-all-tables \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 $ bin/sqoop job \ --list $ bin/sqoop job \ --exec myjob |
尖叫提示:注意import-all-tables和它左邊的--之間有一個空格
尖叫提示:若是須要鏈接metastore,則--meta-connect jdbc:hsqldb:hsql://linux01:16000/sqoop
參數:
序號 |
參數 |
說明 |
1 |
--create <job-id> |
建立job參數 |
2 |
--delete <job-id> |
刪除一個job |
3 |
--exec <job-id> |
執行一個job |
4 |
--help |
顯示job幫助 |
5 |
--list |
顯示job列表 |
6 |
--meta-connect <jdbc-uri> |
用來鏈接metastore服務 |
7 |
--show <job-id> |
顯示一個job的信息 |
8 |
--verbose |
打印命令運行時的詳細信息 |
尖叫提示:在執行一個job時,若是須要手動輸入數據庫密碼,能夠作以下優化
<property> <name>sqoop.metastore.client.record.password</name> <value>true</value> <description>If true, allow saved passwords in the metastore.</description> </property> |
命令:
如:
$ bin/sqoop list-databases \ --connect jdbc:mysql://hadoop102:3306/ \ --username root \ --password 000000 |
參數:與公用參數同樣
命令:
如:
$ bin/sqoop list-tables \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 |
參數:與公用參數同樣
將HDFS中不一樣目錄下面的數據合併在一塊兒並放入指定目錄中
數據環境:
new_staff 1 AAA male 2 BBB male 3 CCC male 4 DDD male old_staff 1 AAA female 2 CCC female 3 BBB female 6 DDD female |
尖叫提示:上邊數據的列之間的分隔符應該爲\t,行與行之間的分割符爲\n,若是直接複製,請檢查之。
命令:
如:
建立JavaBean: $ bin/sqoop codegen \ --connect jdbc:mysql://hadoop102:3306/company \ --username root \ --password 000000 \ --table staff \ --bindir /home/admin/Desktop/staff \ --class-name Staff \ --fields-terminated-by "\t"
開始合併: $ bin/sqoop merge \ --new-data /test/new/ \ --onto /test/old/ \ --target-dir /test/merged \ --jar-file /home/admin/Desktop/staff/Staff.jar \ --class-name Staff \ --merge-key id 結果: 1 AAA MALE 2 BBB MALE 3 CCC MALE 4 DDD MALE 6 DDD FEMALE |
參數:
序號 |
參數 |
說明 |
1 |
--new-data <path> |
HDFS 待合併的數據目錄,合併後在新的數據集中保留 |
2 |
--onto <path> |
HDFS合併後,重複的部分在新的數據集中被覆蓋 |
3 |
--merge-key <col> |
合併鍵,通常是主鍵ID |
4 |
--jar-file <file> |
合併時引入的jar包,該jar包是經過Codegen工具生成的jar包 |
5 |
--class-name <class> |
對應的表名或對象名,該class類是包含在jar包中的 |
6 |
--target-dir <path> |
合併後的數據在HDFS裏存放的目錄 |
記錄了Sqoop job的元數據信息,若是不啓動該服務,那麼默認job元數據的存儲目錄爲~/.sqoop,可在sqoop-site.xml中修改。
命令:
如:啓動sqoop的metastore服務
$ bin/sqoop metastore |
參數:
序號 |
參數 |
說明 |
1 |
--shutdown |
關閉metastore |