Sqoop快速入門【導入數據到HDFS與導出數據到數據庫】

1、Sqoop概述

Sqoop - “SQL到Hadoop和Hadoop到SQL”
sqoop是apache旗下一款"Hadoop和關係數據庫服務器之間傳送數據"的工具。
導入數據:MySQL,Oracle導入數據到Hadoop的HDFS、HIVE、HBASE等數據存儲系統;
導出數據:從Hadoop的文件系統中導出數據到關係數據庫mysql等。

 

 

2、工作機制

將導入或導出命令翻譯成mapreduce程序來實現

在翻譯出的mapreduce中主要是對inputformat和outputformat進行定製

 

 

3、sqoop安裝

(1)安裝sqoop的前提是已經具備java和hadoop的環境

(2)下載並解壓sqoop

(3)修改配置文件

$ cd $SQOOP_HOME/conf
$ mv sqoop-env-template.sh sqoop-env.sh
打開sqoop-env.sh並編輯下面幾行:

export HADOOP_COMMON_HOME=/root/apps/hadoop-2.6.1/ 
export HADOOP_MAPRED_HOME=/root/apps/hadoop-2.6.1/
export HIVE_HOME=/root/apps/hive-1.2.1

(4)加入mysql的jdbc驅動包至$SQOOP_HOME/lib/下

(5)驗證啓動

$ cd $SQOOP_HOME/bin
$ sqoop-version

驗證sqoop到mysql業務庫之間的連通性:
bin/sqoop-list-databases --connect jdbc:mysql://localhost:3306 --username root --password root
bin/sqoop-list-tables --connect jdbc:mysql://localhost:3306/userdb --username root --password root

 

 

4、Sqoop的數據導入

“導入工具”導入單個表從RDBMS到HDFS。表中的每一行被視爲HDFS的記錄。所有記錄都存儲爲文本文件的文本數據(或者Avro、sequence文件等二進制數據)

 

下面的語法用於將數據導入HDFS
$ sqoop import (generic-args) (import-args)

讓我們舉一個名爲emp,emp_add和emp_contact的三個表的示例,這些表位於MySQL數據庫服務器中名爲userdb的數據庫中。

表數據

在mysql中有一個庫userdb中三個表:emp, emp_add和emp_conn

表emp:

id

name

deg

salary

dept

1201

gopal

manager

50,000

TP

1202

manisha

Proof reader

50,000

TP

1203

khalil

php dev

30,000

AC

1204

prasanth

php dev

30,000

AC

1205

kranthi

admin

20,000

TP

表emp_add:

id

hno

street

city

1201

288A

vgiri

jublee

1202

108I

aoc

sec-bad

1203

144Z

pgutta

hyd

1204

78B

old city

sec-bad

1205

720X

hitec

sec-bad

表emp_conn:

id

phno

email

1201

2356742

[email protected]

1202

1661663

[email protected]

1203

8887776

[email protected]

1204

9988774

[email protected]

1205

1231231

[email protected]

 

4.1    導入表數據到HDFS

下面的命令用於從MySQL數據庫服務器中的emp表導入HDFS

在導入表數據到HDFS使用Sqoop導入工具,我們可以指定目標目錄。

以下是指定目標目錄選項的Sqoop導入命令的語法。

--target-dir <new or exist directory in HDFS>

下面的命令是用來導入emp表數據到HDFS目錄下'/sqooptest'目錄。

bin/sqoop import \
--connect jdbc:mysql://hdp-01:3306/userdb \
--username root \
--password root \
--target-dir \
/sqooptest \
--fields-terminated-by ',' \
--table emp \
--split-by id \
--m 2

注意:如果報錯,說emp類找不到,則可以手動從sqoop生成的編譯目錄(/tmp/sqoop-root/compile)中,找到這個emp.class和emp.jar,拷貝到sqoop的lib目錄下,或修改$HADOOP_HOME/etc/hadoop/mapred-site.xml 修改爲yarn運行即可。

如果設置了 --m 1,則意味着只會啓動一個maptask執行數據導入
如果不設置 --m 1,則默認爲啓動4個map task執行數據導入,則需要指定一個列來作爲劃分map task任務的依據

驗證結果:

hadoop fs -cat /sqooptest/part-m-*

它向您顯示emp表數據和字段用逗號(,)分隔。

