sqoop學習總結

sqoop是Apache的一個開源項目,屬於Hadoop家族成員,核心功能是關係型數據庫和Hadoop之間的數據轉換與傳輸,從名字大概可以看出來:sql+hadoop=sqoop。sqoop目前發展處兩個主版本,分別是sqoop1和sqoop2,sqoop1的版本號是1.4.x,sqoop2的版本號是1.99.x,這個編號有點兒意思,尚不清楚爲何這麼遍。sqoop2和sqoop1是徹底不兼容的,從軟件構架到使用方法都是徹底不一樣的。html

sqoop1沒有server的概念,其自己做爲hadoop集羣的client調用mapreduce完成工做,sqoop2則多了一層server的構架,其中集成了tomcat。用戶經過client登陸到sqoop2 shell,在這個shell中能夠建立link,link是基於connector的,connector不須要建立,是sqoop2自己提供的,經常使用的connector包括hdfs-connector和jdbc-connector,分別對應HDFS和關係型數據庫的連接,目前最新的1.99.6版本記得也支持kafka等connector。建立link的過程至關因而connector的實例化,將指定連接的地址、用戶名密碼等信息。有了link以後就能夠建立job,job對應兩個link,一個鏈接數據源一個鏈接數據目的地。job建立完成後並無實際執行數據的傳輸,能夠在任意時間啓動建立成功的job。sqoop2的簡單操做能夠參考官方的這個小Demo:Sqoop5MinutesDemojava

個人理解是:sqoop2 server的做用主要是保存和管理數據源鏈接信息、數據傳輸任務等,固然也提供了經過REST接口操做任務這樣的高級功能。與sqoop1相比,sqoop2因爲多了一個server層,在配置上要麻煩一些,啓動server時常常會遇到一些奇怪的報錯,即便成功啓動server,後面的操做也可能遇到問題。目前我遇到一個問題是:成功建立link,成功建立job,啓動job後卡死,不提示任何錯誤信息,日誌文件中也看不到報錯信息。這個問題最終也沒有解決,因此我轉向了sqoop1。mysql

sqoop1要簡單不少,減壓到指定目錄,/etc/profile中配置好HADOOP_COMMON_HOME和HADOOP_MAPRED_HOME環境變量就能夠了,若是使用Hbase和Hive,也須要配置相應的環境變量。sqoop1使用上也很簡單,就是shell命令的通常用法:命令行裏敲sqoop+一些參數。個人使用場景是:把一臺Postgresql數據庫裏的全部數據導入HDFS,下面是shell腳本:sql

#!/bin/bash
# transport data from PG to HDFS

# parse database names 
psql -h 10.192.33.55 -p 5432 -U postgres -c '\l' > ./database_info
cut -f 1 -d '|'  ./database_info | grep '^\s[a-zA-Z]' | sed s/[[:space:]]//g > database_names
rm -f  ./database_info

# get one database name every time and conduct the transformation by sqoop
cat ./database_names | while read DBNAME
do
if [[ $DBNAME != "postgres" && $DBNAME != "template0" && $DBNAME != "template1" ]]
then
  # make dir on HDFS for each database
  hadoop fs -mkdir /pgdata/$DBNAME
  # make code dir for each database
  mkdir ./gencode/$DBNAME
  SCHEMA=`echo $DBNAME | tr a-z A-Z`
  echo "start working on the database $DBNAME ********************************** "
  sqoop-import-all-tables --connect jdbc:postgresql://10.192.33.55:5432/$DBNAME \
        --direct --username postgres --password postgres --fields-terminated-by '|' \
        --enclosed-by "'" --escaped-by '\' --warehouse-dir /pgdata/$DBNAME -m 1 \
        --outdir ./gencode/$DBNAME   -- --schema $SCHEMA
  echo "finished working on database $DBNAME ==================================="
fi
done

我這裏用的是sqoop-import-all-tables,用於導入(入是相對Hadoop來講的)一個庫的全部表,若是須要導入單個表,能夠用sqoop-import,而後用--table tablename指定要導入的表。除了導入整個表,sqoop也支持按照必定條件過濾導入數據,經過--where選項實現。下面解釋下用腳本中用到的幾個參數:shell

--connect: JDBC連接字符串
--username: 數據庫用戶名
--password: 數據庫登陸密碼,這是顯式指定密碼的方式,也能夠用-P實現交互式指定密碼,還能夠經過--password-file經過指定存有密碼的文件加載密碼。
--direct: 若是能夠,繞過普通的jdbc方式連接,使用數據庫各自特有的直接連接方式導數據,好比mysql的mysqldump,PG的psql。不是全部數據庫產品都支持這種方式。
--fields-terminated-by: 字段之間的分隔符,默認爲逗號。
--enclosed-by: 用來將各個字段包起來的字符,模式爲空。 
--escaped-by: 轉義符,好比我這裏指定了分隔符'|'轉義符'\',若字段內部出現'|'這個字符,就須要將其轉義寫成'\|'。
--warehouse-dir: 導入HDFS的文件存儲目錄
 -m: map任務數,一些表因爲沒有主鍵或者其餘緣由不能拆分用於多個map任務,我這裏爲了方便就所有指定了1個map任務。
--outdir: 導入過程當中生成的java類保存目錄
--schema: PG數據庫模式,注意這類參數是傳遞給特定數據庫鏈接工具的(不是sqoop),好比這裏的是psql,因此須要出如今一個單獨的「--」後面。

須要瞭解更多參數,請參考官方文檔:SqoopUserGuide
導入的結果像下面這樣,數據庫裏的每條記錄對應文件裏的一行:數據庫

'3663684'|'2016-05-12 08:06:00'|'2016-05-13 11:00:00'|'3'|'669'|'62.24'|'2016051200'|'187'
'3663685'|'2016-05-12 08:06:00'|'2016-05-13 17:00:00'|'3'|'669'|'9.71'|'2016051200'|'187'
'3663686'|'2016-05-12 08:06:00'|'2016-05-13 10:00:00'|'3'|'669'|'72.50'|'2016051200'|'187'
'3663687'|'2016-05-12 08:06:00'|'2016-05-13 04:00:00'|'3'|'669'|'1.00'|'2016051200'|'187'
'3663688'|'2016-05-12 08:06:00'|'2016-05-13 00:00:00'|'3'|'669'|'1.00'|'2016051200'|'187'
'3663689'|'2016-05-12 08:06:00'|'2016-05-13 09:00:00'|'3'|'669'|'110.57'|'2016051200'|'187'
'3663690'|'2016-05-12 08:06:00'|'2016-05-13 22:00:00'|'3'|'669'|'13.86'|'2016051200'|'187'
'3663691'|'2016-05-12 08:06:00'|'2016-05-13 08:00:00'|'3'|'669'|'109.19'|'2016051200'|'187'
'3663692'|'2016-05-12 08:06:00'|'2016-05-13 07:00:00'|'3'|'669'|'104.67'|'2016051200'|'187'

本篇就到此,後續再寫一寫導入Hbase以及Hive的方法,以及從Hadoop到sql的導出過程。apache

相關文章
相關標籤/搜索