一、Sqoop簡介
Apache Sqoop(TM)是一種旨在有效地在Apache Hadoop和諸如關系數據庫等結構化數據存儲之間傳輸大量數據的工具。
Sqoop于2012年3月孵化出來,現在是一個頂級的Apache項目。
請注意,1.99.7與1.4.6不兼容,且沒有特征不完整,它并不打算用于生產部署。
二、Sqoop原理
將導入或導出命令翻譯成mapreduce程序來實現。
在翻譯出的mapreduce中主要是對inputformat和outputformat進行定制。
三、Sqoop安裝
安裝Sqoop的前提是已經具備Java和Hadoop的環境。
3.1、下載并解壓
上傳安裝包sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz到虛擬機中,如我的上傳目錄是:/opt/software/
解壓sqoop安裝包到指定目錄,如:
$ tar -zxvf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /opt/module/
3.2、修改配置文件
Sqoop的配置文件與大多數大數據框架類似,在sqoop根目錄下的conf目錄中。
- 重命名配置文件
$ mv sqoop-env-template.sh sqoop-env.sh
$ mv sqoop-site-template.xml sqoop-site.xml 此行不用做
- 修改配置文件
sqoop-env.sh
export HADOOP_COMMON_HOME=/opt/module/hadoop-2.8.4
export HADOOP_MAPRED_HOME=/opt/module/hadoop-2.8.4
export HIVE_HOME=/opt/module/hive
export ZOOKEEPER_HOME=/opt/module/zookeeper-3.4.10
export ZOOCFGDIR=/opt/module/zookeeper-3.4.10/conf
3.3、拷貝JDBC驅動
拷貝jdbc驅動到sqoop的lib目錄下,如:
$ cp -a mysql-connector-java-5.1.27-bin.jar /opt/module/sqoop-1.4.6.bin__hadoop-2.0.4-alpha/lib
3.4、驗證Sqoop
我們可以通過某一個command來驗證sqoop配置是否正確:
$ bin/sqoop help
出現一些Warning警告(警告信息已省略),并伴隨著幫助命令的輸出:
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
version Display version information
·····
注:注釋掉configure-sqoop 134行到143行的內容,內容如下
134 ## Moved to be a runtime check in sqoop.
135 #if [ ! -d "${HCAT_HOME}" ]; then
136 # echo "Warning: $HCAT_HOME does not exist! HCatalog jobs will fail."
137 # echo 'Please set $HCAT_HOME to the root of your HCatalog installation.'
138 #fi
139 #
140 #if [ ! -d "${ACCUMULO_HOME}" ]; then
141 # echo "Warning: $ACCUMULO_HOME does not exist! Accumulo imports will fail."
142 # echo 'Please set $ACCUMULO_HOME to the root of your Accumulo installation.'
143 #fi
3.5、測試Sqoop是否能夠成功連接數據庫
$ bin/sqoop list-databases --connect jdbc:mysql://bigdata113:3306/ --username root --password 000000
出現如下輸出:
information_schema
metastore
mysql
performance_schema
四、Sqoop的簡單使用案例
4.1、導入數據
在Sqoop中,“導入”概念指:從非大數據集群(RDBMS)向大數據集群(HDFS,HIVE,HBASE)中傳輸數據,叫做:導入,即使用import關鍵字。
4.1.1、RDBMS到HDFS
- 確定Mysql服務開啟正常
- 在Mysql中新建一張表并插入一些數據
$ mysql -uroot -p000000
mysql> create database company;
mysql> create table company.staff(id int(4) primary key not null auto_increment, name varchar(255), sex varchar(255));
mysql> insert into company.staff(name, sex) values('Thomas', 'Male');
mysql> insert into company.staff(name, sex) values('Catalina', 'FeMale');
- 導入數據
(1)全部導入
$ bin/sqoop import \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000 \
--table student \
--target-dir /user/test/student1 \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t"
(2)查詢導入
$ bin/sqoop import \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000 \
--target-dir /user/test/student \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--query 'select name,sex from student where id <=6 and $CONDITIONS;'
尖叫提示:must contain 'CONDITIONS前必須加轉移符,防止shell識別為自己的變量。
(3)導入指定列
$ bin/sqoop import \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000 \
--target-dir /user/test/student \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--columns id,name \
--table student
尖叫提示:columns中如果涉及到多列,用逗號分隔,分隔時不要添加空格
(4)使用sqoop關鍵字篩選查詢導入數據
$ bin/sqoop import \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000 \
--target-dir /user/test/student \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--table student \
--where "id=2"
尖叫提示:在Sqoop中可以使用sqoop import -D property.name=property.value這樣的方式加入執行任務的參數,多個參數用空格隔開。
4.1.2、RDBMS到Hive
$ bin/sqoop import \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000 \
--table student \
--delete-target-dir \
--num-mappers 1 \
--hive-import \
--fields-terminated-by "\t" \
--hive-overwrite \
--hive-table student_hive
尖叫提示:該過程分為兩步,第一步將數據導入到HDFS,第二步將導入到HDFS的數據遷移到Hive倉庫
尖叫提示:從MYSQL到Hive,本質時從MYSQL => HDFS => load To Hive
4.2、導出數據
在Sqoop中,“導出”概念指:從大數據集群(HDFS,HIVE,HBASE)向非大數據集群(RDBMS)中傳輸數據,叫做:導出,即使用export關鍵字。
4.2.1、HIVE/HDFS到RDBMS
創建aca表
create table abc(id int,name VARCHAR(5));
$ bin/sqoop export \
--connect jdbc:mysql://bigdata111:3306/test characterEncoding=utf-8\
--username root \
--password 000000 \
--export-dir /user/hive/warehouse/student_hive \
--table student1 \
--num-mappers 1 \
--input-fields-terminated-by "\t"
尖叫提示:Mysql中如果表不存在,不會自動創建,自行根據表結構創建
尖叫提示:重復往mysql的統一個表中導出數據,mysql的表不能設置主鍵和自增。
尖叫提示:如果數據導出mysql中是“??”那么添加characterEncoding=utf-8
思考:數據是覆蓋還是追加 答案:追加
4.3、腳本打包
使用opt格式的文件打包sqoop命令,然后執行
- 創建一個.opt文件
$ touch job_HDFS2RDBMS.opt
- 編寫sqoop腳本
$ vi ./job_HDFS2RDBMS.opt
#以下命令是從staff_hive中追加導入到mysql的aca表中
export
--connect
jdbc:mysql://bigdata112:3306/test
--username
root
--password
000000
--table
student
--num-mappers
1
--export-dir
/user/hive/warehouse111/student_hive
--input-fields-terminated-by
"\t"
- 執行該腳本
$ bin/sqoop --options-file job_HDFS2RDBMS.opt
五、Sqoop一些常用命令及參數
5.1、常用命令列舉
這里給大家列出來了一部分Sqoop操作時的常用參數,以供參考,需要深入學習的可以參看對應類的源代碼。
5.2、命令&參數詳解
剛才列舉了一些Sqoop的常用命令,對于不同的命令,有不同的參數,讓我們來一一列舉說明。
首先來我們來介紹一下公用的參數,所謂公用參數,就是大多數命令都支持的參數。
5.2.1、公用參數:數據庫連接
5.2.2、公用參數:import
5.2.3、公用參數:export
5.2.4、公用參數:hive
公用參數介紹完之后,我們來按照命令介紹命令對應的特有參數。
5.2.5、命令&參數:import
將關系型數據庫中的數據導入到HDFS(包括Hive,HBase)中,如果導入的是Hive,那么當Hive中沒有對應表時,則自動創建。
- 命令:
如:導入數據到hive中
$ bin/sqoop import \
--connect jdbc:mysql://bigdata113:3306/test \
--username root \
--password 000000 \
--table access \
--hive-import \
--fields-terminated-by "\t"
如:增量導入數據到hive中,mode=append
append導入:
$ bin/sqoop import \
--connect jdbc:mysql://bigdata111:3306/test \
--username root \
--password 000000 \
--table student \
--num-mappers 1 \
--fields-terminated-by "\t" \
--target-dir /user/hive/warehouse111/student_hive \
--check-column id \
--incremental append \
--last-value 10
尖叫提示:append不能與--hive-等參數同時使用(Append mode for hive imports is not yet supported. Please remove the parameter --append-mode)
注:--last-value 2 的意思是標記增量的位置為第二行,也就是說,當數據再次導出的時候,從第二行開始算
注:如果 --last-value N , N > MYSQL中最大行數,則HDFS會創建一個空文件。如果N<=0 , 那么就是所有數據
如:增量導入數據到hdfs中,mode=lastmodified(注:卡?。?/p>
先在mysql中建表并插入幾條數據:
mysql> create table staff_timestamp(id int(4), name varchar(255), sex varchar(255), last_modified timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
mysql> insert into staff_timestamp (id, name, sex) values(1, 'AAA', 'female');
mysql> insert into staff_timestamp (id, name, sex) values(2, 'BBB', 'female');
先導入一部分數據:
$ bin/sqoop import \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000 \
--table staff_timestamp \
--delete-target-dir \
--hive-import \
--fields-terminated-by "\t" \
--m 1
再增量導入一部分數據:
mysql> insert into staff_timestamp (id, name, sex) values(3, 'CCC', 'female');
$ bin/sqoop import \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000 \
--table staff_timestamp \
--check-column last_modified \
--incremental lastmodified \
--m 1 \
--last-value "2019-07-16 06:44:12" \
--append \
--fields-terminated-by "\t" \
--warehouse-dir /user/hive/warehouse/
尖叫提示:使用lastmodified方式導入數據要指定增量數據是要--append(追加)還是要--merge-key(合并)
尖叫提示:在Hive中,如果不指定輸出路徑,可以去看以下兩個目錄
/user/root(此為用戶名)
/user/hive/warehouse 個人配置的目錄
尖叫提示:last-value指定的值是會包含于增量導入的數據中
如果卡住,在yarn-site.xml中加入以下配置
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>20480</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>2048</value>
</property>
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>2.1</value>
</property>
- 參數:
5.2.6、命令&參數:export
從HDFS(包括Hive和HBase)中將數據導出到關系型數據庫中。
- 命令:
如:
bin/sqoop export \
--connect jdbc:mysql://bigdata113:3306/test \
--username root \
--password 000000 \
--export-dir /user/hive/warehouse/staff_hive \
--table aca \
--num-mappers 1 \
--input-fields-terminated-by "\t"
- 參數:
5.2.7、命令&參數:codegen
將關系型數據庫中的表映射為一個Java類,在該類中有各列對應的各個字段。
如:
$ bin/sqoop codegen \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000 \
--table student \
--bindir /root/student \
--class-name Student \
--fields-terminated-by "\t"
5.2.8、命令&參數:create-hive-table
生成與關系數據庫表結構對應的hive表結構。
命令:
如:僅建表
$ bin/sqoop create-hive-table \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000 \
--table student \
--hive-table hive_student
參數:
5.2.9、命令&參數:eval
可以快速的使用SQL語句對關系型數據庫進行操作,經常用于在import數據之前,了解一下SQL語句是否正確,數據是否正常,并可以將結果顯示在控制臺。
命令:
如:
$ bin/sqoop eval \
--connect jdbc:mysql://bigdata11:3306/test \
--username root \
--password 000000 \
--query "SELECT * FROM student"
參數:
5.2.10、命令&參數:import-all-tables
可以將RDBMS中的所有表導入到HDFS中,每一個表都對應一個HDFS目錄
命令:
如:注意:(卡住)
$ bin/sqoop import-all-tables \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000 \
--hive-import \
--fields-terminated-by "\t"
bin/sqoop-import-all-tables --connect jdbc:mysql://bigdata111:3306/test --username root --password 000000 --as-textfile --warehouse-dir /user/root/plus -m 1
參數:
5.2.11、命令&參數:job
用來生成一個sqoop任務,生成后不會立即執行,需要手動執行。
命令:
如:
$ bin/sqoop job \
--create myjob -- import-all-tables \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000
$ bin/sqoop job \
--list
$ bin/sqoop job \
--exec myjob1
尖叫提示:注意import-all-tables和它左邊的--之間有一個空格
尖叫提示:如果需要連接metastore,則--meta-connect
執行的結果在HDFS:/user/root/ 目錄中,即導出所有表到/user/root中
參數:
尖叫提示:在執行一個job時,如果需要手動輸入數據庫密碼,可以做如下優化
<property>
<name>sqoop.metastore.client.record.password</name>
<value>true</value>
<description>If true, allow saved passwords in the metastore.</description>
</property>
5.2.12、命令&參數:list-databases
命令:
如:
$ bin/sqoop list-databases \
--connect jdbc:mysql://bigdata113:3306/ \
--username root \
--password 000000
參數:與公用參數一樣
5.2.13、命令&參數:list-tables
命令:
如:
$ bin/sqoop list-tables \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000
參數:與公用參數一樣
5.2.14、命令&參數:merge
將HDFS中不同目錄下面的數據合并在一起并放入指定目錄中
數據環境:注意:以下數據自己手動改成\t
new_staff
1 AAA male
2 BBB male
3 CCC male
4 DDD male
old_staff
1 AAA female
2 CCC female
3 BBB female
6 DDD female
尖叫提示:上邊數據的列之間的分隔符應該為\t,行與行之間的分割符為\n,如果直接復制,請檢查之。
命令:
如:
創建JavaBean:
$ bin/sqoop codegen \
--connect jdbc:mysql://bigdata112:3306/test \
--username root \
--password 000000 \
--table student \
--bindir /opt/Desktop/student \
--class-name Student \
--fields-terminated-by "\t"
開始合并:注:是hdfs路徑
$ bin/sqoop merge \
--new-data /new/ \
--onto /old/ \
--target-dir /test/merged1 \
--jar-file /opt/Desktop/student/Student.jar \
--class-name Student \
--merge-key id
結果:
1 AAA MALE
2 BBB MALE
3 CCC MALE
4 DDD MALE
6 DDD FEMALE
參數:
5.2.15、命令&參數:metastore
記錄了Sqoop job的元數據信息,如果不啟動該服務,那么默認job元數據的存儲目錄為~/.sqoop,可在sqoop-site.xml中修改。
命令:
如:啟動sqoop的metastore服務
$ bin/sqoop metastore
參數: