大資料框架開發基礎之Sqoop(1) 入門
Sqoop是一款開源的工具,主要用於在Hadoop(Hive)與傳統的資料庫(mysql、postgresql...)間進行資料的傳遞,可以將一個關係型資料庫(例如 : MySQL ,Oracle ,Postgres等)中的資料導進到Hadoop的HDFS中,也可以將HDFS的資料導進到關係型資料庫中。
Sqoop的基本認知
原理
將匯入或匯出命令翻譯成mapreduce程式來實現。
在翻譯出的mapreduce中主要是對inputformat和outputformat進行定製。
安裝
Sqoop的安裝也很簡單,首先我們需要有有一個Sqoop安裝包,這個包老夫也提供了。
我們在如下目錄中:
drwxr-xr-x 2 corp corp 4096 Dec 19 2017 bin -rw-rw-r-- 1 corp corp 55089 Dec 19 2017 build.xml -rw-rw-r-- 1 corp corp 47426 Dec 19 2017 CHANGELOG.txt -rw-rw-r-- 1 corp corp 9880 Dec 19 2017 COMPILING.txt drwxr-xr-x 2 corp corp 4096 Dec 19 2017 conf drwxr-xr-x 5 corp corp 4096 Dec 19 2017 docs drwxr-xr-x 2 corp corp 4096 Dec 19 2017 ivy -rw-rw-r-- 1 corp corp 11163 Dec 19 2017 ivy.xml drwxr-xr-x 2 corp corp 4096 Dec 19 2017 lib -rw-rw-r-- 1 corp corp 15419 Dec 19 2017 LICENSE.txt -rw-rw-r-- 1 corp corp 505 Dec 19 2017 NOTICE.txt -rw-rw-r-- 1 corp corp 18772 Dec 19 2017 pom-old.xml -rw-rw-r-- 1 corp corp 1096 Dec 19 2017 README.txt -rw-rw-r-- 1 corp corp 1108073 Dec 19 2017 sqoop-1.4.7.jar -rw-rw-r-- 1 corp corp 6554 Dec 19 2017 sqoop-patch-review.py -rw-rw-r-- 1 corp corp 765184 Dec 19 2017 sqoop-test-1.4.7.jar drwxr-xr-x 7 corp corp 4096 Dec 19 2017 src drwxr-xr-x 4 corp corp 4096 Dec 19 2017 testdata
我們進入到 conf/ 目錄下,先修改檔案 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/apache-hive-1.2.1 export ZOOKEEPER_HOME=/opt/module/zookeeper-3.4.10 export ZOOCFGDIR=/opt/module/zookeeper-3.4.10 export HBASE_HOME=/opt/module/hbase-1.1.2
再將我們的JDBC的驅動拷貝到 sqoop的 lib/ 下
cp mysql-connector-java-5.1.27-bin.jar /opt/module/sqoop-1.4.7/lib/
我們可以通過某一個command來驗證sqoop配置是否正確:
bin/sqoop help 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
測試Sqoop能否連線到MySQL
bin/sqoop list-databases --connect jdbc:mysql://hadoop101:3306/ --username root --password 000000
# 出現下面的標識連線成功了
information_schema
amon
azkaban
cm
corp-ci
hive
hue
metastore
mysql
oozie
performance_schema
telecom-customer-service
test
Sqoop的連線案例
匯入資料
Note: 在Sqoop中,“匯入”概念指:從非大資料叢集(RDBMS)向大資料叢集(HDFS,HIVE,HBASE)中傳輸資料,叫做:匯入,即使用import關鍵字。
RDBMS到HDFS
1) 確定Mysql服務開啟正常
2) 在Mysql中新建一張表並插入一些資料
下面是老夫之前在資料庫中就已經存在的資料,在140W+
全部匯入
bin/sqoop import \
--connect jdbc:mysql://hadoop101:3306/sun-iot \
--username root \
--password 000000 \
--table telecom-customer-service \
--target-dir /user/telecom-customer-service \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"
查詢匯入
bin/sqoop import \
--connect jdbc:mysql://hadoop101:3306/sun-iot \
--username root \
--password 000000 \
--target-dir /user/telecom-customer-service \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--query 'select call1,call2,date_time,duration from telecom-customer-service where id <=1 and $CONDITIONS;'
Note:
提示:must contain '$CONDITIONS' in WHERE clause.
如果query後使用的是雙引號,則$CONDITIONS前必須加轉移符,防止shell識別為自己的變數。
匯入指定列
bin/sqoop import \
--connect jdbc:mysql://hadoop101:3306/sun-iot \
--username root \
--password 000000 \
--target-dir /user/sun-iot \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--columns id,call1,calla_name,call2,call2_name,date_time,duration \
--table telecom-customer-service
刪選關鍵字匯入
bin/sqoop import \
--connect jdbc:mysql://hadoop101:3306/sun-iot \
--username root \
--password 000000 \
--target-dir /user/sun-iot \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--table telecom-customer-service \
--where "id=1"
RDBMS到Hive
bin/sqoop import \
--connect jdbc:mysql://hadoop101:3306/sun-iot \
--username root \
--password 000000 \
--table telecom-customer-service \
--num-mappers 1 \
--hive-import \
--fields-terminated-by "\t" \
--hive-overwrite \
--hive-table sun_iot.telecom_customer_service
Note: 提示:該過程分為兩步,第一步將資料匯入到HDFS,第二步將匯入到HDFS的資料遷移到Hive倉庫,第一步預設的臨時目錄是/user/corp/表名
RDBMS到Hbase
bin/sqoop import \
--connect jdbc:mysql://hadoop101:3306/sun-iot \
--username root \
--password 000000 \
--table telecom-customer-service \
--columns "id,call1,call1_name,call2,call2_name,date_time,date_time_ts,duration" \
--column-family "info" \
--hbase-create-table \
--hbase-row-key "id,call1,call2" \
--hbase-table "telecom_customer_service" \
--num-mappers 1
匯出
在Sqoop中,“匯出”概念指:從大資料叢集(HDFS,HIVE,HBASE)向非大資料叢集(RDBMS)中傳輸資料,叫做:匯出,即使用export關鍵字。
bin/sqoop export \
--connect jdbc:mysql://hadoop101:3306/sun-iot \
--username root \
--password 000000 \
--table telecom-customer-service \
--num-mappers 1 \
--export-dir /user/hive/warehouse/telecom-customer-service \
--input-fields-terminated-by "\t"
Sqoop一些常用命令及引數
常用命令列舉
這裡給大家列出來了一部分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 | 在控制檯打印出詳細資訊 |
公用引數:import
序號 | 引數 | 說明 |
---|---|---|
1 | --enclosed-by | 給欄位值前加上指定的字元 |
2 | --escaped-by | 對欄位中的雙引號加轉義符 |
3 | --fields-terminated-by | 設定每個欄位是以什麼符號作為結束,預設為逗號 |
4 | --lines-terminated-by | 設定每行記錄之間的分隔符,預設是\n |
5 | --mysql-delimiters | Mysql預設的分隔符設定,欄位之間以逗號分隔,行之間以\n分隔,預設轉義符是,欄位值以單引號包裹。 |
6 | --optionally-enclosed-by | 給帶有雙引號或單引號的欄位值前後加上指定字元。 |
公用引數:export
序號 | 引數 | 說明 |
---|---|---|
1 | --input-enclosed-by | 對欄位值前後加上指定字元 |
2 | --input-escaped-by | 對含有轉移符的欄位做轉義處理 |
3 | --input-fields-terminated-by | 欄位之間的分隔符 |
4 | --input-lines-terminated-by | 行之間的分隔符 |
5 | --input-optionally-enclosed-by | 給帶有雙引號或單引號的欄位前後加上指定字元 |
公用引數:hive
序號 | 引數 | 說明 |
---|---|---|
1 | --hive-delims-replacement | 用自定義的字串替換掉資料中的\r\n和\013 \010等字元 |
2 | --hive-drop-import-delims | 在匯入資料到hive時,去掉資料中的\r\n\013\010這樣的字元 |
3 | --map-column-hive | 生成hive表時,可以更改生成欄位的資料型別 |
4 | --hive-partition-key | 建立分割槽,後面直接跟分割槽名,分割槽欄位的預設型別為string |
5 | --hive-partition-value | 匯入資料時,指定某個分割槽的值 |
6 | --hive-home |
hive的安裝目錄,可以通過該引數覆蓋之前預設配置的目錄 |
7 | --hive-import | 將資料從關係資料庫中匯入到hive表中 |
8 | --hive-overwrite | 覆蓋掉在hive表中已經存在的資料 |
9 | --create-hive-table | 預設是false,即,如果目標表已經存在了,那麼建立任務失敗。 |
10 | --hive-table | 後面接要建立的hive表,預設使用MySQL的表名 |
11 | --table | 指定關係資料庫的表名 |
公用引數介紹完之後,我們來按照命令介紹命令對應的特有引數。
命令&引數:import
將關係型資料庫中的資料匯入到HDFS(包括Hive,HBase)中,如果匯入的是Hive,那麼當Hive中沒有對應表時,則自動建立。
1) 命令:
如:匯入資料到hive中
bin/sqoop import \
--connect jdbc:mysql://hadoop101:3306/sun-iot \
--username root \
--password 000000 \
--table staff \
--hive-import
如:增量匯入資料到hive中,mode=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 | 邊界查詢,匯入的資料為該引數的值(一條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 | 將查詢結果的資料匯入,使用時必須伴隨參--target-dir,--hive-table,如果查詢中有where條件,則條件後必須加上$CONDITIONS關鍵字 |
12 | --split-by | 按照某一列來切分表的工作單元,不能與--autoreset-to-one-mapper連用(請參考官方文件) |
13 | --table | 關係資料庫的表名 |
14 | --target-dir |
指定HDFS路徑 |
15 | --warehouse-dir |
與14引數不能同時使用,匯入資料到HDFS時指定的目錄 |
16 | --where | 從關係資料庫匯入資料時的查詢條件 |
17 | --z或--compress | 允許壓縮 |
18 | --compression-codec | 指定hadoop壓縮編碼類,預設為gzip(Use Hadoop codec default gzip) |
19 | --null-string | string型別的列如果null,替換為指定字串 |
20 | --null-non-string | 非string型別的列如果null,替換為指定字串 |
21 | --check-column | |
作為增量匯入判斷的列名 | ||
22 | --incremental | mode:append或lastmodified |
23 | --last-value | 指定某一個值,用於標記增量匯入的位置 |
命令&引數:export
從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 |
存放資料的HDFS的源目錄 |
3 | -m或--num-mappers | 啟動N個map來並行匯入資料,預設4個 |
4 | --table | 指定匯出到哪個RDBMS中的表 |
5 | --update-key | 對某一列的欄位進行更新操作 |
6 | --update-mode | updateonly allowinsert(預設) |
7 | --input-null-string | 請參考import該類似引數說明 |
8 | --input-null-non-string | 請參考import該類似引數說明 |
9 | --staging-table | 建立一張臨時表,用於存放所有事務的結果,然後將所有事務結果一次性匯入到目標表中,防止錯誤。 |
10 | --clear-staging-table | 如果第9個引數非空,則可以在匯出操作執行前,清空臨時事務結果表 |
命令&引數:codegen
將關係型資料庫中的表對映為一個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 |
指定生成的Java檔案、編譯成的class檔案及將生成檔案打包為jar的檔案輸出路徑 |
2 | --class-name | 設定生成的Java檔案指定的名稱 |
3 | --outdir |
生成Java檔案存放的路徑 |
4 | --package-name | 包名,如com.z,就會生成com和z兩級目錄 |
5 | --input-null-non-string | 在生成的Java檔案中,可以將null字串或者不存在的字串設定為想要設定的值(例如空字串) |
6 | --input-null-string | 將null字串替換成想要替換的值(一般與5同時使用) |
7 | --map-column-java | 資料庫欄位在生成的Java檔案中會對映成各種屬性,且預設的資料型別與資料庫型別保持對應關係。該引數可以改變預設型別,例如:--map-column-java id=long, name=String |
8 | --null-non-string | 在生成Java檔案時,可以將不存在或者null的字串設定為其他值 |
9 | --null-string | 在生成Java檔案時,將null字串設定為其他值(一般與8同時使用) |
10 | --table | 對應關係資料庫中的表名,生成的Java檔案中的各個屬性與該表的各個欄位一一對應 |
5.2.8 命令&引數:create-hive-table
生成與關係資料庫表結構對應的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 |
Hive的安裝目錄,可以通過該引數覆蓋掉預設的Hive目錄 |
2 | --hive-overwrite | 覆蓋掉在Hive表中已經存在的資料 |
3 | --create-hive-table | 預設是false,如果目標表已經存在了,那麼建立任務會失敗 |
4 | --hive-table | 後面接要建立的hive表 |
5 | --table | 指定關係資料庫的表名 |
命令&引數:eval
可以快速的使用SQL語句對關係型資料庫進行操作,經常用於在import資料之前,瞭解一下SQL語句是否正確,資料是否正常,並可以將結果顯示在控制檯。
命令:
如:
bin/sqoop eval \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000 \
--query "SELECT * FROM staff"
引數:
序號 | 引數 | 說明 |
---|---|---|
1 | --query或--e | 後跟查詢的SQL語句 |
命令&引數:import-all-tables
可以將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
| 9 | -z或--compress | |
| 10 | --compression-codec | |
命令&引數:job
用來生成一個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引數 |
2 | --delete | 刪除一個job |
3 | --exec | 執行一個job |
4 | --help | 顯示job幫助 |
5 | --list | 顯示job列表 |
6 | --meta-connect | 用來連線metastore服務 |
7 | --show | 顯示一個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>
命令&引數:list-databases
命令:
如:
bin/sqoop list-databases \
--connect jdbc:mysql://hadoop102:3306/ \
--username root \
--password 000000
引數:與公用引數一樣
命令&引數:list-tables
命令:
如:
bin/sqoop list-tables \
--connect jdbc:mysql://hadoop102:3306/company \
--username root \
--password 000000
引數:與公用引數一樣
5.2.14 命令&引數:merge
將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
命令&引數:metastore
記錄了Sqoop job的元資料資訊,如果不啟動該服務,那麼預設job元資料的儲存目錄為~/.sqoop,可在sqoop-site.xml中修改。
命令:
如:啟動sqoop的metastore服務
bin/sqoop metastore
引數:
序號 | 引數 | 說明 |
---|---|---|
1 | --shutdown | 關閉metastore |