Sqoop 數據遷移

Sqoop 基本概念

Apache Sqoop是一個性能高、易用、靈活的數據導入導出工具,在關係型數據庫與Hadoop之間搭建了一個橋樑。
php

# 應用場景
須要將HDFS或Hive上的數據導出到傳統關係型數據庫中(如MySQL、Oracle等),或者將傳統關係型數據庫中的數據導入到HDFS或Hive上,若是經過人工手動進行數據遷移的話,就會顯得很是麻煩。爲此,可以使用Apache提供的Sqoop工具進行數據遷移。
- 數據遷移
企業大數據平臺關係型數據倉庫中的數據以分析爲主,綜合考慮擴展性、容錯性和成本開銷等方面。若將數據遷移到Hadoop大數據平臺上,能夠方便地使用Hadoop提供的如Hive、SparkSQL分佈式系統等工具進行數據分析。爲了一次性將數據導入Hadoop存儲系統,可以使用Sqoop。
- 可視化分析結果
Hadoop處理的輸入數據規模多是很是龐大的,好比PB級別,但最終產生的分析結果可能不會太大,好比報表數據等,而這類結果一般須要進行可視化,以便更直觀地展現分析結果。目前絕大部分可視化工具與關係型數據庫對接得比較好,所以,比較主流的作法是,將Hadoop產生的結果導入關係型數據庫進行可視化展現。
- 數據增量導入
考慮到Hadoop對事務的支持比較差,所以,凡是涉及事務的應用,好比支付平臺等,後端的存儲均會選擇關係數據庫,而事務相關的分析數據,好比用戶支付行爲等,可能在Hadoop分析過程當中用到(好比廣告系統,推薦系統等)。爲了減小Hadoop分析過程當中影響這類系統的性能,咱們一般不會直接讓Hadoop訪問這些關係型數據庫,而是單獨導入一份到Hadoop存儲系統中。

工做流程

從圖能夠看出,經過客戶端CLI(命令行界面)方式或JavaAPI方式調用Sqoop工具,Sqoop能夠將指令轉換爲對應的MapReduce做業(一般只涉及到Map任務,每一個Map任務從數據庫中讀取一片數據,這樣多個Map任務實現併發的拷貝,能夠快速的將整個數據拷貝到HDFS上),而後將關係型數據庫和Hadoop中的數據進行相互轉換,從而完成數據的遷移。

導入原理(HADOOP--->關係型數據庫)

在導入數據以前,Sqoop 使用 JDBC 檢查導入的數據表,檢索出表中的全部列以及列的SQL數據類型,並將這些SQL類型映射爲Java數據類型.
在轉換後的 MapReduce 應用中使用這些對應的Java類型來保存字段的值,Sqoop的代碼生成器使用這些信息來建立對應表的類,用於保存從表中抽取的記錄。

導出原理

在導出數據以前, Sqoop 會根據數據庫鏈接字符串來選擇一個導出方法,對於大部分系統來講,Sqoop會選擇JDBC。
Sqoop會根據目標表的定義生成一個Java類,這個生成的類可以從文本中解析出記錄數據,並可以向表中插入類型合適的值.
而後啓動一個 MapReduce 做業,從HDFS中讀取源數據文件,使用生成的類解析出記錄,而且執行選定的導出方法。

掌握Sqoop的安裝配置和導入導出操做

SQOOP 安裝配置

  • 下載
    sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz
  • 上傳
    cd /export/softwares
  • 解壓至 /export/servers
    tar -zxvf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C ../servers/
  • 重命名爲 sqoop-1.4.6
    mv sqoop-1.4.6.bin__hadoop-2.0.4-alpha sqoop-1.4.6
  • 配置Sqoop
# 賦值模板文件
cp sqoop-env-template.sh sqoop-env.sh
# 參數設置
#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/export/servers/hadoop-2.7.5

#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/export/servers/hadoop-2.7.5

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

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

