Hadoop學習筆記—18.Sqoop框架學習
一、Sqoop基礎:連接關系型數據庫與Hadoop的橋梁
1.1 Sqoop的基本概念
Hadoop正成為企業用於大數據分析的最熱門選擇,但想將你的數據移植過去並不容易。Apache Sqoop正在加緊幫助客戶將重要數據從數據庫移到Hadoop。隨著Hadoop和關系型數據庫之間的數據移動漸漸變成一個標準的流程,雲管理員們能夠利用Sqoop的並行批量數據加載能力來簡化這一流程,降低編寫自定義數據加載腳本的需求。
Apache Sqoop(SQL-to-Hadoop) 項目旨在協助 RDBMS 與 Hadoop 之間進行高效的大數據交流。用戶可以在 Sqoop 的幫助下,輕松地把關系型數據庫的數據導入到 Hadoop 與其相關的系統 (如HBase和Hive)中;同時也可以把數據從 Hadoop 系統裏抽取並導出到關系型數據庫裏。因此,可以說Sqoop就是一個橋梁,連接了關系型數據庫與Hadoop。
1.2 Sqoop的基本機制
Sqoop中一大亮點就是可以通過hadoop的mapreduce把數據從關系型數據庫中導入數據到HDFS。Sqoop架構非常簡單,其整合了Hive、Hbase和Oozie,通過map-reduce任務來傳輸數據,從而提供並發特性和容錯。Sqoop的基本工作流程如下圖所示:
Sqoop在import時,需要制定split-by參數。Sqoop根據不同的split-by參數值來進行切分,然後將切分出來的區域分配到不同map中。每個map中再處理數據庫中獲取的一行一行的值,寫入到HDFS中(由此也可知,導入導出的事務是以Mapper任務為單位)。同時split-by根據不同的參數類型有不同的切分方法,如比較簡單的int型,Sqoop會取最大和最小split-by字段值,然後根據傳入的num-mappers來確定劃分幾個區域。 比如select max(split_by),min(split-by) from得到的max(split-by)和min(split-by)分別為1000和1,而num-mappers為2的話,則會分成兩個區域(1,500)和(501-100),同時也會分成2個sql給2個map去進行導入操作,分別為select XXX from table where split-by>=1 and split-by<500和select XXX from table where split-by>=501 and split-by<=1000。最後每個map各自獲取各自SQL中的數據進行導入工作。
二、Sqoop實踐:MySQL->HDFS/HDFS->MySQL
2.1 Sqoop的安裝配置
(1)下載sqoop安裝包:這裏使用的是1.4.3版本,已經上傳至網盤中(http://pan.baidu.com/s/1pJ7gfxh)
(2)解壓sqoop安裝包:tar -zvxf sqoop-1.4.3.bin__hadoop-1.0.0.tar.gz
(3)設置環境變量:vim /etc/profile ,增加以下內容
export SQOOP_HOME=/usr/local/sqoop
export PATH=.:$HADOOP_HOME/bin:$SQOOP_HOME/bin:$HIVE_HOME/bin:$PIG_HOME/bin:$HBASE_HOME/bin:$ZOOKEEPER_HOME/bin:$JAVA_HOME/bin:$PATH
最後是環境變量生效:source /etc/profile
(4)將mysql的jdbc驅動mysql-connector-java-5.1.10.jar復制到sqoop項目的lib目錄下:
cp mysql-connector-java-5.1.10.jar /usr/local/sqoop/lib
(5)重命名配置文件:在${SQOOP_HOME}/conf中執行命令
mv sqoop-env-template.sh sqoop-env.sh
(6)【可選】修改配置文件:vim sqoop-env.sh
#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/usr/local/hadoop/
#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/usr/local/hadoop
#set the path to where bin/hbase is available export
HBASE_HOME=/usr/local/hbase
#Set the path to where bin/hive is available
export HIVE_HOME=/usr/local/hive
#Set the path for where zookeper config dir is
export ZOOCFGDIR=/usr/local/zookeeper
2.2 數據導入:MySQL->HDFS
這裏假設我們已經在hadoop-master服務器中安裝了MySQL數據庫服務,並使用默認端口3306。需要註意的是,sqoop的數據庫驅動driver默認只支持mysql和oracle,如果使用sqlserver的話,需要把sqlserver的驅動jar包放在sqoop的lib目錄下,然後才能使用drive參數。
(1)MySQL數據源:mysql中的hive數據庫的TBLS表,這裏使用學習筆記17《Hive框架學習》裏邊Hive的數據庫表。
(2)使用import命令將mysql中的數據導入HDFS:
首先看看import命令的基本格式:
sqoop ##sqoop命令
import ##表示導入
--connect jdbc:mysql://ip:3306/sqoop ##告訴jdbc,連接mysql的url
--username root ##連接mysql的用戶名
--password admin ##連接mysql的密碼
--table mysql1 ##從mysql導出的表名稱
--fields-terminated-by ‘\t‘ ##指定輸出文件中的行的字段分隔符
-m 1 ##復制過程使用1個map作業
--hive-import ##把mysql表數據復制到hive空間中。如果不使用該選項,意味著復制到hdfs中
然後看看如何進行實戰:這裏將mysql中的TBLS表導入到hdfs中(默認導入目錄是/user/<username>)
sqoop import --connect jdbc:mysql://hadoop-master:3306/hive --username root --password admin --table TBLS --fields-terminated-by ‘\t‘
最後看看是否成功導入了HDFS中:可以看到TBLS表存入了多個map任務所生成的文件中
(3)剛剛看到了默認是由多個map來進行處理生成,可以設置指定數量的map任務。又由於sqoop默認不是追加方式寫入,還可以設置其為追加方式寫入已有文件末尾:
sqoop import --connect jdbc:mysql://hadoop0:3306/hive --username root --password admin --table TBLS --fields-terminated-by ‘\t‘ --null-string ‘**‘ -m 1 --append
(4)還可以將MySQL中的數據導入Hive中(你設定的hive在hdfs中的存儲位置,我這裏是/hive/):
首先得刪掉剛剛導入到hdfs中的文件數據:
hadoop fs -rmr /user/root/*
然後再通過以下命令導入到hive中:
sqoop import --connect jdbc:mysql://hadoop-master:3306/hive --username root --password admin --table TBLS --fields-terminated-by ‘\t‘ -m 1 --append --hive-import
最後看看是否導入到了hive目錄(/hive/)中:
(5)還可以對指定數據源進行增量導入:所謂增量打入,就是導入上一次導入後數據源新增的那部分數據,例如:上次導入的數據是id從1~100的數據,那麽這次就只導入100以後新增的數據,而不必整體導入,節省了導入時間。下面的命令以TBL_ID字段作為判斷標準采用增量導入,並記錄上一次的最後一個記錄是6,只導入6以後的數據即可。
sqoop import --connect jdbc:mysql://hadoop0:3306/hive --username root --password admin --table TBLS --fields-terminated-by ‘\t‘ --null-string ‘**‘ -m 1 --append --hive-import --check-column ‘TBL_ID‘ --incremental append --last-value 6
2.3 數據導出:HDFS->MySQL
(1)既然要導出到MySQL,那麽首先得要有一張接收從HDFS導出數據的表。這裏為了示範,只創建一個最簡單的數據表TEST_IDS,只有一個int類型的ID字段。
(2)使用export命令進行將數據從HDFS導出到MySQL中,可以看看export命令的基本格式:
sqoop
export ##表示數據從hive復制到mysql中
--connect jdbc:mysql://ip:3306/sqoop ##告訴jdbc,連接mysql的url
--username root ##連接mysql的用戶名
--password admin ##連接mysql的密碼
--table mysql2 ##mysql中的表,即將被導入的表名稱
--export-dir ‘/user/root/warehouse/mysql1‘ ##hive中被導出的文件目錄
--fields-terminated-by ‘\t‘ ##hive中被導出的文件字段的分隔符
註意:導出的數據表必須是事先存在的
(3)準備一個符合數據表規範的文件ids並上傳到HDFS中,作為導出到MySQL的數據源:這個ids裏邊只有10個數字
1 2 3 4 5 6 7 8 9 10
(4)export實戰:將HDFS中的ids導出到mysql中的TEST_IDS數據表中
sqoop export --connect jdbc:mysql://hadoop-master:3306/hive --username root --password admin --table TEST_IDS --fields-terminated-by ‘\t‘ --export-dir ‘/testdir/input/ids‘
最後查看是否導入到了mysql中的TEST_IDS數據表中:
2.4 創建job,運行job
剛剛我們使用了import和export命令進行了常規的導入導出操作,但是每次都要我們使用那麽長的命令不太容易記憶。於是,我們可以將其創建為一個job,每次需要使用時只需要記住job名,運行job即可。
這裏以導入為例,創建一個job名為myjob1的job:
sqoop job --create myjob1 -- import --connect jdbc:mysql://hadoop-master:3306/hive --username root --password admin --table TBLS --fields-terminated-by ‘\t‘ -m 1 --append
可以通過命令查看是否存在job:sqoop job --list
執行剛剛創建的job:
sqoop job --exec myjob1
但是,我們發現上面的設置後還需要我們輸入密碼,這樣便無法做到真正的自動執行job。
於是,我們做一點小小的配置(hive-site.xml)修改:將下面的xml配置的註釋移除即可
<!-- --> <property> <name>sqoop.metastore.client.record.password</name> <value>true</value> <description>If true, allow saved passwords in the metastore. </description> </property>
移除之後,還需要將剛剛那個job刪除掉,重新創建job後才可以無密碼自動執行。
sqoop job --delete myjob1
sqoop job --create myjob1 -- import --connect jdbc:mysql://hadoop-master:3306/hive --username root --password admin --table TBLS --fields-terminated-by ‘\t‘ -m 1 --append
sqoop job --exec myjob1
參考資料
(1)吳超,《Sqoop的安裝與使用》:http://www.superwu.cn/2013/08/12/444/
(2)談翔,《Apache Sqoop:雲端大數據分析的關鍵一環》:http://www.searchcloudcomputing.com.cn/showcontent_86735.htm
(3)標點符,《Hadoop數據傳輸工具:Sqoop》:http://www.biaodianfu.com/sqoop.html
原文鏈接:http://www.cnblogs.com/edisonchou/
Hadoop學習筆記—18.Sqoop框架學習