1201, gopal,    manager, 50000, TP
1202, manisha,  preader, 50000, TP
1203, kalil,    php dev, 30000, AC
1204, prasanth, php dev, 30000, AC
1205, kranthi,  admin,   20000, TP

 

4.2   導入關係表到HIVE

bin/sqoop import \
--connect "jdbc:mysql://hdp-01:3306/userdb?useUnicode=true&characterEncoding=utf-8" \
--username root \
--password root \
--hive-import \
--fields-terminated-by ',' \
--table emp \
--split-by id \
--m 2

實際上是與4.1相似,先將數據導入HDFS的臨時目錄,後調用hive元數據操作API接口,執行建表、將數據從臨時目錄導入到hive目錄的操作

 

4.3   導入表數據子集

我們可以導入表的使用Sqoop導入工具,"where"子句的一個子集。它執行在各自的數據庫服務器相應的SQL查詢,並將結果存儲在HDFS的目標目錄。

where子句的語法如下:

--where <condition>

下面的命令用來導入emp_add表數據的子集。子集查詢檢索員工ID和地址,居住城市爲:Secunderabad

bin/sqoop import \
--connect jdbc:mysql://hdp-01:3306/userdb \
--username root \
--password root \
--where "city ='sec-bad'" \
--target-dir /wherequery \
--table emp_add \
 --m 1

按需導入  --query

bin/sqoop import \
--connect jdbc:mysql://hdp-01:3306/userdb \
--username root \
--password root \
--target-dir /wherequery2 \
--query 'select id,name,deg from emp WHERE id>1207 and $CONDITIONS' \
--split-by id \
--fields-terminated-by '\t' \
--m 2

and $CONDITIONS務必需要加上,相當於and 1 = 1

下面的命令用來驗證數據從emp_add表導入/wherequery目錄

$HADOOP_HOME/bin/hadoop fs -cat /wherequery/part-m-*

它用逗號(,)分隔 emp_add表數據和字段。

1202, 108I, aoc, sec-bad
1204, 78B, oldcity, sec-bad
1205, 720C, hitech, sec-bad

 

4.4    增量導入

增量導入是僅導入新添加的表中的行的技術
sqoop支持兩種增量MySql導入到hive的模式
一種是append,即通過指定一個遞增的列,比如:

--incremental append  --check-column num_id --last-value 1000

只導入num_id字段大於1000的數據。 

另一種是可以根據時間戳,比如:

--incremental lastmodified --check-column created --last-value '2019-04-22 11:11:11' 

就是隻導入created 比'2019-04-22 11:11:11'更大的數據。

4.4.1    append模式
它需要添加'incremental', 'check-column', 和 'last-value'選項來執行增量導入。
下面的語法用於Sqoop導入命令增量選項

--incremental <mode>
--check-column <column name>
--last value <last check column value>

例子:   只導入id字段大於1208的數據,不包括1208

bin/sqoop import \
--connect jdbc:mysql://hdp-01:3306/userdb \
--target-dir /sqooptest \
--username root \
--password root \
--table emp --m 1 \
--incremental append \
--check-column id \
--last-value 1208

 

4.5    導入所有表格

如何將所有表從RDBMS數據庫服務器導入到HDFS。每個表格數據存儲在一個單獨的目錄中,並且目錄名稱與表格名稱相同。

語法

$ sqoop import-all-tables (generic-args) (import-args) 
$ sqoop-import-all-tables (generic-args) (import-args)

舉一個從userdb數據庫導入所有表的例子,數據庫userdb包含的表的列表如下所示:

+--------------------+
 |      Tables        |
 +--------------------+
 |      emp           |
 |      emp_add       |
 |      emp_contact   |
 +--------------------+

以下命令用於從userdb數據庫中導入所有表

$ sqoop import-all-tables \
--connect jdbc:mysql://localhost/userdb \
--username root

注 - 如果使用的是全部導入表,則該數據庫中的每個表都必須具有主鍵字段。
以下命令用於驗證HDFS中的所有表數據到userdb數據庫。

$ $HADOOP_HOME/bin/hadoop fs -ls

它將向您顯示userdb數據庫中的表名稱列表作爲目錄。

輸出:

