Sqoop
Sqoop是一款開源的工具,主要用於在HADOOP不傳統的數據庫(mysql、postgresql等)進行數據的傳遞,可以將一個關係型數據庫(例如:MySQL、Oracle、Postgres等)中的數據導進到Hadoop的HDFS中,也可以將HDFS的數據導進到關係型數據庫中。 Sqoop中一大亮點就是可以通過hadoop的mapreduce把數據從關係型數據庫中導入數據到HDFS。
版本選擇
CDH 5.3.x 版本,非常的穩定,好用 cdh-5.3.6,各個版本之間的依賴和兼容不同
* hadoop-2.5.0-cdh5.3.6.tar.gz * hive-0.13.1-cdh5.3.6.tar.gz * zookeeper-3.4.5-cdh5.3.6.tar.gz * sqoop-1.4.5-cdh5.3.6.tar.gz 下載地址 http://archive.cloudera.com/cdh5/cdh/5/
sqoop安裝
tar -zxvf sqoop-1.4.5-cdh5.3.6.tar.gz -C /opt/cdh5.3.6
#在sqoop下的conf目錄下修改sqoop-env.sh
#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/opt/cdh-5.3.6/hadoop-2.5.0-cdh5.3.6
#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/opt/cdh-5.3.6/hadoop-2.5.0-cdh5.3.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=/opt/cdh-5.3.6/hive-0.13.1-cdh5.3.6
#Set the path for where zookeper config dir is
#export ZOOCFGDIR=
#RDBMS以Mysql數據庫爲例講解,拷貝jdbc驅動包到$SQOOP_HOME/lib目錄下
cp hive-0.13.1-cdh5.3.6/lib/mysql-connector-java-5.1.27-bin.jar sqoop-1.4.5-cdh5.3.6/lib/
sqoop常用命令
**************************************
sqoop-import 注意點
import 可能會用到的參數:
Argument Described
--append Append data to an existing dataset in HDFS
--as-sequencefile import序列化的文件
--as-textfile import plain文件 ,默認
--columns <col,col,col…> 指定列import,逗號分隔,比如:--columns "id,name"
--delete-target-dir 刪除存在的import目標目錄
--direct 直連模式,速度更快(HBase不支持)
--fetch-size <n> 一次從數據庫讀取 n 個實例,即n條數據
-m,--num-mappers <n> 建立 n 個併發執行task import
-e,--query <statement> 構建表達式<statement>執行
--split-by <column-name> 根據column分隔實例
--autoreset-to-one-mappe 如果沒有主鍵和split-by 用one mapper import (split-by 和此選項不共存)
--table <table-name> 指定表名import
--target-dir <d> HDFS destination dir
--warehouse-dir <d> HDFS parent for table destination
--where <where clause> 指定where從句,如果有雙引號,注意轉義 \$CONDITIONS,不能用or,子查詢,join
-z,--compress 開啓壓縮
--null-string <null-string> string列爲空指定爲此值
--null-non-string <null-string> 非string列爲空指定爲此值,-null這兩個參數are optional, 如果不設置,會指定爲"null"
列出mysql數據庫中的所有數據庫
bin/sqoop list-databases --connect jdbc:mysql://hadoop.jianxin.com:3306 --username root --password missandlove
**************************************
**************************************
建立mysql表
CREATE TABLE my_user(
`id` int(4) NOT NULL AUTO_INCREMENT,
`account` varchar(255) DEFAULT NULL,
`passwd` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
);
插入數據
INSERT INTO `my_user` VALUES ('1', 'admin', 'admin');
INSERT INTO `my_user` VALUES ('3', 'system', 'system');
INSERT INTO `my_user` VALUES ('5', 'lee', 'lee');
INSERT INTO `my_user` VALUES ('6', 'les', 'les');
INSERT INTO `my_user` VALUES ('7', 'jianxin', 'jianxin');
**************************************
**************************************
mysql導出數據
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com:3306/test \
--username root \
--password missandlove \
--table my_user
如果不指定–target-dir,數據會存儲在HDFS中的對應用戶名目錄下
**************************************
**************************************
導出到指定文件目錄下
sqoop 底層的實現就是MapReduce,import來說,僅僅運行Map Task
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com:3306/test \
--username root \
--password missandlove \
--table my_user \
--delete-target-dir \
--target-dir /user/jianxin/sqoop/import_myuser \
--num-mappers 3
**************************************
**************************************
數據導出儲存方式(數據存儲文件格式---( textfil parquet)
--as-textfile Imports data as plain text (default)
--as-parquetfile Imports data to Parquet Files
)
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com:3306/test \
--username root \
--password missandlove \
--table my_user \
--target-dir /user/jianxin/sqoop/import_myuser_parquet \
--delete-target-dir \
--num-mappers 3 \
--fields-terminated-by ',' \
--as-parquetfile
**************************************
**************************************
hive建立表
drop table if exists default.hive_user_prq;
create table default.hive_user_prq(
id int,
username string,
password string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS parquet;
數據入表
load data inpath '/user/jianxin/sqoop/import_myuser_parquet' into table default.hive_user_prq;
**************************************
**************************************
指定的列導入到數據庫
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com:3306/test \
--username root \
--password missandlove \
--table my_user \
--delete-target-dir \
--target-dir /user/jianxin/sqoop/import_column \
--as-parquetfile \
--num-mappers 3 \
--fields-terminated-by ',' \
--column id,account \
**************************************
**************************************
初步清洗和過濾數據
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com:3306/test \
--username root \
--password missandlove \
--table my_user \
--delete-target-dir \
--target-dir /user/jianxin/sqoop/import_query \
--as-parquetfile \
--num-mappers 3 \
--fields-terminated-by ',';
--query 'select id, account from my_user where $CONDITIONS'
使用query查詢導入必須指定條件$CONDITIONS,如果不指定將報錯。
create table query_table(id int ,account string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS parquet;
load data inpath '/user/jianxin/sqoop/import_query' into table query_table;
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com:3306/test \
--username root \
--password missandlove \
--table my_user \
--delete-target-dir \
--target-dir /user/jianxin/sqoop/import_query \
--as-parquetfile \
--num-mappers 3 \
--fields-terminated-by ',';
--query 'select id, account from my_user where id>1'
**************************************
**************************************
數據壓縮
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com/test \
--username root \
--password missandlove \
--table my_user \
--target-dir /user/jianxin/sqoop/imp_my_sannpy \
-- delete-target-dir \
--num-mappers 3 \
--compress \
-- compression-codec org.apache.hadoop.io.compress.SnappyCodec \
--fields-terminated-by ',' \
--as-parquetfile
**************************************
**************************************
數據的增量導入
sqoop
Incremental import arguments:
--check-column <column> Source column to check for incremental change
--incremental <import-type> Define an incremental import of type 'append' or 'lastmodified'
--last-value <value> Last imported value in the incremental check column
–check-column,用來指定一些列,這些列在導入時用來檢查做決定數據是否要被作爲增量數據,在一般關係型數據庫中,都存在類似Last_Mod_Date的字段或主鍵。注意:這些被檢查的列的類型不能是任意字符類型,例如Char,VARCHAR…(即字符類型不能作爲增量標識字段)
–incremental,用來指定增量導入的模式(Mode),append和lastmodified
–last-value,指定上一次導入中檢查列指定字段最大值
1、append,在導入的新數據ID值是連續時採用,對數據進行附加 加不加–last-value的區別在於:數據是否冗餘,如果不加,則會導入源表中的所有數據導致數據冗餘。
2、lastmodified,在源表中有數據更新的時候使用,檢查列就必須是一個時間戳或日期類型的字段,更新完之後,last-value會被設置爲執行增量導入時的當前系統時間,當使用–incremental lastmodified模式進行導入且導入目錄已存在時,需要使用–merge-key或–append
導入>=last-value的值。--incremental lastmodified --check-column created --last-value '2012-02-01 11:0:00'
就是隻導入created 比'2012-02-01 11:0:00'更大的數據。
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com:3306/test \
--username root \
--password missandlove \
--table my_user \
--target-dir /user/jianxin/sqoop/increament \
--num-mappers 1 \
--incremental append \
--check-column id \
--last-value 0
[root@hadoop hadoop-2.5.0-cdh5.3.6]# bin/hdfs dfs -cat /user/jianxin/sqoop/increament/part-m-00000
1,admin,admin
3,system,system
5,lee,lee
6,les,les
7,jianxin,jianxin
INSERT INTO `my_user` VALUES ('12', 'admin', 'admin');
INSERT INTO `my_user` VALUES ('11', 'system', 'system');
INSERT INTO `my_user` VALUES ('10', 'lee', 'lee');
INSERT INTO `my_user` VALUES ('8', 'les', 'les');
INSERT INTO `my_user` VALUES ('9', 'jianxin', 'jianxin');
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com:3306/test \
--username root \
--password missandlove \
--table my_user \
--target-dir /user/jianxin/sqoop/increament \
--num-mappers 1 \
--incremental append \
--check-column id \
--last-value 7
[root@hadoop hadoop-2.5.0-cdh5.3.6]# bin/hdfs dfs -cat /user/jianxin/sqoop/increament/part-m-00001
8,les,les
9,jianxin,jianxin
10,lee,lee
11,system,system
12,admin,admin
create table customer(id int,name varchar(20),last_mod timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
insert into customer(id,name) values(1,'neil');
insert into customer(id,name) values(2,'jack');
insert into customer(id,name) values(3,'martin');
insert into customer(id,name) values(4,'tony');
insert into customer(id,name) values(5,'eric');
mysql> select * from customer;
+------+--------+---------------------+
| id | name | last_mod |
+------+--------+---------------------+
| 1 | neil | 2018-04-26 14:00:08 |
| 2 | jack | 2018-04-26 14:00:08 |
| 3 | martin | 2018-04-26 14:00:08 |
| 4 | tony | 2018-04-26 14:00:08 |
| 5 | eric | 2018-04-26 14:00:09 |
+------+--------+---------------------+
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com/test \
--username root \
--password missandlove \
--table customer \
--target-dir /user/jianxin/sqoop/increament_bytime \
--num-mappers 1 \
--check-column last_mod \
--incremental lastmodified \
--last-value 0
[root@hadoop hadoop-2.5.0-cdh5.3.6]# bin/hdfs dfs -cat /user/jianxin/sqoop/increament_bytime/part-m-00000
1,neil,2018-04-26 14:00:08.0
2,jack,2018-04-26 14:00:08.0
3,martin,2018-04-26 14:00:08.0
4,tony,2018-04-26 14:00:08.0
5,eric,2018-04-26 14:00:09.0
使用lastmodified模式進行增量處理要指定增量數據是以append模式(附加)還是merge-key(合併)模式添加
insert into customertest(id,name) values(6,'james')
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com/test \
--username root \
--password missandlove \
--table customer \
--target-dir /user/jianxin/sqoop/increament_bytime \
--num-mappers 1 \
--check-column last_mod \
--incremental lastmodified \
--last-value '2018-04-26 14:00:09' \
--merge-key id
這種方式不會新建立hdfs文件系統下的文件
**************************************
**************************************
直接導入
bin/sqoop import \
--connect jdbc:mysql://hadoop.jianxin.com:3306/test \
--username root \
--password missandlove \
--table customer \
--num-mappers 1 \
--target-dir /user/jianxin/sqoop/derict \
--delete-target-dir
--direct
**************************************
**************************************
導出到數據庫
論據 描述
--connect <jdbc-uri> 指定JDBC連接字符串
--connection-manager <class-name> 指定要使用的連接管理器類
--driver <class-name> 手動指定要使用的JDBC驅動程序類
--hadoop-mapred-home <dir> 覆蓋$ HADOOP_MAPRED_HOME
--help 打印使用說明
--password-file 爲包含認證密碼的文件設置路徑
-P 從控制檯讀取密碼
--password <password> 設置驗證密碼
--username <username> 設置驗證用戶名
--verbose 在工作時打印更多信息
--connection-param-file <filename> 提供連接參數的可選屬性文件
--relaxed-isolation 將連接事務隔離設置爲未提交給映射器的讀取。
--columns <col,col,col…> 要導出到表格的列
--direct 使用直接導出快速路徑
--export-dir <dir> 用於導出的HDFS源路徑
-m,--num-mappers <n> 使用n個地圖任務並行導出
--table <table-name> 要填充的表
--call <stored-proc-name> 存儲過程調用
--update-key <col-name> 錨點列用於更新。如果有多個列,請使用以逗號分隔的列列表。
--update-mode <mode> 指定在數據庫中使用不匹配的鍵找到新行時如何執行更新。
mode包含的 updateonly默認 值(默認)和 allowinsert。
--input-null-string <null-string> 字符串列被解釋爲空的字符串
--input-null-non-string <null-string> 要對非字符串列解釋爲空的字符串
--staging-table <staging-table-name> 數據在插入目標表之前將在其中展開的表格。
--clear-staging-table 表示可以刪除登臺表中的任何數據。
--batch 使用批處理模式執行基礎語句。
touch /opt/datas/my_user_fromhive
[root@hadoop datas]# vi my_user_fromhive
16,hiveuser,hiveuser
18,hivemiss,hivemiss
[root@hadoop hadoop-2.5.0-cdh5.3.6]# bin/hdfs dfs -mkdir -p /user/jianxin/hive_to_mysql
[root@hadoop hadoop-2.5.0-cdh5.3.6]# bin/hdfs dfs -put /opt/datas/my_user_fromhive /user/jianxin/hive_to_mysql
bin/sqoop export \
--connect jdbc:mysql://hadoop.jianxin.com:3306/test \
--username root \
--password missandlove \
--table my_user \
--export-dir /user/jianxin/hive_to_mysql \
--num-mappers 1
mysql> select * from my_user;
+----+----------+----------+
| id | account | passwd |
+----+----------+----------+
| 1 | admin | admin |
| 3 | system | system |
| 5 | lee | lee |
| 6 | les | les |
| 7 | jianxin | jianxin |
| 8 | les | les |
| 9 | jianxin | jianxin |
| 10 | lee | lee |
| 11 | system | system |
| 12 | admin | admin |
| 13 | admin | admin |
| 16 | hiveuser | hiveuser |
| 18 | hivemiss | hivemiss |
+----+----------+----------+
**************************************
本文分享自微信公衆號 - 我愛問讀書(wawds_)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。