Sqoop使用筆記

[TOC]

最近在研究數(shù)據(jù)采集相關(guān)的知識(shí),需要用到Sqoop把關(guān)系型數(shù)據(jù)庫的數(shù)據(jù)導(dǎo)入到Hive里,這里記錄下自己的使用心得,更多的是需要注意的地方。

環(huán)境準(zhǔn)備

OS: MacOS
Hadoop: 2.7.2
Hive: 1.0.0
Sqoop: 1.4.6

根據(jù)Sqoop官網(wǎng)說法,Sqoop2 目前還未開發(fā)完,不建議在生產(chǎn)環(huán)境使用,所以這里選的是Sqoop的穩(wěn)定版 1.4.6
Hadoop和Hive的安裝與配置可以參考網(wǎng)上的資料,Sqoop環(huán)境配置注意修改 ${SQOOP_HOME}/conf/sqoop_env.sh ,如果使用MySQL,還要將MySQL的驅(qū)動(dòng)jar包拷貝到 ${SQOOP_HOME}/lib 目錄下

Sqoop簡(jiǎn)介

Sqoop是一個(gè)用于Hadoop和關(guān)系型數(shù)據(jù)庫或主機(jī)之間的數(shù)據(jù)傳輸工具。它可以將數(shù)據(jù)從關(guān)系型數(shù)據(jù)庫import到HDFS,也可以從HDFS export到關(guān)系型數(shù)據(jù)庫,通過Hadoop的MapReduce實(shí)現(xiàn)。

Sqoop命令

執(zhí)行 $sqoop help, 可以看到Sqoop支持的命令:

Sqoop命令

具體使用方法參見官方文檔, 這里我們主要介紹下 import 命令的注意點(diǎn)

sqoop-import 注意點(diǎn)

import 可能會(huì)用到的參數(shù):

Argument Described
--append Append data to an existing dataset in HDFS
--as-sequencefile import序列化的文件
--as-textfile import plain文件 ,默認(rèn)
--columns <col,col,col…> 指定列import,逗號(hào)分隔,比如:--columns "id,name"
--delete-target-dir 刪除存在的import目標(biāo)目錄
--direct 直連模式,速度更快(HBase不支持)
--fetch-size <n> 一次從數(shù)據(jù)庫讀取 n 個(gè)實(shí)例,即n條數(shù)據(jù)
-m,--num-mappers <n> 建立 n 個(gè)并發(fā)執(zhí)行task import
-e,--query <statement> 構(gòu)建表達(dá)式<statement>執(zhí)行
--split-by <column-name> 根據(jù)column分隔實(shí)例
--autoreset-to-one-mappe 如果沒有主鍵和split-by 用one mapper import (split-by 和此選項(xiàng)不共存)
--table <table-name> 指定表名import
--target-dir <d> HDFS destination dir
--warehouse-dir <d> HDFS parent for table destination
--where <where clause> 指定where從句,如果有雙引號(hào),注意轉(zhuǎn)義 \$CONDITIONS,不能用or,子查詢,join
-z,--compress 開啟壓縮
--null-string <null-string> string列為空指定為此值
--null-non-string <null-string> 非string列為空指定為此值,-null這兩個(gè)參數(shù)are optional, 如果不設(shè)置,會(huì)指定為"null"
  1. 如果是分布式環(huán)境,--connect參數(shù)不要寫成localhost,應(yīng)該寫TaskTracker節(jié)點(diǎn)的地址

  2. 數(shù)據(jù)庫登錄密碼可以指定文件 --password-file ${user.home}/.password這個(gè)文件可以放到local或者h(yuǎn)dfs上,注意:此文件不能有空格,echo -n "secret" > password.file

  3. 盡量別用 --password,不安全(ps命令可以獲取到此參數(shù)), 可以用-P輸入console方式, 注意:密碼可以設(shè)置別名:--password-alias

  4. -m <n> 并發(fā)數(shù)默認(rèn)是4 task, 并發(fā)數(shù)n不要超過可用的MapReduce集群數(shù),也不要超過數(shù)據(jù)庫支持限度。并發(fā)原理:假定split-column = id,數(shù)據(jù)庫中 id = 0-1000,sqoop默認(rèn)4個(gè)task,切成0-250,251-500 ... 不支持多列 split. (可以看到hdfs里有按并發(fā)數(shù)切了4個(gè)切片)

  5. 當(dāng)使用Oozie啟動(dòng)Sqoop job時(shí),添加 --skip-dist-cache 參數(shù),Oozie會(huì)cache job需要的lib包

  6. --warehouse-dir 可以指定父級(jí)目錄,與 --target-dir 不共存

  7. --map-column-java, --map-column-hive 指定某幾列映射成Java或Hive的列屬性

  8. 支持增量 --incremental <mode> mode指定為append或lastmodified,還要指定列增量的值,感覺不是很好用,萬一數(shù)據(jù)是更新怎么辦?

  9. 導(dǎo)出數(shù)據(jù)文件分兩種 delimited 和 序列化文件,還可以-z壓縮

  10. 如果列含有BLOB或CLOB等大型數(shù)據(jù)列,--inline-lob-limit 可以限制下,暫時(shí)先不研究

  11. 其他涉及到import export特殊字符轉(zhuǎn)義的先不考慮,如果需要可以參見 Table6、7 Format

  12. 數(shù)據(jù)導(dǎo)入Hive


  • --hive-overwrite: 全表overwrite(需配合--hive-import使用,如果Hive里沒有表會(huì)先創(chuàng)建之)

  • --create-hive-table: 自動(dòng)推斷表字段類型直接建表,overwrite功能可以完全替代掉了(但hive里此表不能exist,所以在import前要先drop下)

  • --hive-import - -hive-overwrite 這兩個(gè)參數(shù)組合很不錯(cuò) (直接overwrite也可以,但是考慮到如果表結(jié)構(gòu)有變化,hive里是不會(huì)感知到的,所以還是先drop吧)

  • 如果含有特殊字符,需要轉(zhuǎn)義可以用 -detlims 參數(shù),這個(gè)參數(shù)只能用于hive默認(rèn)分隔符

  • 默認(rèn)用"null" 代替 NULL,而Hive \N 標(biāo)識(shí) NULL值,可以使用--null-string '\\N' --null-non-string '\\N' 解決這個(gè)問題, 沒什么特殊要求就加上吧

  • Hive也可以使用 --compress 壓縮,但是缺點(diǎn)是很多解碼器不支持并行任務(wù)的split,貌似lzop解壓可以,但是要求頗多,不建議使用

  • Hive里不支持 SQL 類型:bit(2),這樣是不妥的,應(yīng)該改成 bit(1)

  1. Sqoop支持import到 HBase,Accumulo 時(shí)間關(guān)系,暫不研究
  2. 支持額外的參數(shù) conf/sqoop-site.xml 自己配置去(-…-)

