1. 程式人生 > >Hive中Sqoop的基本用法和常見問題

Hive中Sqoop的基本用法和常見問題

一、通過Sqoop將Hive表資料匯入到Mysql

1、第一種是將hive上某張表的全部資料匯入到mysql對應的表中。

2、第二種是將hive上某張表中的部分資料匯入到mysql對應的表中。

兩種方式的區別在於第二種情況需要指定要匯入資料的列名稱。兩種情況的匯入方式分別如下:

1.全部匯入

Sqoop export --connect jdbc:mysql://127.0.0.1:3306/dbname?useUnicode=true&characterEncoding=utf-8 --username mysql(mysql使用者名稱) --password 123456(密碼) --table  student(mysql上的表) --export-dir /user/hive/warehouse/tablename(hive上的表) --input-null-string "\\N" --input-null-non-string "\\N" --fields-terminated-by "," --lines-terminated-by '\n'

說明:

dbname?useUnicode=true&characterEncoding=utf-8:設定資料庫的編碼格式

--export-dir:指定hive表的儲存路徑,資料儲存在HDFS中

--input-null-string "\\N" --input-null-non-string "\\N":為了避免空值時,沒有資料,需要該命令

--fields-terminated-by ","  :指定行內資料的分隔符

 --lines-terminated-by '\n':指定行間資料的分隔符

2.部分匯入

Sqoop export --connect  jdbc:mysql://127.0.0.1:3306/dbname  --username mysql(mysql使用者名稱) --password 123456(密碼) --table  student(mysql上的表) --columns "id,name,age"  --hcatalog-database sopdm(hive上的schema) --hcatalog-table student(hive上的表)

說明:

--columns :匯入表中的部分欄位,後面跟指定的列名;

--where :可以按條件匯入資料;

sqoop import \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root --password 123456 \
--table stu \
--mapreduce-job-name FromMySQL2HDFS \
--delete-target-dir \
--fields-terminated-by '\t' \
-m 1 \
--null-string 0 \
--columns "name" \
--target-dir STU_COLUMN_WHERE \
--where 'id<3'

--query :按照查詢條件匯入資料,使用--query關鍵字,就不能使用--table和--columns 

自定義sql語句的where條件中必須包含字串 $CONDITIONS,$CONDITIONS是一個變數,用於給多個map任務劃分任務範 圍;

sqoop import \
--connect jdbc:mysql://localhost:3306/sqoop \
--username root --password 123456 \
--mapreduce-job-name FromMySQL2HDFS \
--delete-target-dir \
--fields-terminated-by '\t' \
-m 1 \
--null-string 0 \
--target-dir STU_COLUMN_QUERY \
--query "select * from stu where id>1 and \$CONDITIONS"
                                                         

3.匯入分割槽表到MySQL

從HIVE分割槽表匯入到MySQL,需要依次匯入每個分割槽的資料

sqoop export   \
--connect jdbc:mysql://server74:3306/Server74   \
--username root   \
--password 123456   \
--table dw_pvs_hour \
--hive-partition-key datestr \
--hive-partition-value ‘2017-11-05’ \
--export-dir /user/hive/warehouse/dw_pvs_hour/datestr=2017-11-15/  \
--input-fields-terminated-by '\001'   \
--input-lines-terminated-by '\n'

根據官方文件的說法,---export-dir這個引數是必須的,指定hive表原始檔路徑後,sqoop回到路徑下路徑下的檔案,檔案不是路徑否則報錯。所以分割槽表需要單獨指定每個分割槽的目錄,分別匯入。

二、通過Sqoop將MySQL表資料匯入到Hive中

1、將mysql當中的資料直接匯入到hive當中

sqoop import --connect jdbc:mysql://192.168.1.10:3306/itcast --username root --password 123 --table trade_detail --hive-import --hive-overwrite --hive-table trade_detail --input-null-string "\\N" --input-null-non-string "\\N"  --fields-terminated-by ","   --lines-terminated-by '\n'

