一、概述
sqoop是hive、hdfs、hbase等與RDMBS(mysql等)之間的溝通橋梁,主要通過JDBC與RDMBS進行交互。有兩個版本sqoop1和sqoop2,sqoop1架構簡單,使用非常方便(由於我使用的是sqoop1,所以本文主要介紹sqoop1),sqoop2是c/s架構,需要一個tomcat部署server端,並且提供了更多的訪問方式:REST API、WEBUI、CLI、JAVA API等,並且提供了更安全的訪問方式(主要是密碼不會是明文)。但是sqoop主要在內網是用所以這都無所謂了。
二、部署
1、安裝前的准備
去官方下載最新的安裝包,下載地址:https://github.com/apache/sqoop/releases
下載mysql的連接jar包,下載地址:http://central.maven.org/maven2/mysql/mysql-connector-java/8.0.9-rc/mysql-connector-java-8.0.9-rc.jar
請確保已經提前安裝好hadoop、hive。
2、安裝
#tar xf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C /data/
#cd /data/sqoop-1.4.7.bin__hadoop-2.6.0/lib
#wget http://central.maven.org/maven2/mysql/mysql-connector-java/8.0.9-rc/mysql-connector-java-8.0.9-rc.jar
#cd /data/sqoop-1.4.7.bin/__hadoop-2.6.0/conf
添加系統環境變量
#vim /etc/profile
export SQOOP_HOME=/data/sqoop-1.4.7.bin__hadoop-2.6.0
export PATH=$SQOOP_HOME/bin:$PATH
export HADOOP_CLASSPATH=$CLASSPATH:$HIVE_HOME/lib/*
修改sqoop-env.sh
#cp sqoop-env-template.sh sqoop-env.sh
添加如下內容:
#vim sqoop-env.sh
export HADOOP_COMMON_HOME=/data/hadoop-2.7.5
export HADOOP_MAPRED_HOME=/data/hadoop-2.7.5
export HIVE_HOME=/data/apache-hive-2.3.2-bin
export HIVE_CONF_DIR=$HIVE_HOME/conf
#vim $JAVA_HOME/jre/lib/security/java.policy
在grant{}內部添加如下內容:
permission javax.management.MBeanTrustPermission "register";
3、替換lib目錄下面想應的jar包,否則是用的時候會報錯
1)報錯:
main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTrustPermission" "register")
解決方法:
#vim $JAVA_HOME/jre/lib/security/java.policy
在grant{}內部添加如下內容:
permission javax.management.MBeanTrustPermission "register";
2)報錯:
NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapper.readerFor
是由於sqoop的lib目錄下面的jackson相關的包的版本與hive的lib目錄下的jackson相關jar包的版本不一致導致的。
解決方法:
將hive下的所有jackson相關jar全部copy到sqoop的lib目錄下面
#cp -r $HIVE_HOME/lib/jackson-* $SQOOP_HOME/lib/
然后將重復的低版本的全部刪掉就可以了。(切記不要全部刪除,有些是不重復的)
3)報錯:
ERROR tool.ImportTool: Encountered IOException running import job: java.io.IOException: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf
解決方法:
#vim /etc/profile
export HADOOP_CLASSPATH=$CLASSPATH:$HIVE_HOME/lib/*
#source /etc/profile
4)報錯:
ERROR sqoop.Sqoop: Got exception running Sqoop: java.lang.RuntimeException: java.lang.RuntimeException: java.sql.SQLException: The connection property 'zeroDateTimeBehavior' acceptable values are: 'CONVERT_TO_NULL', 'EXCEPTION' or 'ROUND'. The value 'convertToNull' is not acceptable.
java.lang.RuntimeException: java.lang.RuntimeException: java.sql.SQLException: The connection property 'zeroDateTimeBehavior' acceptable values are: 'CONVERT_TO_NULL', 'EXCEPTION' or 'ROUND'. The value 'convertToNull' is not acceptable
解決方法:
使用命令是又一個jdbc的url,在url的后面加上zeroDateTimeBehavior=CONVERT_TO_NULL。
#sqoop import --connect jdbc:mysql://10.0.2.248:3306/test?zeroDateTimeBehavior=CONVERT_TO_NULL --username root --password hive123 --table a --hive-import --fields-terminated-by ',' --hive-overwrite -m 1
三、使用
1)將mysql數據導入到hive
創建hive表:
# sqoop create-hive-table --connect jdbc:mysql://10.0.2.248:3306/test --username root --password hive123 --table a --hive-table tt --fields-terminated-by ',' --hive-overwrite --as-parquetfile --target-dir /data/
將數據導入到hive表:
#sqoop import --connect jdbc:mysql://10.0.2.248:3306/test?zeroDateTimeBehavior=CONVERT_TO_NULL --username root --password hive123 --table a --hive-import --fields-terminated-by ',' --hive-overwrite -m 1 --as-parquetfile
#sqoop import --connect jdbc:mysql://10.0.2.248:3306/test?zeroDateTimeBehavior=CONVERT_TO_NULL --username root --password hive123 --table userlog --fields-terminated-by "\t" --lines-terminated-by "\n" --hive-import --hive-overwrite --create-hive-table --hive-table userlog.userlog --delete-target-dir
將數據導入到hive指定的庫中:
#sqoop import --connect jdbc:mysql://10.0.2.248:3306/test?zeroDateTimeBehavior=CONVERT_TO_NULL --username root --password hive123 --table porder0 --hive-import --hive-overwrite --hive-database bigdata -m 1
導入部分字段:
#sqoop import --connect jdbc:mysql://10.0.2.248:3306/test?zeroDateTimeBehavior=CONVERT_TO_NULL --username root --password hive123 --table b --columns id,csv_date --hive-import --fields-terminated-by ',' --hive-overwrite --direct -m 1 --delete-target-dir
2)將mysql數據增量導入到hive里面:
#sqoop import --connect jdbc:mysql://10.0.2.248:3306/test?zeroDateTimeBehavior=CONVERT_TO_NULL --username root --password hive123 --table a --hive-import --fields-terminated-by ',' --hive-overwrite -m 1 --as-parquetfile
#sqoop import --connect jdbc:mysql://10.0.2.248:3306/test?zeroDateTimeBehavior=CONVERT_TO_NULL --username root --password hive123 --table a -m 1 --target-dir /test/a_2 --incremental lastmodified --check-column crt_date --where crt_date>="2016-12-26 17:04:20" --as-parquetfile
3)codegen生成jar包:
#sqoop codegen --connect jdbc:mysql://10.0.2.248:3306/test?zeroDateTimeBehavior=CONVERT_TO_NULL --username root --password hive123 --table a
4)合並
#sqoop merge --new-data /test/a_2 --onto /test/a_1 --target-dir /test/a_merge --jar-file /tmp/sqoop-root/compile/57c71c4b6aa32458bb7a2d2636ba673f/a.jar --class-name a --merge-key id
注:–class-name a(這里是表名)
5)將合並后的數據導入到hive:
#cat hive.ql
drop table a;
create table if not exists a(id int, name string, csr_date timestamp) row delimited fields terminated by ',' stored as parquet;
load data inpath "/test/a_merge/" into table a;
#hive -f hive.ql
將hive里的數據導入到mysql:
1、根據hive里面表的結構,創建mysql表:
>create table if not exists test(id int, name varchar(40));
2、導入數據
#sqoop export --connect jdbc:mysql://10.0.2.248:3306/test?zeroDateTimeBehavior=CONVERT_TO_NULL --username root --password hive23 --table test --export-dir /user/hive/warehouse/a -m 1 --input-fields-terminated-by ','
將mysql數據導入到hdfs中
#sqoop import --connect jdbc:mysql://10.0.2.248:3306/sqoop?zeroDateTimeBehavior=CONVERT_TO_NULL --username root --password hive123 --table test -m 1 --as-parquetfile --target-dir /user/hive/result
參數詳解:
--append 將數據追加到 hdfs 中已經存在的 dataset 中已經存在的 dataset 中。使用該參數, sqoop 將把數據先導入到一個臨時目錄中,然后重新給文件命 名到一個正式的目錄中,以避免和該目錄中已存在的文件重名。
--as-avrodatafile 將數據導入到一個 Avro 數據文件中
--as-sequencefile 將數據導入到一個 sequence 文件中
--as-parquetfile 將數據導入到一個parquet文件里面
--as-textfile 將數據導入到一個普通文本文件中,生成該文本文件后,可以在 hive 中通過 sql 語句查詢出結果。
--boundary-query <statement> 邊界查詢,也就是在導入前先通過 SQL 查詢得到一個結果集,然后導入的數據就是該結果集內的數據,格式如: --boundary-query 'select id,no from t where id = 3' ,表示導入的數據為 id=3 的記錄,或者 select min(<split-by>), max(<split-by>) from <table name> ,注意查詢的字段中不能有數據類型為字符串的字段,否則會報錯
--columns<col,col> 指定要導入的字段值,格式如: --columns id,username
--direct 直接導入模式,使用的是關系數據庫自帶的導入導出工具。官網上是說這樣導入會更快
--direct-split-size 在使用上面 direct 直接導入的基礎上,對導入的流按字節數分塊,特別是使用直連模式從 PostgreSQL 導入數據的時候,可以將一個到達設定大小的文件分為幾個獨立的文件。
--inline-lob-limit 設定大對象數據類型的最大值
-m,--num-mappers 啟動 N 個 map 來並行導入數據,默認是 4 個,最好不要將數字設置為高於集群的節點數
--query , -e <sql> 從查詢結果中導入數據,該參數使用時必須指定– target-dir 、– hive-table ,在查詢語句中一定要有 where 條件且在 where 條件中需要包含 \$CONDITIONS ,示例: --query 'select * from t where \$CONDITIONS ' --target-dir /tmp/t – hive-table t
--split-by <column> 表的列名,用來切分工作單元,一般后面跟主鍵 ID
--target-dir <dir> 指定 hdfs 路徑
--delete-target-dir 刪除目標目錄
--warehouse-dir <dir> 與 --target-dir 不能同時使用,指定數據導入的存放目錄,適用於 hdfs 導入,不適合導入 hive 目錄
--where 從關系數據庫導入數據時的查詢條件,示例: --where "id = 2"
-z,--compress 默認情況下數據是沒被壓縮的,通過該參數可以使用 gzip 壓縮算法對數據進行壓縮,適用於 SequenceFile, text 文本文件 , 和 Avro 文件
--compression-codec Hadoop 壓縮編碼,默認是 gzip
--table <table-name> 關系數據庫表名,數據從該表中獲取
--hive-import 導入到hive中
--hive-overwrite 覆蓋原有的數據
--hive-database 指定導入到hive中指定的庫
