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 |
|
1201 |
2356742 |
|
1202 |
1661663 |
|
1203 |
8887776 |
|
1204 |
9988774 |
|
1205 |
1231231 |
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
如有侵權,聯繫刪除