drwxr-xr-x - hadoop supergroup 0 2014-12-22 22:50 _sqoop
drwxr-xr-x - hadoop supergroup 0 2014-12-23 01:46 emp
drwxr-xr-x - hadoop supergroup 0 2014-12-23 01:50 emp_add
drwxr-xr-x - hadoop supergroup 0 2014-12-23 01:52 emp_contact

 

 

5、Sqoop的數據導出

將數據從HDFS把文件導出到RDBMS數據庫
導出前,目標表必須存在於目標數據庫中
     輸入給Sqoop的文件包含記錄,這些記錄在表中稱爲行,這些被讀取並解析成一組記錄並用用戶指定的分隔符分隔。
     默認操作是從將文件中的數據使用INSERT語句插入到表中
     更新模式下,是生成UPDATE語句更新表數據

語法
以下是導出命令的語法

$ sqoop export (generic-args) (export-args) 
$ sqoop-export (generic-args) (export-args)

以HDFS中的文件中的員工數據爲例,僱員數據在HDFS的'emp /'目錄中的emp_data文件中可用,該emp_data如下:

1201, gopal,     manager, 50000, TP
1202, manisha,   preader, 50000, TP
1203, kalil,     php dev, 30000, AC
1204, prasanth,  php dev, 30000, AC
1205, kranthi,   admin,   20000, TP
1206, satish p,  grp des, 20000, GR

必須手動創建要導出的表,並將其導出到數據庫中。
1、首先需要手動創建mysql中的目標表

$ mysql
mysql> USE db;
mysql> CREATE TABLE employee ( 
   id INT NOT NULL PRIMARY KEY, 
   name VARCHAR(20), 
   deg VARCHAR(20),
   salary INT,
   dept VARCHAR(10));

2、然後執行導出命令

bin/sqoop export \
--connect jdbc:mysql://hdp-01:3306/userdb \
--username root \
--password root \
--table employee \
--input-fields-terminated-by ',' \
--export-dir /sqooptest/

3、驗證表mysql命令行

plus:HDFS中的數據仍然還在

 

 

6、Job

本章介紹如何創建和維護Sqoop作業。Sqoop作業創建並保存導入和導出命令,它指定參數來識別和調用保存的作業。這種重新調用或重新執行用於增量導入,它可以將更新的行從RDBMS表導入HDFS。

語法
以下是創建Sqoop作業的語法

$ sqoop job (generic-args) (job-args)
   [-- [subtool-name] (subtool-args)]
$ sqoop-job (generic-args) (job-args)
   [-- [subtool-name] (subtool-args)]

創建作業(--create)
我們在這裏創建一個名爲myjob的作業,它可以將表數據從RDBMS表導入HDFS。以下命令用於創建將數據從db數據庫中的employee表導入到HDFS文件的作業。

$ sqoop job --create myjob \
-- import \
--connect jdbc:mysql://localhost/db \
--username root \
--table employee --m 1

驗證作業(--list)
'--list'參數用於驗證保存的作業。以下命令用於驗證保存的Sqoop作業列表。

$ sqoop job --list

它顯示保存的作業列表

Available jobs: 
   myjob

檢查作業( --顯示)
'--show'參數用於檢查或驗證特定作業及其細節。以下命令和示例輸出用於驗證名爲myjob的作業。

$ sqoop job --show myjob

它顯示了myjob中使用的工具及其選項。

Job: myjob 
 Tool: import Options:
 ---------------------------- 
 direct.import = true
 codegen.input.delimiters.record = 0
 hdfs.append.dir = false 
 db.table = employee
 ...
 incremental.last.value = 1206
 ...

執行作業(--exec)
'--exec'選項用於執行保存的作業。以下命令用於執行名爲myjob的保存作業。

$ sqoop job --exec myjob

顯示以下輸出。

10/08/19 13:08:45 INFO tool.CodeGenTool: Beginning code generation 
...

 


7、Codegen

本章介紹'codegen'工具的重要性。從面向對象的應用程序的角度來看,每個數據庫表都有一個dao類,它包含用於初始化對象的'getter'和'setter'方法。該工具(-codegen)自動生成dao類。

它根據表模式結構在Java中生成dao類。Java定義被實例化爲導入過程的一部分。這個工具的主要用途是檢查Java是否丟失了Java代碼。如果是這樣,它將使用字段之間的默認分隔符創建Java的新版本。

語法
以下是Sqoop codegen命令的語法。

$ sqoop codegen (generic-args) (codegen-args) 
$ sqoop-codegen (generic-args) (codegen-args)


