sqoop学习
?Sqoop 是傳統(tǒng)數(shù)據(jù)庫與 Hadoop 之間數(shù)據(jù)同步的工具,它是 Hadoop 發(fā)展到一定程度的必然產(chǎn)物,它主要解決的是傳統(tǒng)數(shù)據(jù)庫和Hadoop之間數(shù)據(jù)的遷移問題。這節(jié)課我們將詳細介紹 Sqoop 這個工具。
Sqoop 產(chǎn)生背景
????????Sqoop 的產(chǎn)生主要源于以下幾種需求:
????????1、多數(shù)使用 Hadoop 技術(shù)處理大數(shù)據(jù)業(yè)務(wù)的企業(yè),有大量的數(shù)據(jù)存儲在傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(RDBMS)中。
????????2、由于缺乏工具的支持,對 Hadoop 和 傳統(tǒng)數(shù)據(jù)庫系統(tǒng)中的數(shù)據(jù)進行相互傳輸是一件十分困難的事情。
????????3、基于前兩個方面的考慮,亟需一個在 RDBMS 與 Hadoop 之間進行數(shù)據(jù)傳輸?shù)捻椖俊?/span>
Sqoop 是什么
????????Sqoop 是連接傳統(tǒng)關(guān)系型數(shù)據(jù)庫和 Hadoop 的橋梁。它包括以下兩個方面:
????????1、 將關(guān)系型數(shù)據(jù)庫的數(shù)據(jù)導(dǎo)入到 Hadoop 及其相關(guān)的系統(tǒng)中,如 Hive和HBase。
????????2、 將數(shù)據(jù)從 Hadoop 系統(tǒng)里抽取并導(dǎo)出到關(guān)系型數(shù)據(jù)庫。
????????Sqoop 的核心設(shè)計思想是利用 MapReduce 加快數(shù)據(jù)傳輸速度。也就是說 Sqoop 的導(dǎo)入和導(dǎo)出功能是通過 MapReduce 作業(yè)實現(xiàn)的。所以它是一種批處理方式進行數(shù)據(jù)傳輸,難以實現(xiàn)實時的數(shù)據(jù)進行導(dǎo)入和導(dǎo)出。
為什么選擇 Sqoop
????????我們?yōu)槭裁催x擇 Sqoop 呢?通常基于三個方面的考慮:
????????1、它可以高效、可控地利用資源,可以通過調(diào)整任務(wù)數(shù)來控制任務(wù)的并發(fā)度。另外它還可以配置數(shù)據(jù)庫的訪問時間等等。
????????2、它可以自動的完成數(shù)據(jù)類型映射與轉(zhuǎn)換。我們往往導(dǎo)入的數(shù)據(jù)是有類型的,它可以自動根據(jù)數(shù)據(jù)庫中的類型轉(zhuǎn)換到 Hadoop 中,當(dāng)然用戶也可以自定義它們之間的映射關(guān)系。
????????3、它支持多種數(shù)據(jù)庫,比如,Mysql、Oracle和PostgreSQL等等數(shù)據(jù)庫。
Sqoop 安裝
????????我們 Hadoop 集群安裝的是 Hadoop2.2.0 版本,所以 Sqoop 安裝版本也要與之相匹配,否則后面 Sqoop 工具的使用會出現(xiàn)問題。這里我們選擇?sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz版本安裝。 安裝 Sqoop 很簡單,分為以下幾步完成。
????????1、首先將下載的 sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz放到 /usr/java/目錄下,然后對安裝包解壓、修改文件名和修改用戶權(quán)限。
[root@single-hadoop-dajiangtai-com?java]#?tar?zxvf?sqoop-1.4.6.bin__hadoop-1.0.0.tar.gz?//解壓[root@single-hadoop-dajiangtai-com?java]#?rm?sqoop-1.4.6.bin__hadoop-1.0.0.tar.gz?//刪除安裝包
[root@single-hadoop-dajiangtai-com?java]#?mv?sqoop-1.4.6.bin__hadoop-1.0.0?sqoop?//修改安裝文件目錄
[root@single-hadoop-dajiangtai-com?java]#?chown?-R?hadoop:hadoop?sqoop?//賦予sqoop?hadoop用戶權(quán)限
????????2、切換到/sqoop/conf 目錄下,執(zhí)行以下命令。
[hadoop@single-hadoop-dajiangtai-com?java]$?cd?sqoop/conf[hadoop@single-hadoop-dajiangtai-com?java]$?mv?sqoop-env-template.sh?sqoop-env.sh
????????然后使用 vi sqoop-env.sh 命令,打開文件添加如下內(nèi)容。
#Set?path?to?where?bin/hadoop?is?availableexport?HADOOP_COMMON_HOME=/usr/java/hadoop-2.2.0-x64
#Set?path?to?where?hadoop-*-core.jar?is?available
export?HADOOP_MAPRED_HOME=/usr/java/hadoop-2.2.0-x64
#set?the?path?to?where?bin/hbase?is?available
#export?HBASE_HOME=
#Set?the?path?to?where?bin/hive?is?available
export?HIVE_HOME=/usr/java/hive-1.0.0
#Set?the?path?for?where?zookeper?config?dir?is
#export?ZOOCFGDIR=
????????如果數(shù)據(jù)讀取不涉及hbase和hive,那么相關(guān)hbase和hive的配置可以不加;如果集群有獨立的zookeeper集群,那么配置zookeeper,反之,不用配置。
????????3、將相關(guān)的驅(qū)動 jar 包拷貝到 sqoop/lib 目錄下。安裝 Hadoop2.2.0 的核心 jar包有三個需要導(dǎo)入:commons-cli-1.2.jar、hadoop-common-2.2.0.jar和hadoop-mapreduce-client-core-2.2.0.jar。 數(shù)據(jù)庫驅(qū)動 jar 包需要導(dǎo)入,這里我們使用的是 mysql 數(shù)據(jù)庫,所以需要導(dǎo)入mysql-connector-java-5.1.21.jar包。
[hadoop@single-hadoop-dajiangtai-com?lib]$?cp?commons-cli-1.2.jar?/usr/java/sqoop/lib[hadoop@single-hadoop-dajiangtai-com?common]$?cp?hadoop-common-2.2.0.jar?/usr/java/sqoop/lib
[hadoop@single-hadoop-dajiangtai-com?mapreduce]$?cp?hadoop-mapreduce-client-core-2.2.0.jar?/usr/java/sqoop/lib
[hadoop@single-hadoop-dajiangtai-com?java]$?cp?mysql-connector-java-5.1.21.jar?/usr/java/sqoop/lib
????????4、添加環(huán)境變量。
[hadoop@single-hadoop-dajiangtai-com?java]$?vi?~/.bash_profilePATH=$PATH:$HOME/bin
export?SQOOP_HOME=/usr/java/sqoop?//sqoop安裝目錄
export?PATH=$PATH:$SQOOP_HOME/bin
????????環(huán)境添加完畢后,執(zhí)行以下命令使環(huán)境生效。
[hadoop@single-hadoop-dajiangtai-com?java]$?source?~/.bash_profile????????5、測試運行
[hadoop@single-hadoop-dajiangtai-com?java]$?sqoop?list-databases?\>?--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
>?--username?sqoop?\
>?--password?sqoop
15/06/03?02:47:27?INFO?sqoop.Sqoop:?Running?Sqoop?version:?1.4.6
15/06/03?02:47:27?WARN?tool.BaseSqoopTool:?Setting?your?password?on?the?command-line?is?insecure.?Consider?using?-P?instead.
15/06/03?02:47:28?INFO?manager.MySQLManager:?Preparing?to?use?a?MySQL?streaming?resultset.
information_schema
djtdb_demo
djtdb_hadoop
djtdb_www
????????sqoop 命令執(zhí)行成功,代表安裝成功。
Sqoop 架構(gòu)
????????Sqoop 架構(gòu)是非常簡單的,它主要由三個部分組成:Sqoop client、HDFS/HBase/Hive、Database。下面我們來看一下 Sqoop 的架構(gòu)圖。
????????用戶向 Sqoop 發(fā)起一個命令之后,這個命令會轉(zhuǎn)換為一個基于 Map Task 的 MapReduce 作業(yè)。Map Task 會訪問數(shù)據(jù)庫的元數(shù)據(jù)信息,通過并行的 Map Task 將數(shù)據(jù)庫的數(shù)據(jù)讀取出來,然后導(dǎo)入 Hadoop 中。 當(dāng)然也可以將 Hadoop 中的數(shù)據(jù),導(dǎo)入傳統(tǒng)的關(guān)系型數(shù)據(jù)庫中。它的核心思想就是通過基于 Map Task (只有 map)的 MapReduce 作業(yè),實現(xiàn)數(shù)據(jù)的并發(fā)拷貝和傳輸,這樣可以大大提高效率。
Sqoop與HDFS結(jié)合
????????下面我們結(jié)合 HDFS,介紹 Sqoop 從關(guān)系型數(shù)據(jù)庫的導(dǎo)入和導(dǎo)出。
Sqoop import
????????它的功能是將數(shù)據(jù)從關(guān)系型數(shù)據(jù)庫導(dǎo)入 HDFS 中,其流程圖如下所示。
????????我們來分析一下 Sqoop 數(shù)據(jù)導(dǎo)入流程,首先用戶輸入一個 Sqoop import 命令,Sqoop 會從關(guān)系型數(shù)據(jù)庫中獲取元數(shù)據(jù)信息,比如要操作數(shù)據(jù)庫表的 schema是什么樣子,這個表有哪些字段,這些字段都是什么數(shù)據(jù)類型等。它獲取這些信息之后,會將輸入命令轉(zhuǎn)化為基于 Map 的 MapReduce作業(yè)。這樣 MapReduce作業(yè)中有很多 Map 任務(wù),每個 Map 任務(wù)從數(shù)據(jù)庫中讀取一片數(shù)據(jù),這樣多個 Map 任務(wù)實現(xiàn)并發(fā)的拷貝,把整個數(shù)據(jù)快速的拷貝到 HDFS 上。
????????下面我們看一下 Sqoop 如何使用命令行來導(dǎo)入數(shù)據(jù)的,其命令行語法如下所示。
sqoop?import?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--password?sqoop?\
--table?user?\
--target-dir?/junior/sqoop/?\ //可選,不指定目錄,數(shù)據(jù)默認導(dǎo)入到/user下
--where?"sex='female'"?\ //可選
--as-sequencefile?\ //可選,不指定格式,數(shù)據(jù)格式默認為?Text?文本格式
--num-mappers?10?\ //可選,這個數(shù)值不宜太大
--null-string?'\\N'?\ //可選?
--null-non-string?'\\N'?\ //可選
????????--connect:指定 JDBC URL。
????????--username/password:mysql 數(shù)據(jù)庫的用戶名。
????????--table:要讀取的數(shù)據(jù)庫表。
????????--target-dir:將數(shù)據(jù)導(dǎo)入到指定的 HDFS 目錄下,文件名稱如果不指定的話,會默認數(shù)據(jù)庫的表名稱。
????????--where:過濾從數(shù)據(jù)庫中要導(dǎo)入的數(shù)據(jù)。
????????--as-sequencefile:指定數(shù)據(jù)導(dǎo)入數(shù)據(jù)格式。
????????--num-mappers:指定 Map 任務(wù)的并發(fā)度。
????????--null-string,--null-non-string:同時使用可以將數(shù)據(jù)庫中的空字段轉(zhuǎn)化為'\N',因為數(shù)據(jù)庫中字段為 null,會占用很大的空間。
????????下面我們介紹幾種 Sqoop 數(shù)據(jù)導(dǎo)入的特殊應(yīng)用。
????????1、Sqoop 每次導(dǎo)入數(shù)據(jù)的時候,不需要把以往的所有數(shù)據(jù)重新導(dǎo)入 HDFS,只需要把新增的數(shù)據(jù)導(dǎo)入 HDFS 即可,下面我們來看看如何導(dǎo)入新增數(shù)據(jù)。
sqoop?import?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--password?sqoop?\
--table?user?\
--incremental?append?\ //代表只導(dǎo)入增量數(shù)據(jù)
--check-column?id?\ //以主鍵id作為判斷條件
--last-value?999 //導(dǎo)入id大于999的新增數(shù)據(jù)
????????上述三個組合使用,可以實現(xiàn)數(shù)據(jù)的增量導(dǎo)入。
????????2、Sqoop 數(shù)據(jù)導(dǎo)入過程中,直接輸入明碼存在安全隱患,我們可以通過下面兩種方式規(guī)避這種風(fēng)險。
????????1)-P:sqoop 命令行最后使用 -P,此時提示用戶輸入密碼,而且用戶輸入的密碼是看不見的,起到安全保護作用。密碼輸入正確后,才會執(zhí)行 sqoop 命令。
sqoop?import?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--table?user?\
-P
????????2)--password-file:指定一個密碼保存文件,讀取密碼。我們可以將這個文件設(shè)置為只有自己可讀的文件,防止密碼泄露。
sqoop?import?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--table?user?\
--password-file?my-sqoop-password
Sqoop export
????????它的功能是將數(shù)據(jù)從 HDFS 導(dǎo)入關(guān)系型數(shù)據(jù)庫表中,其流程圖如下所示。
????????我們來分析一下 Sqoop 數(shù)據(jù)導(dǎo)出流程,首先用戶輸入一個 Sqoop export 命令,它會獲取關(guān)系型數(shù)據(jù)庫的 schema,建立 Hadoop 字段與數(shù)據(jù)庫表字段的映射關(guān)系。 然后會將輸入命令轉(zhuǎn)化為基于 Map 的 MapReduce作業(yè),這樣 MapReduce作業(yè)中有很多 Map 任務(wù),它們并行的從 HDFS 讀取數(shù)據(jù),并將整個數(shù)據(jù)拷貝到數(shù)據(jù)庫中。
????????下面我們看一下 Sqoop 如何使用命令行來導(dǎo)出數(shù)據(jù)的,其命令行語法如下所示。
sqoop?export?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--password?sqoop?\
--table?user?\
--export-dir?user
????????--connect:指定 JDBC URL。
????????--username/password:mysql 數(shù)據(jù)庫的用戶名和密碼。
????????--table:要導(dǎo)入的數(shù)據(jù)庫表。
????????--export-dir:數(shù)據(jù)在 HDFS 上的存放目錄。
????????下面我們介紹幾種 Sqoop 數(shù)據(jù)導(dǎo)出的特殊應(yīng)用。
????????1、Sqoop export 將數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫,一般情況下是一條一條導(dǎo)入的,這樣導(dǎo)入的效率非常低。這時我們可以使用 Sqoop export 的批量導(dǎo)入提高效率,其具體語法如下。
sqoop?export?\--Dsqoop.export.records.per.statement=10?\
--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--password?sqoop?\
--table?user?\
--export-dir?user?\
--batch
????????--Dsqoop.export.records.per.statement:指定每次導(dǎo)入10條數(shù)據(jù),--batch:指定是批量導(dǎo)入。
????????2、在實際應(yīng)用中還存在這樣一個問題,比如導(dǎo)入數(shù)據(jù)的時候,Map Task 執(zhí)行失敗, 那么該 Map 任務(wù)會轉(zhuǎn)移到另外一個節(jié)點執(zhí)行重新運行,這時候之前導(dǎo)入的數(shù)據(jù)又要重新導(dǎo)入一份,造成數(shù)據(jù)重復(fù)導(dǎo)入。 因為 Map Task 沒有回滾策略,一旦運行失敗,已經(jīng)導(dǎo)入數(shù)據(jù)庫中的數(shù)據(jù)就無法恢復(fù)。Sqoop export 提供了一種機制能保證原子性, 使用--staging-table 選項指定臨時導(dǎo)入的表。Sqoop export 導(dǎo)出數(shù)據(jù)的時候會分為兩步:第一步,將數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫中的臨時表,如果導(dǎo)入期間 Map Task 失敗,會刪除臨時表數(shù)據(jù)重新導(dǎo)入;第二步,確認所有 Map Task 任務(wù)成功后,會將臨時表名稱為指定的表名稱。
sqoop?export?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--password?sqoop?\
--table?user?\
--staging-table?staging_user
????????3、在 Sqoop 導(dǎo)出數(shù)據(jù)過程中,如果我們想更新已有數(shù)據(jù),可以采取以下兩種方式。
????????1)通過 --update-key id 更新已有數(shù)據(jù)。
sqoop?export?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--password?sqoop?\
--table?user?\
--update-key?id
????????2)使用 --update-key id和--update-mode allowinsert 兩個選項的情況下,如果數(shù)據(jù)已經(jīng)存在,則更新數(shù)據(jù),如果數(shù)據(jù)不存在,則插入新數(shù)據(jù)記錄。
sqoop?export?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--password?sqoop?\
--table?user?\
--update-key?id?\
--update-mode?allowinsert
????????4、如果 HDFS 中的數(shù)據(jù)量比較大,很多字段并不需要,我們可以使用 --columns 來指定插入某幾列數(shù)據(jù)。
sqoop?export?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--password?sqoop?\
--table?user?\
--column?username,sex
????????5、當(dāng)導(dǎo)入的字段數(shù)據(jù)不存在或者為null的時候,我們使用--input-null-string和--input-null-non-string 來處理。
sqoop?export?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--password?sqoop?\
--table?user?\
--input-null-string?'\\N'?\
--input-null-non-string?'\\N'
Sqoop與其它系統(tǒng)結(jié)合
????????Sqoop 也可以與Hive、HBase等系統(tǒng)結(jié)合,實現(xiàn)數(shù)據(jù)的導(dǎo)入和導(dǎo)出,用戶需要在 sqoop-env.sh 中添加HBASE_HOME、HIVE_HOME等環(huán)境變量。
????????1、Sqoop與Hive結(jié)合比較簡單,使用 --hive-import 選項就可以實現(xiàn)。
sqoop?import?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--password?sqoop?\
--table?user?\
--hive-import
????????2、Sqoop與HBase結(jié)合稍微麻煩一些,需要使用 --hbase-table 指定表名稱,使用 --column-family 指定列名稱。
sqoop?import?\--connect?jdbc:mysql://db.dajiangtai.net:3306/djtdb_hadoop?\
--username?sqoop?\
--password?sqoop?\
--table?user?\
--hbase-table?user?\
--column-family?city
轉(zhuǎn)載于:https://blog.51cto.com/gldbhome/1768390
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
- 上一篇: Node.js使用npm下载第三方模块包
- 下一篇: nlp中的经典深度学习模型(一)