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