Sqoop-1.4.6安裝部署及詳細使用介紹


之所以選擇Sqoop1是因為Sqoop2目前問題太多。無法正常使用,綜合比較后選擇Sqoop1。

Sqoop1安裝配置比較簡單

一、安裝部署

(1)、下載安裝包

下載地址:http://archive.cloudera.com/cdh5/cdh/5/sqoop-1.4.6-cdh5.5.2.tar.gz

解壓到/home/duanxz/sqoop

tar -zxvf sqoop-1.4.6-cdh5.5.2.tar.gz

(2)、拷貝mysql的jdbc驅動包mysql-connector-java-5.1.31-bin.jar到sqoop/lib目錄下。

duanxz@three:~/sqoop/sqoop-1.4.6-cdh5.5.2/lib$ ll mysql-connector-java-5.1.31.jar 
-rw------- 1 duanxz duanxz 964879 Jun 19 08:22 mysql-connector-java-5.1.31.jar
duanxz@three:~/sqoop/sqoop-1.4.6-cdh5.5.2/lib$ 

(3)、配置環境變量

#sqoop
export SQOOP_HOME=/home/duanxz/sqoop/sqoop-1.4.6-cdh5.5.2
export PATH="$PATH:$JAVA_HOME/bin:$HIVE_HOME/bin:$HIVE_HOME/conf:$SQOOP_HOME/bin"

(4)、復制sqoop/conf/sqoop-env-template.sh為sqoop-env.sh

添加相關的配置

#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/usr/local/hadoop-2.7.6

#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/usr/local/hadoop-2.7.6

#set the path to where bin/hbase is available
#export HBASE_HOME=

#Set the path to where bin/hive is available
export HIVE_HOME=/home/duanxz/hive/apache-hive-2.1.1-bin

#Set the path for where zookeper config dir is
#export ZOOCFGDIR=

(5)、測試Sqoop

sqoop help

結果:

duanxz@ubuntu:~/sqoop/sqoop-1.4.6-cdh5.5.2/bin$ sqoop help
Warning: /home/duanxz/sqoop/sqoop-1.4.6-cdh5.5.2/../hbase does not exist! HBase imports will fail.
Please set $HBASE_HOME to the root of your HBase installation.
Warning: /home/duanxz/sqoop/sqoop-1.4.6-cdh5.5.2/../hcatalog does not exist! HCatalog jobs will fail.
Please set $HCAT_HOME to the root of your HCatalog installation.
Warning: /home/duanxz/sqoop/sqoop-1.4.6-cdh5.5.2/../accumulo does not exist! Accumulo imports will fail.
Please set $ACCUMULO_HOME to the root of your Accumulo installation.
Warning: /home/duanxz/sqoop/sqoop-1.4.6-cdh5.5.2/../zookeeper does not exist! Accumulo imports will fail.
Please set $ZOOKEEPER_HOME to the root of your Zookeeper installation.
18/06/19 18:20:23 INFO sqoop.Sqoop: Running Sqoop version: 1.4.6-cdh5.5.2
usage: sqoop COMMAND [ARGS]

Available commands:
  codegen            Generate code to interact with database records
  create-hive-table  Import a table definition into Hive
  eval               Evaluate a SQL statement and display the results
  export             Export an HDFS directory to a database table
  help               List available commands
  import             Import a table from a database to HDFS
  import-all-tables  Import tables from a database to HDFS
  import-mainframe   Import datasets from a mainframe server to HDFS
  job                Work with saved jobs
  list-databases     List available databases on a server
  list-tables        List available tables in a database
  merge              Merge results of incremental imports
  metastore          Run a standalone Sqoop metastore
  version            Display version information

See 'sqoop help COMMAND' for information on a specific command.
duanxz@ubuntu:~/sqoop/sqoop-1.4.6-cdh5.5.2/bin$

說明:因為我們沒有基於hadoop安裝HBase,所以HBase相關的命令不能用,但是操作hadoop分布式文件系統的命令是可以用的。

再次執行sqoop version

duanxz@ubuntu:~/sqoop/sqoop-1.4.6-cdh5.5.2/bin$ sqoop version
Warning: /home/duanxz/sqoop/sqoop-1.4.6-cdh5.5.2/../hbase does not exist! HBase imports will fail.
Please set $HBASE_HOME to the root of your HBase installation.
Warning: /home/duanxz/sqoop/sqoop-1.4.6-cdh5.5.2/../hcatalog does not exist! HCatalog jobs will fail.
Please set $HCAT_HOME to the root of your HCatalog installation.
Warning: /home/duanxz/sqoop/sqoop-1.4.6-cdh5.5.2/../accumulo does not exist! Accumulo imports will fail.
Please set $ACCUMULO_HOME to the root of your Accumulo installation.
Warning: /home/duanxz/sqoop/sqoop-1.4.6-cdh5.5.2/../zookeeper does not exist! Accumulo imports will fail.
Please set $ZOOKEEPER_HOME to the root of your Zookeeper installation.
18/06/19 18:55:22 INFO sqoop.Sqoop: Running Sqoop version: 1.4.6-cdh5.5.2
Sqoop 1.4.6-cdh5.5.2
git commit id 8e266e052e423af592871e2dfe09d54c03f6a0e8
Compiled by jenkins on Mon Jan 25 16:10:15 PST 2016
duanxz@ubuntu:~/sqoop/sqoop-1.4.6-cdh5.5.2/bin$ 

二、使用Sqoop測試

2.1、測試連接:

(1)顯示mysql數據庫列表

sqoop list-databases --username risk_user  --password 'risk_pwd' --connect jdbc:mysql://10.200.110.4:3306/risk_data?characterEncoding=UTF-8

(2)顯示數據庫里所有表:

sqoop list-tables --username risk_user  --password 'risk_pwd' --connect jdbc:mysql://10.200.110.4:3306/risk_data?characterEncoding=UTF-8

2、Mysql與HDFS互導

(1)mysql導入到hdfs

mysql中創建一個測試表:

DROP TABLE IF EXISTS `user_info`;

