博客 / 詳情

返回

【趙渝強老師】大數據交換引擎Sqoop

Sqoop是SQL To Hadoop的簡稱,它是一款開源的工具,主要用於在Hadoop(Hive)與傳統的數據庫(Oracle、MySQL等)間進行數據的傳遞。通過使用Sqoop可以將一個關係型數據庫中的數據導進到Hadoop的HDFS中,也可以將HDFS的數據導進到關係型數據庫中。Sqoop是基於MapReduce完成數據的交換,因此在使用Sqoop之前需要部署Hadoop環境;另一方面,由於Sqoop交換的是關係型數據庫中的數據,因此底層需要JDBC驅動的支持。

Sqoop項目開始於2009年,最早是作為Hadoop的一個第三方模塊存在,後來為了讓使用者能夠快速部署,也為了讓開發人員能夠更快速的迭代開發,Sqoop獨立成為一個Apache項目。

視頻講解如下:
https://www.bilibili.com/video/BV1iQuyzZEH5/?aid=114855377902...

一、 準備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_HOME

PATH=$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"

image.png

(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() {
      @Override
      public 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

image.png

(4)將MySQL數據庫中的emp表導入到HDFS。命令執行完成後,查看HDFS目錄的內容,如下圖所示。

sqoop import --connect jdbc:mysql://localhost:3306/demo  \
--username root --password Welcome_1 --table emp --target-dir /myempdata

image.png

(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

image.png

(6)將MySQL數據庫中的所有表導入到HDFS。執行完成後默認將導入HDFS的/user/root目錄,如下圖所示。

sqoop import-all-tables --connect jdbc:mysql://localhost:3306/demo \
--username root --password Welcome_1

image.png

(7)列出MySQL的所有數據庫。命令執行完成後,如下圖所示。

sqoop list-databases --connect jdbc:mysql://localhost:3306/demo \
--username root --password Welcome_1

image.png

(8)列出MySQL數據庫中所有的表,執行結果如下圖所示。

sqoop list-tables --connect jdbc:mysql://localhost:3306/demo \
--username root --password Welcome_1

image.png

(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。
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.