1. 程式人生 > >sqoop將Mysql資料匯入Hive中

sqoop將Mysql資料匯入Hive中

  • 注:筆者用的是sqoop1.4.6版本

一、將Mysql資料匯入Hive中

命令:

sqoop import  
-Dorg.apache.sqoop.splitter.allow_text_splitter=true       
--connect jdbc:mysql://xxx:3306/db 
--username user 
--password pwd 
--table  tablename 
--hive-import 
--hive-table tablename 

如果該表沒有主鍵:可將其執行在一個map中,如下

sqoop import 
--connect jdbc:
mysql://xxx:3306/db
--username user --password pwd --table tablename --hive-import --hive-table tablename -m 1

操作例項:
建立mysql表testSqoop

DROP TABLE IF EXISTS `testsqoop`;
CREATE TABLE `testsqoop` (
  `XH` varchar(255) CHARACTER SET utf8 NOT NULL COMMENT '序號',
  `SSQ` varchar(255) CHARACTER SET utf8 DEFAULT
NULL COMMENT '所屬區' ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

插入測試資料:

INSERT INTO `testsqoop` VALUES ('1', '海珠區');
INSERT INTO `testsqoop` VALUES ('10', '白雲區');
INSERT INTO `testsqoop` VALUES ('11', '黃埔區');
INSERT INTO `testsqoop` VALUES ('12', '荔灣區');
INSERT INTO `testsqoop` VALUES ('13', '天河區');
INSERT INTO `testsqoop` VALUES ('
14', '海珠區'); INSERT INTO `testsqoop` VALUES ('15', '海珠區'); INSERT INTO `testsqoop` VALUES ('16', '海珠區'); INSERT INTO `testsqoop` VALUES ('17', '荔灣區'); INSERT INTO `testsqoop` VALUES ('18', '海珠區'); INSERT INTO `testsqoop` VALUES ('19', '黃埔區'); INSERT INTO `testsqoop` VALUES ('2', '黃埔區'); INSERT INTO `testsqoop` VALUES ('20', '黃埔區'); INSERT INTO `testsqoop` VALUES ('21', '番禺區'); INSERT INTO `testsqoop` VALUES ('22', '花都區'); INSERT INTO `testsqoop` VALUES ('23', '海珠區'); INSERT INTO `testsqoop` VALUES ('24', '白雲區'); INSERT INTO `testsqoop` VALUES ('25', '花都區'); INSERT INTO `testsqoop` VALUES ('26', '海珠區'); INSERT INTO `testsqoop` VALUES ('27', '番禺區'); INSERT INTO `testsqoop` VALUES ('28', '天河區');
  • 執行匯入Hive的命令(如果Hive中沒有存在對應的hive表,則會依據mysql 的表來建立對應的表,欄位屬性也跟mysql的一致)

  • 1、這張表不存在的情況下(預設會自動建立對應的Hive表並全量將資料載入進去)

sqoop import 
--connect jdbc:mysql://xxx:3306/db 
--username xxx --password xxx 
--table  testSqoop 
--hive-import 
--hive-table testSqoop -m 1

hive中資料如下所示:

hive> select * from testSqoop;
OK
1       海珠區
10      白雲區
11      黃埔區
12      荔灣區
13      天河區
14      海珠區
15      海珠區
16      海珠區
17      荔灣區
18      海珠區
19      黃埔區
2       黃埔區
20      黃埔區
  • 2、這張表存在的情況下(預設往表中追加資料)
sqoop import 
--connect jdbc:mysql://xxx:3306/db 
--username xxx 
--password xxx 
--table  testSqoop 
--hive-import 
--hive-table testSqoop -m 1
  • 3、複雜查詢條件匯入

    where 引數的使用

sqoop import -Dorg.apache.sqoop.splitter.allow_text_splitter=true 
--connect jdbc:mysql://192.168.1.2:3306/test 
--username root 
--password 123456 
--table  test1 
--where 
   " SXQMC='廣東省廣州市蘿崗區' and XZJDMC='九龍鎮' and BMC='女' and S_LAST_UPDATED > '2018-01-04 03:10:13'  and  S_LAST_UPDATED < '2018-01-04 03:21:00' "  
--hive-import 
--hive-table test1  
--hive-drop-import-delims

query 引數的使用

sqoop import 
-Dorg.apache.sqoop.splitter.allow_text_splitter=true 
--connect jdbc:mysql://192.168.1.2:3306/test 
--username root 
--password 123456  
--query  
   " select * from test1  where SXQMC='廣東省廣州市番禺區' and BMC='女' and S_LAST_UPDATED > '2018-01-04 03:10:13'  and  S_LAST_UPDATED < '2018-01-04 03:21:00'  AND \$CONDITIONS"  
--hive-import 
--hive-table test1  
--hive-drop-import-delims 
--target-dir  /apps/hive/warehouse/test1   
--split-by s_duid 

二、 sqoop 中匯入常用引數簡要說明

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

三、遇到的問題:

問題一:
出現如下錯誤提示:No primary key could be found for table t_gz_cyyqmcb

 17/12/13 10:35:58 ERROR tool.ImportTool: Error during import: No primary key could be found for table t_gz_cyyqmcb.

這裡寫圖片描述

解決方法一:給該表新增主鍵便可;

解決方法二:加到sqoop 對應的引數 -m 1 ,也就是該命令只在一個mapreduce程序中進行,所以該方法會使得資料抽取的效率變低。

 sqoop import 
 --connect jdbc:mysql://xxx:3306/db 
 --username xxx  
 --password xxx 
 --table t_gz_cyyqmcb  
 --hive-import  
 --hive-table t_gz_cyyqmcb -m 1 

問題二:有關sqoop 分割符的問題

  • 在將mysql 中的資料匯入到hive中,mysql 中的資料如下;
  • 如XH=1在mysql中這是一條資料,但是資料對應的某一列資料有換行符。

這裡寫圖片描述

  • 在進行sqoop import 資料時,如果不加其他引數,匯入的資料預設的列分隔符是’\001’,預設的行分隔符是’\n’。也就像下面的資料那樣,在匯入時出現換行符時hive以為這條資料已經結束,並將其後面輸入的資料當做另一條資料。
    因而hive 預設會解析成兩條資料,這樣就造成匯入資料時出現了資料跟原表不一致的問題。如下圖所示:
sqoop import  
--connect jdbc:mysql://xxx:3306/db  
--username xxx  
--password xxx  
--table  testSqoop  
--hive-import  
--hive-table testSqoop -m 1

這裡寫圖片描述

解決方法:
加上引數–hive-drop-import-delims來把匯入資料中包含的hive預設的分隔符去掉
命令如下所示:

sqoop import  
--connect jdbc:mysql://xxx:3306/db  
--username xxx  
--password xxx  
--table  testSqoop  
--hive-import  
--hive-table testSqoop -m 1  
--hive-drop-import-delims

這裡寫圖片描述

問題三: No columns to generate for ClassWriter

ERROR tool.ImportTool: Encountered IOException running import job: java.io.IOException: No columns to generate for ClassWriter 

這個是由於mysql-connector-java的bug造成的,出錯時我用的是mysql-connector-java-5.1.17,更新成mysql-connector-java-5.1.36.jar就可以了。
上面替換的jar包是sqool lib下對應的包。
如:筆者該jar包對應的目錄為:/usr/hdp/2.5.3.0-37/sqoop/lib

  • 注:筆者的環境是開啟了kerberos認證安全機制,因此在進行sqoop導資料前得先進行kerberos認證。