sqoop-import-all-tables 注意點(diǎn)

  1. import-all-tables 可以整庫的import,但有以為下限制條件:
  • 每個(gè)表都必須有一個(gè)單列主鍵,或者指定--autoreset-to-one-mapper參數(shù)
  • 每個(gè)表只能import全部列,即不可指定列import
  • 不能使用非默認(rèn)的分隔符,不能指定 where 從句
  1. --exclude-tables <tables>此參數(shù)可以 exlude掉不需要import的表(多個(gè)表逗號(hào)分隔)
  2. 不可以使用 --table, --split-by, --columns, --where,--delete-target-dir 等等參數(shù)
  3. 不支持 --class-name,可以用 --package-name 指定package
  4. 一旦執(zhí)行過程中有異常拋出,會(huì)立即停止

sqoop-import-mainframe

直接import主機(jī)!這個(gè)命令過于暴力,和import-all-tables差別不大,等有需要在研究研究吧。

sqoop-job 注意點(diǎn)

Sqoop可以將import任務(wù)保存為job,可以理解為起了個(gè)別名,這樣方便的Sqoop任務(wù)的管理。

參數(shù)列表:
Argument Described
--create <job-id> 創(chuàng)建一個(gè)job,job-id是job名稱,
--delete <job-id> 刪除這個(gè)job
--exec <job-id> 執(zhí)行這個(gè)job
--show <job-id> Show the parameters for a saved job.
--list List all saved jobs
--meta-connect <jdbc-uri> Specifies the JDBC connect string used to connect to the metastore
job存儲(chǔ)方案

job的是有兩種存儲(chǔ)方案的,通過配置--meta-connect或者在conf/sqoop-site.xml 里配置 sqoop.metastore.client.autoconnect.url 參數(shù)來指定是否使用metastore-client

方案A(推薦):不使用metastore-client

如果job信息放到 ${HOME}/.sqoop 目錄下,此目錄下有兩個(gè)文件:
metastore.db.properties:metastore的配置信息
metastore.db.script:job的詳細(xì)信息,通過sql語句存儲(chǔ)

方案B: 不使用metastore-client

此時(shí),job的信息會(huì)存儲(chǔ)到配置的 autoconnect.url 的 SQOOP_SESSION 表里,但是此方案會(huì)有個(gè)bug,我本地在執(zhí)行創(chuàng)建job的時(shí)候報(bào)錯(cuò):

ERROR tool.JobTool: I/O error performing job operation: java.io.IOException: Invalid metadata version

上網(wǎng)查了下解決方案,發(fā)現(xiàn) SQOOP_ROOT 表需要插入條數(shù)據(jù):

INSERT INTO SQOOP_ROOT VALUES(NULL,'sqoop.hsqldb.job.storage.version','0');

所以,還是使用方案A吧,這樣也不會(huì)對(duì)數(shù)據(jù)庫造成入侵