#Set the path for where zookeper config dir is
export ZOOCFGDIR=/export/servers/zookeeper-3.4.9

# 系統環境變量配置
vim /etc/profile

export SQOOP_HOME=/export/servers/sqoop-1.4.6
export PATH=:$SQOOP_HOME/bin:$PATH

source /etc/profile
# 上傳mysql驅動包至 sqoop的lib目錄下
cd /export/servers/sqoop-1.4.6/lib

Sqoop測試及經常使用指令

鏈接測試

[root@node03 sqoop-1.4.6]# bin/sqoop help
html

  • 鏈接mysql
  • 列出數據庫
    sqoop list-databases --username root --password 123456 --connect jdbc:mysql://node03:3306/
  • 列出表格
    sqoop list-tables --username root --password 123456 --connect jdbc:mysql://node03:3306/taobao

經常使用指令

# 查看導出到關係型數據庫操做的參數
sqoop help export

sqoop 數據導入導出案例

數據

是將關係型數據庫中的單個表數據導入到HDFS,HIVE等具備HADOOP分佈式存儲結構的文件系統中
# 建立userdb數據庫,裏面添加三張表 emp, emp_add和emp_contact
# emp 
create table emp(
id int,
name varchar(20),
deg varchar(20),
salary  int,
dept varchar(20)
);
# 插入數據
insert into emp values(1201,'gopal','manager',50000,'TP');
insert into emp values(1202,' manisha ',' Proof reader',50000,'TP');
insert into emp values(1203,' khalil','php dev',30000,'AC');
insert into emp values(1204,' prasanth',' php dev',30000,'AC');
insert into emp values(1205,' kranthi',' admin',20000,'TP');
# emp_add
create table emp_add(
id int,
hno varchar(20),
street varchar(20),
city varchar(20)
);

# 插入數據
insert into emp_add values(1201,'288A','vgiri','jublee');
insert into emp_add values(1202,'1801','aoc','sec-bad');
insert into emp_add values(1203,'144Z','pguttai','hyd');
insert into emp_add values(1204,'78B','old city','sec-bad');
insert into emp_add values(1205,'720X','hitec','sec-bad');
# emp_conn
create table emp_conn(
id int,
phno int,
email varchar(20)
);

# 插入數據
insert into emp_conn values(1201,'2356742','gopal@tp.com');
insert into emp_conn values(1202,'1661663','manisha@tp.com');
insert into emp_conn values(1203,'8887776','khalil@ac.com');
insert into emp_conn values(1204,'9988774','prasanth@ac.com');
insert into emp_conn values(1205,'1231231','kranthi@tp.com');

從MySQL數據庫服務器中的emp表導入HDFS

# 啓動 hadoop 集羣
# 執行 
sqoop import --connect jdbc:mysql://node03:3306/userdb --username root --password 123456 --table emp --m 1
- --m 1表示設置一個mapper任務
# 執行成功,數據在 http://node01:50070/explorer.html#/user/root/emp 打開
# 也能夠設置輸出路徑  --target-dir /sqoopresult
sqoop import --connect jdbc:mysql://node03:3306/userdb --username root --password 123456 --target-dir /sqoopresult --table emp --num-mappers 1

# 查看方式 2
hdfs dfs -cat /user/root/emp/part-m-00000

增量導入

當MySQL表中的數據發生了新增或修改變化,須要更新HDFS上對應的數據時,就可使用Sqoop的增量導入功能。
Sqoop目前支持兩種增量導入模式:append模式和lastmodified模式。
- append模式主要針對INSERT新增數據的增量導入;
- lastmodified模式主要針對UPDATE修改數據的增量導入。
- 在進行增量導入操做時,首先必須指定「-check-column」參數,用來檢查數據表列字段,從而肯定哪些數據須要執行增量導入。
- 例如,在執行append模式增量導入時,一般會將「check-column」參數指定爲具備連續自增功能的列(如主鍵id);
- 執行lastmodified模式增量導入時,一般會將「--check-column」參數必須指定爲日期時間類型的列(如date 或timestamp類型的列)。
# 在mysql中插入數據
INSERT INTO emp VALUES(1206,'ttw','feis',40000,'th');
# 執行增量導入
sqoop import --connect jdbc:mysql://node03:3306/userdb --username root --password 123456 --table emp --incremental append --check-column id --last-value 1205 --num-mappers 1
# 查看
hdfs dfs -cat /user/root/emp/part-m-00001

