Sqoop是SQL To Hadoop的簡稱,它是一款開源的工具,主要用于在Hadoop(Hive)與傳統的數據庫(Oracle、MySQL等)間進行數據的傳遞。通過使用Sqoop可以將一個關系型數據庫中的數據導進到Hadoop的HDFS中,也可以將HDFS的數據導進到關系型數據庫中。Sqoop是基于MapReduce完成數據的交換,因此在使用Sqoop之前需要部署Hadoop環境;另一方面,由于Sqoop交換的是關系型數據庫中的數據,因此底層需要JDBC驅動的支持。
Sqoop項目開始于2009年,最早是作為Hadoop的一個第三方模塊存在,后來為了讓使用者能夠快速部署,也為了讓開發人員能夠更快速的迭代開發,Sqoop獨立成為一個Apache項目。
視頻講解如下 |
---|
【趙渝強老師】大數據交換引擎Sqoop |
一、 準備Sqoop環境
Apache Sqoop的安裝部署比較簡單,直接解壓后就可以使用。由于Sqoop底層需要JDBC的支持。因此需要將對應關系型數據庫的JDBC Driver復制到Sqoop的lib目錄下。這里將在bigdata111的虛擬主機上來完成安裝和部署,并采集之前部署好的MySQL數據庫中的數據。下面通過具體的步驟來演示Sqoop的部署。
(1)將Sqoop的安裝包解壓到/root/training目錄。
tar -zxvf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C ~/training/
(2)將Sqoop的目錄進行重命名。
cd ~/training/
mv sqoop-1.4.7.bin__hadoop-2.6.0/ sqoop/
(3)將MySQL的JDBC Driver復制到Sqoop的lib目錄下。
cp mysql-connector-java-5.1.43-bin.jar ~/training/sqoop/lib/
(4)編輯文件/root/.bash_profile設置Sqoop相應的環境變量。
SQOOP_HOME=/root/training/sqoop
export SQOOP_HOMEPATH=$SQOOP_HOME/bin:$PATH
export PATH
(5)生效環境變量。
source /root/.bash_profile
(6)啟動Hadoop環境。
start-all.sh
(7)登錄MySQL數據庫執行下面的腳本建立測試數據。
create database if not exists demo;
use demo;create table emp
(empno int primary key,
ename varchar(10),
job varchar(10),
mgr int,
hiredate varchar(10),
sal int,
comm int,
deptno int);create table dept
(deptno int primary key,
dname varchar(10),
loc varchar(10)
);insert into emp values(7369,'SMITH','CLERK',7902,'1980/12/17',800,0,20);
insert into emp values(7499,'ALLEN','SALESMAN',7698,'1981/2/20',1600,300,30);
insert into emp values(7521,'WARD','SALESMAN',7698,'1981/2/22',1250,500,30);
insert into emp values(7566,'JONES','MANAGER',7839,'1981/4/2',2975,0,20);
insert into emp values(7654,'MARTIN','SALESMAN',7698,'1981/9/28',1250,1400,30);
insert into emp values(7698,'BLAKE','MANAGER',7839,'1981/5/1',2850,0,30);
insert into emp values(7782,'CLARK','MANAGER',7839,'1981/6/9',2450,0,10);
insert into emp values(7788,'SCOTT','ANALYST',7566,'1987/4/19',3000,0,20);
insert into emp values(7839,'KING','PRESIDENT',-1,'1981/11/17',5000,0,10);
insert into emp values(7844,'TURNER','SALESMAN',7698,'1981/9/8',1500,0,30);
insert into emp values(7876,'ADAMS','CLERK',7788,'1987/5/23',1100,0,20);
insert into emp values(7900,'JAMES','CLERK',7698,'1981/12/3',950,0,30);
insert into emp values(7902,'FORD','ANALYST',7566,'1981/12/3',3000,0,20);
insert into emp values(7934,'MILLER','CLERK',7782,'1982/1/23',1300,0,10);insert into dept values(10,'ACCOUNTING','NEW YORK');
insert into dept values(20,'RESEARCH','DALLAS');
insert into dept values(30,'SALES','CHICAGO');
insert into dept values(40,'OPERATIONS','BOSTON');
二、 使用Sqoop完成數據交換
下面將通過具體的操作步驟來演示如何使用Sqoop完成與關系型數據庫MySQL的數據交換。
(1)使用Sqoop執行一個簡單的查詢。這里將查詢10號部門的員工姓名、職位、薪水和部門號,結果如下圖所示。
sqoop eval --connect jdbc:mysql://localhost:3306/demo?useSSL=false \
--username root --password Welcome_1 --query \
"select ename,job,sal,deptno from emp where deptno=10"
(2)根據MySQL數據庫中的表結構生成對應的Java Class。
sqoop codegen --connect jdbc:mysql://localhost:3306/demo \
--username root --password Welcome_1 --table emp# 輸出的日志如下所示:
2021-04-22 14:34:42,491 INFO orm.CompilationManager: HADOOP_MAPRED_HOME is /root/training/hadoop-3.1.2
Note: /tmp/sqoop-root/compile/2abad54ace6665327b12e83a02b14a8f/emp.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
2021-04-22 14:34:45,173 INFO orm.CompilationManager: Writing jar file: /tmp/sqoop-root/compile/2abad54ace6665327b12e83a02b14a8f/emp.jar# 執行成功后,會自動將/tmp目錄下生成的emp.java拷貝至當前目錄,部分代碼如下:
public class emp extends SqoopRecord implements DBWritable, Writable {private final int PROTOCOL_VERSION = 3;public int getClassFormatVersion() { return PROTOCOL_VERSION; }public static interface FieldSetterCommand {void setField(Object value); } protected ResultSet __cur_result_set;private Map<String, FieldSetterCommand> setters = new HashMap<String, FieldSetterCommand>();private void init0() {setters.put("empno", new FieldSetterCommand() {@Overridepublic void setField(Object value) {emp.this.empno = (Integer)value;}});setters.put("ename", new FieldSetterCommand() {@Override# 這里可以看到emp類實現了Writable接口。按照開發MapReduce程序的要求,
# 該類可以作為MapReduce的Key或者Value。
(3)根據MySQL數據庫中的表結構生成對應的Hive表結構。命令執行完成后,查看Hive中的表結構信息如下圖所示。
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HIVE_HOME/lib/*sqoop create-hive-table --connect jdbc:mysql://localhost:3306/demo \
--username root --password Welcome_1 --table emp --hive-table emphive
(4)將MySQL數據庫中的emp表導入到HDFS。命令執行完成后,查看HDFS目錄的內容,如下圖所示。
sqoop import --connect jdbc:mysql://localhost:3306/demo \
--username root --password Welcome_1 --table emp --target-dir /myempdata
(5)將HDFS的數據導出到MySQL數據庫中。命令執行完成后,在MySQL中驗證數據是否導入如下圖所示。
# 先在MySQL中創建對應的表
create table mynewemp like emp;# 執行導入
sqoop export --connect jdbc:mysql://localhost:3306/demo \
--username root --password Welcome_1 \
--table mynewemp --export-dir /myempdata
(6)將MySQL數據庫中的所有表導入到HDFS。執行完成后默認將導入HDFS的/user/root目錄,如下圖所示。
sqoop import-all-tables --connect jdbc:mysql://localhost:3306/demo \
--username root --password Welcome_1
(7)列出MySQL的所有數據庫。命令執行完成后,如下圖所示。
sqoop list-databases --connect jdbc:mysql://localhost:3306/demo \
--username root --password Welcome_1
(8)列出MySQL數據庫中所有的表,執行結果如下圖所示。
sqoop list-tables --connect jdbc:mysql://localhost:3306/demo \
--username root --password Welcome_1
(9)將MySQL表的數據導入HBase。
#進入HBase Shell創建表
create 'emp','empinfo'#執行導入
sqoop import --connect jdbc:mysql://localhost:3306/demo \
--username root --password Welcome_1 --table emp \
--columns empno,ename,sal,deptno \
--hbase-table emp --hbase-row-key empno --column-family empinfo# Sqoop導入數據到HBase時,HBase的版本不能太高,建議使用HBase 1.3.6。