注意: 如果使用Oozie執(zhí)行sqoop-job的話,務(wù)必將sqoop-site.xml 中的 sqoop.metastore.client.record.password參數(shù)設(shè)置為true

其他命令

  1. sqoop-export:HDFS export 到關(guān)系型數(shù)據(jù)庫,目標(biāo)table必須存在,可分為insert和update模式
  2. sqoop-metastore:指定metadata倉庫,可在配置文件中設(shè)置
  3. sqoop-merge:合并兩個(gè)數(shù)據(jù)集,一個(gè)數(shù)據(jù)集的記錄應(yīng)該重新舊數(shù)據(jù)集的條目
  4. sqoop-codegen:將數(shù)據(jù)集封裝成Java類
  5. sqoop-create-hive-table:Sqoop單獨(dú)提供了針對(duì)Hive的命令,可以代替 sqoop import --hive-import, 其他參數(shù)一樣
  6. sqoop-eval:執(zhí)行sql語句,結(jié)果會(huì)打印在控制臺(tái),可以用來校驗(yàn)下import的查詢條件是否正確
  7. sqoop-list-databases,sqoop-list-tables:列出數(shù)據(jù)庫,列出表

以上命令暫時(shí)沒用到或很簡(jiǎn)單,等以后需要的時(shí)候再去研究吧

HCatalog

HCatalog提供表和存儲(chǔ)管理服務(wù),使不同的Hadoop數(shù)據(jù)處理工具如:Pig,MapReduce,Hive更容易讀取和寫入數(shù)據(jù)網(wǎng)格

看文檔比較復(fù)雜,暫時(shí)用不到,等以后需要的時(shí)候再去研究吧o(╯□╰)o

需要注意的地方

  1. MySQL
  • MySQL允許Date類型字段出現(xiàn)'0000-00-00',Sqoop有三種方式處理這種情況:1. 轉(zhuǎn)成NULL(默認(rèn)),2. 拋出異常 3. 置成'0001-01-01', 配置zeroDateTimeBehavior參數(shù)設(shè)置,跟在connect string后面
  • UNSIGNED 列, MySQL 范圍:0 ~ 2^32 ,Sqoop范圍:-2^31~ +2^31-1, 注意不要越界
  1. Hive
  • DATE, TIME, TIMESTAMP 類型轉(zhuǎn)換到Hive里會(huì)被處理為 String
  • NUMERIC, DECIMAL 類型轉(zhuǎn)換到Hive里會(huì)被處理為 DOUBLE
  • Sqoop會(huì)打印warn日志警告可能會(huì)丟失精度
  1. --direct 參數(shù)目前只有MySQL和PostgreSQL(import) 支持,不支持BLOB, CLOB, LONGVARBINARY 列
  2. --direct不支持視圖

最佳實(shí)踐

根據(jù)我的個(gè)人需求,配置了適合我的最佳Sqoop參數(shù)(∩_∩)

單表import到Hive:

sqoop import  \
  --connect jdbc:mysql://127.0.0.1:3306/database_name \
  --username root \
  --password 123456 \
  --table table_name \
  --outdir \${HOME}/.sqoop/java  \
  --delete-target-dir \
  --hive-import \
  --hive-overwrite \
  --null-string '\\N' \ 
  --null-non-string '\\N' \
  -m 8 \
  --direct

整庫import到Hive:

sqoop import-all-tables \
  --connect jdbc:mysql://127.0.0.1:3306/database_name \
  --username root \
  --password 123456 \
  --outdir \${HOME}/.sqoop/java  \
  --hive-import \
  --hive-overwrite \
  --null-string '\\N' \ 
  --null-non-string '\\N'  \
  -m 8 \
  --direct

說明:
--out-dir:指定Java文件的路徑
--delete-target-dir:刪除HDFS目錄
--hive-import:直接導(dǎo)入的Hive
--hive-overwrite:全表覆蓋(如果表不存在會(huì)直接創(chuàng)建表)
--null-string:指定String列如果為NULL轉(zhuǎn)換到Hive里也為NULL
--null-non-string:指定String列如果為NULL轉(zhuǎn)換到Hive里也為NULL
-m 8:8個(gè)并發(fā)
--direct:直連模式,使用mysqldump加快速度(本地測(cè)試13W條數(shù)據(jù),74M, 快了10%左右)

最后

通過幾天對(duì)Sqoop的研究,掌握了Sqoop import的基本用法,更高級(jí)的用法還有待探索,最近在寫個(gè)Sqoop的Java工具類,希望能通過API的形式執(zhí)行Sqoop命令,以后也會(huì)加入Oozie對(duì)Sqoop job的管理。

PS:Sqoop2 有很多新特性, 支持命令行、Web UI、REST API,支持server模式同時(shí)也更安全易用,所以很期待Sqoop的 2.0 版!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容