CREATE TABLE `user_info` (
  `id` int(11) NOT NULL,
  `user_name` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `address` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

 

加點數據:

insert into `user_info` (`id`, `user_name`, `age`, `address`) values('1','zhangsan  ','20','shenzhen nanshang');
insert into `user_info` (`id`, `user_name`, `age`, `address`) values('2','lisi','21','shenzhen baoan');
insert into `user_info` (`id`, `user_name`, `age`, `address`) values('3','wangwu','23','shenzhen futian');
insert into `user_info` (`id`, `user_name`, `age`, `address`) values('4','zhuqi','25','shenzhen guangming');
insert into `user_info` (`id`, `user_name`, `age`, `address`) values('5','houba','26','shenzhen xili');
insert into `user_info` (`id`, `user_name`, `age`, `address`) values('6','cailiu','27','shenzhen xili');
insert into `user_info` (`id`, `user_name`, `age`, `address`) values('7','laojiu','27','shenzhen yantian');

 

把mysql中表user_info導入到hdfs,導入之前查詢一下user_info表中的數據

共:7條

sqoop import --connect jdbc:mysql://10.200.110.4:3306/risk_data --username risk_user --password 'risk_pwd'  --table user_info --target-dir /tmp/hive/sqoop/user_info -m 4

參數說明:

-m:表示Map並發數

--target-dir:hdfs的目標目錄,若是不寫, 則默認是hdfs上的user/username/tablename 路徑

如果重復執行,會提示目錄已經存在,可以手動刪除

運行完mapreduce結束后去HDFS上檢查。

HDFS的50070上看到已經成功,如下圖:

驗證hdfs上導入的數據:

duanxz@ubuntu:~/sqoop/sqoop-1.4.6-cdh5.5.2/bin$ hadoop fs -ls /tmp/hive/sqoop/user_info
Found 5 items
-rw-r--r--   1 duanxz supergroup          0 2018-06-19 19:14 /tmp/hive/sqoop/user_info/_SUCCESS
-rw-r--r--   1 duanxz supergroup         59 2018-06-19 19:14 /tmp/hive/sqoop/user_info/part-m-00000
-rw-r--r--   1 duanxz supergroup         58 2018-06-19 19:14 /tmp/hive/sqoop/user_info/part-m-00001
-rw-r--r--   1 duanxz supergroup         25 2018-06-19 19:14 /tmp/hive/sqoop/user_info/part-m-00002
-rw-r--r--   1 duanxz supergroup         55 2018-06-19 19:14 /tmp/hive/sqoop/user_info/part-m-00003
duanxz@ubuntu:~/sqoop/sqoop-1.4.6-cdh5.5.2/bin$ hadoop fs -ls /tmp/hive/sqoop/user_info/part-m-00000
-rw-r--r--   1 duanxz supergroup         59 2018-06-19 19:14 /tmp/hive/sqoop/user_info/part-m-00000
duanxz@ubuntu:~/sqoop/sqoop-1.4.6-cdh5.5.2/bin$ hadoop fs -cat /tmp/hive/sqoop/user_info/part-m-00000
1,zhangsan  ,20,shenzhen nanshang
2,lisi,21,shenzhen baoan
duanxz@ubuntu:~/sqoop/sqoop-1.4.6-cdh5.5.2/bin$ 

(2)HDFS導入到mysql

把HDFS中數據導入到Mysql表中,mysql中需要預先建立空表user_info2,此時該表為空

導入指令:

sqoop export --connect jdbc:mysql://10.200.110.4:3306/risk_data --table user_info2 -m 1 --username risk_user --password 'risk_pwd' --export-dir /tmp/hive/sqoop/user_info/ --input-fields-terminated-by ',' --columns="id,user_name,address"

運行完顯示

顯示導出7條記錄。

或者:根據條件篩選部分記錄導入到hdfs中。

sqoop import --connect jdbc:mysql://10.200.110.4:3306/risk_data --username risk_user --password 'risk_pwd' --query 'select id, user_name,age,address from user_info where $CONDITIONS LIMIT 100' --target-dir /tmp/hive/import/user_info --num-mappers 1 --fields-terminated-by ','

 

再到表user_info2查看

並且正好也是7條。 

至此,用Sqoop將mysql與HDFS互導功都驗證完畢。

 

你還可以指定其他的參數:

參數 說明
--append 將數據追加到hdfs中已經存在的dataset中。使用該參數,sqoop將把數據先導入到一個臨時目錄中,然后重新給文件命名到一個正式的目錄中,以避免和該目錄中已存在的文件重名。
--as-avrodatafile 將數據導入到一個Avro數據文件中
--as-sequencefile 將數據導入到一個sequence文件中
--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
--table <table-name> 關系數據庫表名,數據從該表中獲取
--delete-target-dir 刪除目標目錄
--target-dir <dir> 指定hdfs路徑
--warehouse-dir <dir> 與 --target-dir 不能同時使用,指定數據導入的存放目錄,適用於hdfs導入,不適合導入hive目錄
--where 從關系數據庫導入數據時的查詢條件,示例:--where "id = 2"
-z,--compress 壓縮參數,默認情況下數據是沒被壓縮的,通過該參數可以使用gzip壓縮算法對數據進行壓縮,適用於SequenceFile, text文本文件, 和Avro文件
--compression-codec Hadoop壓縮編碼,默認是gzip
--null-string <null-string> 可選參數,如果沒有指定,則字符串null將被使用
--null-non-string <null-string> 可選參數,如果沒有指定,則字符串null將被使用

示例程序:

$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --table TBLS --columns "tbl_id,create_time" --where "tbl_id > 1" --target-dir /user/hive/result

使用 sql 語句

參照上表,使用 sql 語句查詢時,需要指定 $CONDITIONS

$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --query 'SELECT * from TBLS where \$CONDITIONS ' --split-by tbl_id -m 4 --target-dir /user/hive/result 

上面命令通過 -m 1 控制並發的 map 數。

使用 direct 模式:

$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --table TBLS --delete-target-dir --direct --default-character-set UTF-8 --target-dir /user/hive/result

指定文件輸出格式:

$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --table TBLS --fields-terminated-by"\t" --lines-terminated-by "\n" --delete-target-dir --target-dir /user/hive/result

這時候查看 hdfs 中數據(觀察分隔符是否為制表符):

$ hadoop fs -ls result
Found 5 items -rw-r--r-- 3 root hadoop 0 2014-08-04 16:07 result/_SUCCESS -rw-r--r-- 3 root hadoop 69 2014-08-04 16:07 result/part-m-00000 -rw-r--r-- 3 root hadoop 0 2014-08-04 16:07 result/part-m-00001 -rw-r--r-- 3 root hadoop 142 2014-08-04 16:07 result/part-m-00002 -rw-r--r-- 3 root hadoop 62 2014-08-04 16:07 result/part-m-00003 $ hadoop fs -cat result/part-m-00000 34 1406784308 8 0 root 0 45 test1 EXTERNAL_TABLE null null null $ hadoop fs -cat result/part-m-00002 40 1406797005 9 0 root 0 52 test2 EXTERNAL_TABLE null null null 42 1407122307 7 0 root 0 59 test3 EXTERNAL_TABLE null null null 

指定空字符串:

$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --table TBLS --fields-terminated-by "\t" --lines-terminated-by "\n" --delete-target-dir --null-string '\\N' --null-non-string '\\N' --target-dir /user/hive/result 

如果需要指定壓縮:

$ sqoop import --connect jdbc:mysql://192.168.56.121:3306/metastore --username hiveuser --password redhat --table TBLS --fields-terminated-by "\t" --lines-terminated-by "\n" --delete-target-dir --null-string '\\N' --null-non-string '\\N' --compression-codec "com.hadoop.compression.lzo.LzopCodec" --target-dir /user/hive/result 

附:可選的文件參數如下表。

參數 說明
--enclosed-by <char> 給字段值前后加上指定的字符,比如雙引號,示例:--enclosed-by '\"',顯示例子:"3","jimsss","dd@dd.com"
--escaped-by <char> 給雙引號作轉義處理,如字段值為"測試",經過 --escaped-by "\\" 處理后,在hdfs中的顯示值為:\"測試\",對單引號無效
--fields-terminated-by <char> 設定每個字段是以什么符號作為結束的,默認是逗號,也可以改為其它符號,如句號.,示例如:--fields-terminated-by
--lines-terminated-by <char> 設定每條記錄行之間的分隔符,默認是換行串,但也可以設定自己所需要的字符串,示例如:--lines-terminated-by "#" 以#號分隔
--mysql-delimiters Mysql默認的分隔符設置,字段之間以,隔開,行之間以換行\n隔開,默認轉義符號是\,字段值以單引號'包含起來。
--optionally-enclosed-by <char> enclosed-by是強制給每個字段值前后都加上指定的符號,而--optionally-enclosed-by只是給帶有雙引號或單引號的字段值加上指定的符號,故叫可選的

 3、Mysql與Hive互導

下面的命令行,將mysql的user_info表導入到hive的

sqoop import --connect jdbc:mysql://10.200.110.4:3306/risk_data --table user_info --username risk_user --password 'risk_pwd' --fields-terminated-by ',' --delete-target-dir --num-mappers 1 --hive-import --hive-database default --hive-table hive_user_info

 

出現如下錯誤:

錯誤1:Sqoop:Import failed: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf

解決方法:

將mysql中的數據導入到hive中報錯:

ERROR tool.ImportTool:Import failed: java.io.IOException: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf

這是因為sqoop需要一個hive的包,將hive/lib中的hive-common-2.3.3.jar拷貝到sqoop的lib目錄中,重新執行試試。

 

錯誤2:ERROR tool.CreateHiveTableTool: Encountered IOException running create table job: java.io.IOException: Hive exited with status 1

解決方法:

我的hive是本地模式,只能一個用戶登錄。所以要把另外一個hive登錄給退出。

錯誤3:error='Cannot allocate memory' (errno=12)

解決方法:

我的hive是本地模式,只能一個用戶登錄。所以要把另外一個hive登錄給退出。 

 

錯誤4:Version information not found ,Caused by: MetaException(message:Version information not found in metastore. )

解決方法:

1、mysql-connector-java-5.1.26-bin.jar  是否放到hive/lib 目錄下 建議修改權限為777 (chmod 777 mysql-connector-java-5.1.26-bin.jar)

2、修改conf/hive-site.xml 中的 “hive.metastore.schema.verification”  值為 false  即可解決 “Caused by: MetaException(message:Version information not found in metastore. )” 

 

 

錯誤3:

ERROR tool.ImportTool: EncounteredIOException running import job: java.io.IOException: DataStreamer Exception:

       atorg.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.run(DFSOutputStream.java:796)

Caused by: java.lang.OutOfMemoryError:unable to create new native thread

       at java.lang.Thread.start0(Native Method)

       at java.lang.Thread.start(Thread.java:714)

       atorg.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.initDataStreaming(DFSOutputStream.java:581)

       at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.run(DFSOutputStream.java:669)

 

 

解決方法:

 

net.ipv4.ip_local_port_range = 1024 65000

修改系統參數

echo "100000" > /proc/sys/kernel/threads-max

echo "100000" > /proc/sys/kernel/pid_max (默認32768)

echo "200000" > /proc/sys/vm/max_map_count (默認65530)

修改/etc/security/limits.conf

* - nproc 999999
* -nofile 999999
PS:nproc是修改系統的max user processes大小;nofile 是修改open files的大小,另外linux 2.6.25內核之前有個宏定義,定義了這個值的最大值,為1024*1024,正好是100萬,而在2.6.25內核及其之后,這個值是可以通過/proc/sys/fs/nr_open來設置,不過,999999足夠用了。
很多人可能會遇到,只能啟動32000多個線程就不能再起更多的線程了,其實就是pid_max = 32768 給限制住了

增加map數量,通過sqoop -m 選項指定更多的map。通過更多的map,降少每個子進程占用的heap space,避免超出hadoop設置的java heap space 大小
sqoop ... -m <map 數量>

錯誤2:

Caused by: java.lang.RuntimeException:java.sql.SQLException: Access denied for user 'root'@'hadoop003' (usingpassword: YES)

       atorg.apache.sqoop.mapreduce.db.DBInputFormat.getConnection(DBInputFormat.java:220)

       atorg.apache.sqoop.mapreduce.db.DBInputFormat.setConf(DBInputFormat.java:165)

       ... 9 more

程序正常運行,結果也正確。說明數據庫連接是正確的,而且單獨用mysql連接也是可以的。就是報這個異常錯誤。 

查詢數據庫里用戶信息

 

 

JDBC連接的機器名是hadoop003,雖然已經賦予root所有機器的遠程訪問權限(“%”),但是hadoop003這個賬戶可能沒有開通機器的遠程權限。於是給hadoop003這個機器開通遠程權限。

GRANT ALL PRIVILEGES ON *.* TO'root'@'hadoop003' IDENTIFIED BY '********' WITH GRANT OPTION;

 

再次執行導入命令。成功。不再出現上面錯誤。

 

錯誤3:

 

從mysql導入到Hive里報如下錯誤:

ERROR hive.HiveConfig: Could not loadorg.apache.hadoop.hive.conf.HiveConf. Make sure HIVE_CONF_DIR is set correctly.

16/02/26 14:43:47 ERROR tool.ImportTool:Encountered IOException running import job: java.io.IOException:java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf

數據已經導入到HDFS。從HDFS移動到Hive里時出錯。提示HIVE_CONF_DIR配置不對。

但是將HIVE_CONF_DIR添加到sqoop-env.sh、hadoop-env.sh、hive-env.sh都不起作用。

最終正確的解決方法:

在/etc/profile  里添加下面一句話

exportHADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HIVE_HOME/lib/*

Sqoop-1.4.7版本好像解決了這個問題。期待這個版本


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM