1. 程式人生 > 實用技巧 >Sqoop 使用shell命令的各種引數的配置及使用方法

Sqoop 使用shell命令的各種引數的配置及使用方法

1、Sqoop簡介

  • Sqoop將使用者編寫的sqoop命令翻譯為MR程式,MR程式讀取關係型資料庫中的資料,寫入到HDFS或讀取HDFS上的資料,寫入到關係型資料庫
  • 在MR程式中如果要讀取關係型資料中的資料,必須制定輸入格式為DBInputformat
  • 在MR程式中如果要向關係型資料吸入資料,必須制定輸出格式為DBOutputformat
  • Sqoop命令執行的MR程式,只有Map階段,沒有reduce階段。只需要資料傳輸,不需要對資料進行合併和排序

2、Sqoop匯入資料

2.1 到入到HDFS

2.1.1 全表匯入

bin/sqoop import \
##連線的關係型資料庫的url,使用者名稱,密碼
--connect jdbc:mysql://hadoop102:3306/test \ --username root \ --password 123 \ ##連線的表 --table t_emp \ ##匯出資料在hdfs上存放路徑 --target-dir /sqoopTest \ ##如果路徑已存在則先刪除 --delete-target-dir \ ##匯入到Hdfs上後,每個欄位使用什麼引數進行分割 --fields-terminated-by "\t" \ ##要啟動幾個MapTask,預設4個 --num-mappers 2 \ ##資料集根據哪個欄位進行切分,切分後每個MapTask負責一部分
--split-by id \ ##要實現部分匯入,加入下面的引數,表示匯入哪些列 ##columns中如果涉及到多列,用逗號分隔,分隔時不要新增空格 --columns id,name,age

2.1.2 使用sqoop關鍵字篩選查詢匯入資料

bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/test \
--username root \
--password 123 \
--table t_emp \
##指定過濾的where語句,where語句最好使用引號包裹
--where 'id>6' \
--target-dir /sqoopTest \
--delete-target-dir \ --fields-terminated-by "\t" \ --num-mappers 1 \ --split-by id

2.1.3 使用查詢語句匯入

bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/test \
--username root \
--password 123 \
##查詢語句最好使用單引號
##如果query後使用的是雙引號,則$CONDITIONS前必須加轉移符,防止shell識別為自己的變數
--query 'select * from t_emp where id>3 and $CONDITIONS' \
--target-dir /sqoopTest \
--delete-target-dir \
--fields-terminated-by "\t" \
--num-mappers 1 \
--split-by id 

注意:

  1. 如果使用了--query,就不能指定--table,和--columns和--where
  2. --query 和 --table一定不能同時存在!
  3. --where和--query同時存在時,--where失效
  4. --columns和--query同時存在時,--where無效!
  5. --query 必須跟--target-dir

2.2 匯入到hive

bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/test \
--username root \
--password 123 \
--query 'select * from t_emp where id>3 and $CONDITIONS' \
--target-dir /sqoopTest \
##如果不限定分隔符,那麼hive儲存的資料將不帶分隔符,之後再想操作很麻煩,所以建議加上
--fields-terminated-by "\t" \
--delete-target-dir \
##匯入到hive
--hive-import \
##是否覆蓋寫,不加這個引數就是追加寫
--hive-overwrite \
##指定要匯入的hive的表名
--hive-table t_emp \
--num-mappers 1 \
--split-by id

原理還是分倆步:先把資料從關係資料庫裡導到hdfs中,然後再從hdfs中導到hive中,此時hdfs中的檔案會被刪除

注意:如果hive中沒表會自動建立表,但是型別是自動生成的,所以還是建議手動建立

也可以分倆步走:

(1)先匯入hdfs

#!/bin/bash
import_data(){
$sqoop import \
--connect jdbc:mysql://hadoop102:3306/gmall \
--username root \
--password 123 \
--target-dir /origin_data/gmall/db/$1/$do_date \
--delete-target-dir \
--query "$2 and  \$CONDITIONS" \
--num-mappers 1 \
--fields-terminated-by '\t' \
# 使用壓縮,和指定壓縮格式為lzop
--compress \
--compression-codec lzop \
#將String型別和非String型別的空值替換為\N,方便Hive讀取
--null-string '\\N' \
--null-non-string '\\N'
}