mysql表數據導入HIVE

# 打開hive 
cd /export/servers/apache-hive-2.1.1-bin/
bin/hive
 show databases;
- 包含test數據庫,下面將emp_add 上傳至 HIVE上的目標地址爲 test 數據倉庫的 emp_add_sp表中、
sqoop import --connect jdbc:mysql://node03:3306/userdb --u root --p 123456 --table emp_add --hive-table mytest.emp_add_sp --create-hive-table --hive-import --m 1
# 查看
- 在 hive 中進入數據庫-表,select *
- 在 hdfs中打開: /user/hive/warehouse/mytest.db/emp_add_sp/part-m-00000
hdfs dfs -cat /user/hive/warehouse/mytest.db/emp_add_sp/part-m-00000

MySQL 表數據的子集導入

實際業務中,開發人員可能須要只針對部分數據進行導入操做
-使用sqoop提供的 where 和 query 參數,先進行數據過濾,例如,將表emp_add中 city=sec-bad 的數據導入HDFS 中

# where 進行數據過濾
sqoop import \
--connect jdbc:mysql://node03:3306/userdb \
--username root --password '123456' \
--where "city ='sec-bad'" \
--target-dir /wherequery \
--table emp_add --m 1

# query 進行數據過濾


sqoop import \
--connect jdbc:mysql://node03:3306/userdb \
--username root --password '123456' \
--target-dir /wherequery \
--query 'select id,name,deg FROM emp WHERE id>1203 AND $CONDITIONS' \
--m 1
上述代碼示例中,使用了Sqoop的「-query」參數進行數據過濾,它的主要做用就是先經過該參數指定的查詢語句查詢出子集數據,而後再將子集數據進行導入。上述示例中,$CONDITIONS至關於一個動態佔位符,動態的接收傳過濾後的子集數據,而後讓每一個Map任務執行查詢的結果並進行數據導入。

(1)若是沒有指定「-num-mappers 1」(或-m 1,即map任務個數爲1),那麼在指令中必須還要添加「-split-by」參數。「-split-by」參數的做用就是針對多副本map任務並行執行查詢結果並進行數據導入,該參數的值要指定爲表中惟一的字段(例如主鍵id);
(2)「-query」參數後的查詢語句中(例如示例中單引號中的SELECT語句),若是已經使用了WHERE關鍵字,那麼在鏈接SCONDITIONS佔位符前必須使用AND關鍵字;不然,就必須使用WHERE關鍵字鏈接;
(3)「-query」參數後的查詢語句中的$CONDITIONS佔位符不可省略,而且若是查詢語句使用雙引號(")進行包裝,那麼就必須使用\$CONDITIONS,這樣能夠避免Shell將其視爲Shell變量。

sqoop數據導出

# 數據庫中新建一張表 emp_export

DROP TABLE IF EXISTS emp_export;
CREATE TABLE emp_export(
id INT,
NAME VARCHAR(20),
deg VARCHAR(20),
salary  INT,
dept VARCHAR(20),
PRIMARY KEY (id)
);
# 數據導出(將HDFS上的文件導入到mysql中)
sqoop export \
--connect jdbc:mysql://node03:3306/userdb \
--username root \
--password 123456 \
--table emp_export \
--export-dir /user/root/emp
# 導出結果
![](https://img2020.cnblogs.com/blog/1044397/202008/1044397-20200802224322490-645300066.png)
相關文章
相關標籤/搜索