Sqoop 使用shell命令的各種引數的配置及使用方法
阿新 • • 發佈:2020-07-31
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
注意:
- 如果使用了--query,就不能指定--table,和--columns和--where
- --query 和 --table一定不能同時存在!
- --where和--query同時存在時,--where失效
- --columns和--query同時存在時,--where無效!
- --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