(2)利用 load data 命令匯入hive

注意:

  • Hive中的Null在底層是以“\N”來儲存,而MySQL中的Null在底層就是Null,為了保證資料兩端的一致性。
  • 在匯出資料時採用--input-null-string和--input-null-non-string兩個引數。
  • 匯入資料時採用--null-string和--null-non-string。

2.3 匯入到HBase

bin/sqoop import \
--connect jdbc:mysql://hadoop102:3306/test \
--username root \
--password 123 \
--query 'select * from t_emp where id>3 and $CONDITIONS' \
--target-dir /sqoopTest \
--delete-target-dir \
##表不存在是否建立
--hbase-create-table \
##hbase中的表名
--hbase-table "t_emp" \
##將匯入資料的哪一列作為rowkey
--hbase-row-key "id" \
##匯入的列族
--column-family "info" \
--num-mappers 2 \
--split-by id

當選用自動建立表時,如果版本不相容會報錯:

20/03/24 13:51:24 INFO mapreduce.HBaseImportJob: Creating missing HBase table t_emp
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.hadoop.hbase.HTableDescriptor.addFamily(Lorg/apache/hadoop/hbase/HColumnDescriptor;)V

此時只能自己手動建立或者可以重新編譯sqoop原始碼

如果要多列族匯入,只能多次執行命令,一次匯入一個列族

3、匯出

3.1 表為空表時

bin/sqoop export \
--connect 'jdbc:mysql://hadoop102:3306/test?useUnicode=true&characterEncoding=utf-8' \
--username root \
--password 123 \
##匯出的表名,需要自己提前建立好
--table t_emp2 \
--num-mappers 1 \
##hdfs上匯出的資料的路徑
--export-dir /user/hive/warehouse/t_emp \
##hdfs上資料的分隔符
--input-fields-terminated-by "\t"

3.2 表不為空時

如果插入的資料的主鍵和表中已有資料的主鍵衝突,那麼會報錯Duplicate entry '5' for key 'PRIMARY'

3.2.1 在mysql中

INSERT INTO t_emp2 VALUE(5,'jack',30,3,1111) 
ON DUPLICATE KEY UPDATE NAME=VALUES(NAME),deptid=VALUES(deptid),
empno=VALUES(empno);

指定當插入時,主鍵重複時時,對於重複的記錄,只做更新,不做插入!

而用sqoop時,則可以啟用以下倆種模式

3.2.2 updateonly模式

bin/sqoop export \
--connect 'jdbc:mysql://hadoop103:3306/mydb?useUnicode=true&characterEncoding=utf-8' \
--username root \
--password 123456 \
--table t_emp2 \
--num-mappers 1 \
--export-dir /hive/t_emp \
--input-fields-terminated-by "\t" \
--update-key id

利用 --update-key 欄位 ,表示主鍵重複時會進行更新,但是主鍵不重複的時候,資料不會插入進來

3.2.3 allowinsert模式

bin/sqoop export \
--connect 'jdbc:mysql://hadoop103:3306/mydb?useUnicode=true&characterEncoding=utf-8' \
--username root \
--password 123456 \
--table t_emp2 \
--num-mappers 1 \
--export-dir /hive/t_emp \
--input-fields-terminated-by "\t" \
--update-key id \
--update-mode  allowinsert

表示主鍵重複時會進行更新,主鍵不重複的時候,資料也會插入進來

3.3 檢視匯出命令的具體實現

3.3.1配置/etc/my.cnf

[mysqld]
#開啟binlog日誌功能
log-bin=mysql-bin

3.3.2重啟mysql服務

3.3.3進入/var/lib/mysql,呼叫方法

sudo mysqlbinlog mysql-bin.000001

原文地址:https://www.cnblogs.com/yangxusun9/p/12558683.html