大數據框架開發基礎之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+
    telecom-custome-service
全部導入
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"

sqoop-all-import
sqoop-all-import-result

查詢導入
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

sqoop-col-import
sqoop-col-import-result

刪選關鍵字導入
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"

sqoop-key-import
sqoop-key-import-result

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

sqoop-hive-import
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
6 --inline-lob-limit
7 --m或—num-mappers
8 --warehouse-dir
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 HDFS 待合並的數據目錄,合並后在新的數據集中保留
2 --onto HDFS合並后,重復的部分在新的數據集中被覆蓋
3 --merge-key
合並鍵,一般是主鍵ID
4 --jar-file 合並時引入的jar包,該jar包是通過Codegen工具生成的jar包
5 --class-name 對應的表名或對象名,該class類是包含在jar包中的
6 --target-dir 合並后的數據在HDFS里存放的目錄

命令&參數:metastore

記錄了Sqoop job的元數據信息,如果不啟動該服務,那么默認job元數據的存儲目錄為~/.sqoop,可在sqoop-site.xml中修改。

命令:

如:啟動sqoop的metastore服務

bin/sqoop metastore

參數:

序號 參數 說明
1 --shutdown 關閉metastore


免責聲明!

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



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