讓我們舉一個例子來爲userdb數據庫中的emp表生成Java代碼。

以下命令用於執行給定示例。

$ sqoop codegen \
--connect jdbc:mysql://localhost/userdb \
--username root \ 
--table emp

如果該命令執行成功,則它將在終端上產生以下輸出。

14/12/23 02:34:40 INFO sqoop.Sqoop: Running Sqoop version: 1.4.5
14/12/23 02:34:41 INFO tool.CodeGenTool: Beginning code generation
……………….
14/12/23 02:34:42 INFO orm.CompilationManager: HADOOP_MAPRED_HOME is /usr/local/hadoop
Note: /tmp/sqoop-hadoop/compile/9a300a1f94899df4a9b10f9935ed9f91/emp.java uses or 
   overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

14/12/23 02:34:47 INFO orm.CompilationManager: Writing jar file: 
   /tmp/sqoop-hadoop/compile/9a300a1f94899df4a9b10f9935ed9f91/emp.jar

驗證
讓我們看看輸出。該粗體路徑是emp表生成和存儲的Java代碼的位置。讓我們使用以下命令來驗證該位置中的文件。

$ cd /tmp/sqoop-hadoop/compile/9a300a1f94899df4a9b10f9935ed9f91/
$ ls
emp.class
emp.jar
emp.java

如果要深入驗證,請比較userdb數據庫中的emp表和/tmp/sqoop-hadoop/compile/9a300a1f94899df4a9b10f9935ed9f91/.目錄中的emp.java。

 

 

8、Eval

本章介紹如何使用Sqoop'eval'工具。它允許用戶針對各自的數據庫服務器執行用戶定義的查詢,並在控制檯中預覽結果。所以,用戶可以期望導入結果表數據。使用eval,我們可以評估任何類型的可以是DDL或DML語句的SQL查詢。

語法
以下語法用於Sqoop eval命令。

$ sqoop eval (generic-args) (eval-args) 
$ sqoop-eval (generic-args) (eval-args)

選擇查詢評估
使用eval工具,我們可以評估任何類型的SQL查詢。讓我們舉一個在db數據庫的employee表中選擇有限行的例子。以下命令用於評估使用SQL查詢的給定示例。

$ sqoop eval \
--connect jdbc:mysql://localhost/db \
--username root \ 
--query “SELECT * FROM employee LIMIT 3”

如果該命令執行成功,則它將在終端上產生以下輸出。

+------+--------------+-------------+-------------------+--------+
| Id   | Name         | Designation | Salary            | Dept   |
+------+--------------+-------------+-------------------+--------+
| 1201 | gopal        | manager     | 50000             | TP     |
| 1202 | manisha      | preader     | 50000             | TP     |
| 1203 | khalil       | php dev     | 30000             | AC     |
+------+--------------+-------------+-------------------+--------+
插入查詢評估
Sqoop評估工具可適用於建模和定義SQL語句。這意味着,我們也可以使用eval來插入語句。以下命令用於在db數據庫的employee表中插入新行。

$ sqoop eval \
--connect jdbc:mysql://localhost/db \
--username root \ 
-e “INSERT INTO employee VALUES(1207,‘Raju’,‘UI dev’,15000,‘TP’)”

如果該命令成功執行,則會在控制檯上顯示更新行的狀態。

否則,您可以在MySQL控制檯上驗證僱員表。以下命令用於使用select'query來驗證db數據庫的employee表的行。

mysql>
mysql> use db;
mysql> SELECT * FROM employee;
+------+--------------+-------------+-------------------+--------+
| Id   | Name         | Designation | Salary            | Dept   |
+------+--------------+-------------+-------------------+--------+
| 1201 | gopal        | manager     | 50000             | TP     |
| 1202 | manisha      | preader     | 50000             | TP     |
| 1203 | khalil       | php dev     | 30000             | AC     |
| 1204 | prasanth     | php dev     | 30000             | AC     |
| 1205 | kranthi      | admin       | 20000             | TP     |
| 1206 | satish p     | grp des     | 20000             | GR     |
| 1207 | Raju         | UI dev      | 15000             | TP     |
+------+--------------+-------------+-------------------+--------+

 

 


部分內容參考博客:

https://blog.csdn.net/ancony_/article/details/80012908

如有侵權,聯繫刪除

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章