sqoop import --connect jdbc:mysql://localhost:3306/test --username root --password 123456 --table person --hive-import --target-dir temp -m 1 --hive-overwrite  --input-null-string "\\N" --input-null-non-string "\\N"  --fields-terminated-by ","   --lines-terminated-by '\n'

sqoop import --connect jdbc:mysql://192.168.7.7:3306/asto_ec_web --username root --password password --table shop_tb  --target-dir /ysf/input/shop_tb --fields-terminated-by ','

使用--hive-import就可以將資料匯入到hive中;

hive-overwrite引數:在匯入表的時候對錶的資料進行覆蓋;

fields-terminated-by引數:改變預設的分隔符;

-m 1:表示啟動一個map程式,如果資料量比較大可以啟動多個,預設啟動4個;

--hive-partition-key dt  --hive-partition-value "2018-08-08":匯入資料到指定的分割槽,即dt='2018-08-08'。

三、通過Sqoop將SQLServer表資料匯入到Hive中

首先需要在叢集機器上安裝sqlserver的jdbc包,sqoop的寫法如下:

import--driver com.microsoft.sqlserver.jdbc.SQLServerDriver --connect jdbc:sqlserver://10.177.0.164:49376;database=資料庫名 --username 使用者名稱--password  密碼 --table testtable --null-non-string \\N --null-string \\N --lines-terminated-by \n  --hive-import --hive-overwrite --hive-table database.testtable  --delete-target-dir -m 1 --fields-terminated-by ','

–create-hive-table :建立目標表,如果有會報錯; 

–hive-database:指定hive資料庫; 

–hive-import :指定匯入hive(沒有這個條件匯入到hdfs中); 

–hive-overwrite :覆蓋源資料; 

–hive-table stu_import :指定hive中表的名字,如果不指定使用匯入的表的表名。

--delete-target-dir :表示刪除目標目錄,再匯入資料;

-m 1:表示啟動一個map程式。

四、Sqoop同步需要注意的幾個常見問題:

1、Sqoop將hive表同步MySQL時,需要先在mysql構建對應的表;將MySQL表同步到Hive時,可以不建表直接同步,但是沒有欄位說明,一般情況下寫好建表語句建表再進行同步

2、Hive中建表的時候也需要定義fields-terminated-by、lines-terminated-by,Hive表的資料是以檔案的形式儲存在HDFS上,定義fields-terminated-by非常關鍵,實際情況中資料之間的分隔有空格、逗號、tab、\001等,如果資料某一列包含了如逗號,那麼表的分隔符就不能使用逗號分隔,預設使用‘\001’。如果表的fields分隔使用了逗號,sqoop就會報錯。

3、Sqoop的過程中也需要注意欄位型別的不同,Hive的常用型別是int、bigint、double、string,而且Hive中不需要定義欄位長度;MySQL中一般都會預設定義欄位型別及長度,所以在Sqoop資料從hive到mysql的時候就要控制好欄位長度、資料型別。特別注意時間格式,在Hive中時間一般用string型別,在時間計算插入hive表的時候最好不要用timestamp,如current_timestamp,考慮用格式化後的年月日時分秒,如當前時間作為create_time則用from_unixtime(unix_timestamp()),這樣在mysql中可能用datetime就不會報錯。

4、useUnicode=true&characterEncoding=utf-8:設定資料庫的編碼格式,避免出現中文亂碼的問題; --input-null-string "\\N" --input-null-non-string "\\N":為了避免空值時,沒有資料,需要該命令;一般這兩句話在寫sqoop語句時儘量帶上,確保不會出現問題。

(1) –null-string含義是 string型別的欄位,當Value是NULL,替換成指定的字元"\\N"; 
(2) –null-non-string 含義是非string型別的欄位,當Value是NULL,替換成指定字元"\\N"。

5、在進行資料同步的時候,一定要注意表名是否一致,特別是大小寫要留意。Hive建表後表名是不區分大小寫的,但是HDFS中的檔名是有大小寫的,所以MySQL中一定要對應上大小寫,hive建表用的大寫MySQL建表則也大寫,否則也會報錯,導致資料無法同步。