Sqoop能夠在HDFS/Hive和關係型數據庫之間進行數據的導入導出,其中主要使用了import和export這兩個工具。這兩個工具很是強大,提供了不少選項幫助咱們完成數據的遷移和同步。好比,下面兩個潛在的需求:html
- 業務數據存放在關係數據庫中,若是數據量達到必定規模後須要對其進行分析或同統計,單純使用關係數據庫可能會成爲瓶頸,這時能夠將數據從業務數據庫數據導入(import)到Hadoop平臺進行離線分析。
- 對大規模的數據在Hadoop平臺上進行分析之後,可能須要將結果同步到關係數據庫中做爲業務的輔助數據,這時候須要將Hadoop平臺分析後的數據導出(export)到關係數據庫。
這裏,咱們介紹Sqoop完成上述基本應用場景所使用的import和export工具,經過一些簡單的例子來講明這兩個工具是如何作到的。java
工具通用選項mysql
import和export工具備些通用的選項,以下表所示:sql
選項 |
含義說明 |
--connect <jdbc-uri> |
指定JDBC鏈接字符串 |
--connection-manager <class-name> |
指定要使用的鏈接管理器類 |
--driver <class-name> |
指定要使用的JDBC驅動類 |
--hadoop-mapred-home <dir> |
指定$HADOOP_MAPRED_HOME路徑 |
--help |
打印用法幫助信息 |
--password-file |
設置用於存放認證的密碼信息文件的路徑 |
-P |
從控制檯讀取輸入的密碼 |
--password <password> |
設置認證密碼 |
--username <username> |
設置認證用戶名 |
--verbose |
打印詳細的運行信息 |
--connection-param-file <filename> |
可選,指定存儲數據庫鏈接參數的屬性文件 |
數據導入工具import數據庫
import工具,是將HDFS平臺外部的結構化存儲系統中的數據導入到Hadoop平臺,便於後續分析。咱們先看一下import工具的基本選項及其含義,以下表所示:apache
選項 |
含義說明 |
--append |
將數據追加到HDFS上一個已存在的數據集上 |
--as-avrodatafile |
將數據導入到Avro數據文件 |
--as-sequencefile |
將數據導入到SequenceFile |
--as-textfile |
將數據導入到普通文本文件(默認) |
--boundary-query <statement> |
邊界查詢,用於建立分片(InputSplit) |
--columns <col,col,col…> |
從表中導出指定的一組列的數據 |
--delete-target-dir |
若是指定目錄存在,則先刪除掉 |
--direct |
使用直接導入模式(優化導入速度) |
--direct-split-size <n> |
分割輸入stream的字節大小(在直接導入模式下) |
--fetch-size <n> |
從數據庫中批量讀取記錄數 |
--inline-lob-limit <n> |
設置內聯的LOB對象的大小 |
-m,--num-mappers <n> |
使用n個map任務並行導入數據 |
-e,--query <statement> |
導入的查詢語句 |
--split-by <column-name> |
指定按照哪一個列去分割數據 |
--table <table-name> |
導入的源表表名 |
--target-dir <dir> |
導入HDFS的目標路徑 |
--warehouse-dir <dir> |
HDFS存放表的根路徑 |
--where <where clause> |
指定導出時所使用的查詢條件 |
-z,--compress |
啓用壓縮 |
--compression-codec <c> |
指定Hadoop的codec方式(默認gzip) |
--null-string <null-string> |
果指定列爲字符串類型,使用指定字符串替換值爲null的該類列的值 |
--null-non-string <null-string> |
若是指定列爲非字符串類型,使用指定字符串替換值爲null的該類列的值 |
下面,咱們經過實例來講明,在實際中如何使用這些選項。app
數據導出工具export
export工具,是將HDFS平臺的數據,導出到外部的結構化存儲系統中,可能會爲一些應用系統提供數據支持。咱們看一下export工具的基本選項及其含義,以下表所示:
選項 |
含義說明 |
--validate <class-name> |
啓用數據副本驗證功能,僅支持單表拷貝,能夠指定驗證使用的實現類 |
--validation-threshold <class-name> |
指定驗證門限所使用的類 |
--direct |
使用直接導出模式(優化速度) |
--export-dir <dir> |
導出過程當中HDFS源路徑 |
-m,--num-mappers <n> |
使用n個map任務並行導出 |
--table <table-name> |
導出的目的表名稱 |
--call <stored-proc-name> |
導出數據調用的指定存儲過程名 |
--update-key <col-name> |
更新參考的列名稱,多個列名使用逗號分隔 |
--update-mode <mode> |
指定更新策略,包括:updateonly(默認)、allowinsert |
--input-null-string <null-string> |
使用指定字符串,替換字符串類型值爲null的列 |
--input-null-non-string <null-string> |
使用指定字符串,替換非字符串類型值爲null的列 |
--staging-table <staging-table-name> |
在數據導出到數據庫以前,數據臨時存放的表名稱 |
--clear-staging-table |
清除工做區中臨時存放的數據 |
--batch |
使用批量模式導出 |
下面,咱們經過實例來講明,在實際中如何使用這些選項。這裏,咱們主要結合一個實例,講解如何將Hive中的數據導入到MySQL數據庫。
首先,咱們準備幾個表,MySQL數據庫爲tag_db,裏面有兩個表,定義以下所示:
01 |
CREATE TABLE tag_db.users ( |
02 |
id INT (11) NOT NULL AUTO_INCREMENT, |
03 |
name VARCHAR (100) NOT NULL , |
05 |
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
07 |
CREATE TABLE tag_db.tags ( |
08 |
id INT (11) NOT NULL AUTO_INCREMENT, |
10 |
tag VARCHAR (100) NOT NULL , |
12 |
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
這兩個表中存儲的是基礎數據,同時對應着Hive中以下兩個表:
咱們首先在上述MySQL的兩個表中插入一些測試數據:
1 |
INSERT INTO tag_db.users( name ) VALUES ( 'jeffery' ); |
2 |
INSERT INTO tag_db.users( name ) VALUES ( 'shirdrn' ); |
3 |
INSERT INTO tag_db.users( name ) VALUES ( 'sulee' ); |
5 |
INSERT INTO tag_db.tags(user_id, tag) VALUES (1, 'Music' ); |
6 |
INSERT INTO tag_db.tags(user_id, tag) VALUES (1, 'Programming' ); |
7 |
INSERT INTO tag_db.tags(user_id, tag) VALUES (2, 'Travel' ); |
8 |
INSERT INTO tag_db.tags(user_id, tag) VALUES (3, 'Sport' ); |
而後,使用Sqoop的import工具,將MySQL兩個表中的數據導入到Hive表,執行以下命令行:
導入成功之後,再在Hive中建立一個用來存儲users和tags關聯後數據的表:
1 |
CREATE TABLE user_tags ( |
執行以下HQL語句,將關聯數據插入user_tags表:
1 |
FROM users u JOIN tags t ON u.id=t.user_id INSERT INTO TABLE user_tags SELECT CONCAT( CAST (u.id AS STRING), CAST (t.id AS STRING)), u. name , t.tag; |
將users.id與tags.id拼接的字符串,做爲新表的惟一字段id,name是用戶名,tag是標籤名稱。
再在MySQL中建立一個對應的user_tags表,以下所示:
1 |
CREATE TABLE tag_db.user_tags ( |
2 |
id varchar (200) NOT NULL , |
3 |
name varchar (100) NOT NULL , |
4 |
tag varchar (100) NOT NULL |
使用Sqoop的export工具,將Hive表user_tags的數據同步到MySQL表tag_db.user_tags中,執行以下命令行:
1 |
bin/sqoop export --connect jdbc:mysql://10.95.3.49:3306/tag_db --username shirdrn --P --table user_tags -- export - dir /hive/user_tags --input-fields-terminated-by '\001' -- --default-character- set =utf-8 |
執行導出成功後,能夠在MySQL的tag_db.user_tags表中看到對應的數據。
若是在導出的時候出現相似以下的錯誤:
查看源代碼 打印幫助
01 |
14/02/27 17:59:06 INFO mapred.JobClient: Task Id : attempt_201402260008_0057_m_000001_0, Status : FAILED |
02 |
java.io.IOException: Can't export data, please check task tracker logs |
03 |
at org.apache.sqoop.mapreduce.TextExportMapper.map(TextExportMapper.java:112) |
04 |
at org.apache.sqoop.mapreduce.TextExportMapper.map(TextExportMapper.java:39) |
05 |
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145) |
06 |
at org.apache.sqoop.mapreduce.AutoProgressMapper.run(AutoProgressMapper.java:64) |
07 |
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764) |
08 |
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:364) |
09 |
at org.apache.hadoop.mapred.Child$4.run(Child.java:255) |
10 |
at java.security.AccessController.doPrivileged(Native Method) |
11 |
at javax.security.auth.Subject.doAs(Subject.java:396) |
12 |
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1190) |
13 |
at org.apache.hadoop.mapred.Child.main(Child.java:249) |
14 |
Caused by: java.util.NoSuchElementException |
15 |
at java.util.AbstractList$Itr.next(AbstractList.java:350) |
16 |
at user_tags.__loadFromFields(user_tags.java:225) |
17 |
at user_tags.parse(user_tags.java:174) |
18 |
at org.apache.sqoop.mapreduce.TextExportMapper.map(TextExportMapper.java:83) |
經過指定字段分隔符選項--input-fields-terminated-by
,指定Hive中表字段之間使用的分隔符,供Sqoop讀取解析,就不會報錯了。