一香伴、Sqoop簡(jiǎn)介
官網(wǎng)介紹:https://sqoop.apache.org
Apache Sqoop(TM) is a tool designed for efficiently transferring bulk data between Apache Hadoop and structured datastores such as relational databases.Sqoop successfully graduated from the Incubator in March of 2012 and is now a Top-Level Apache project: More informationLatest stable release is 1.4.7 (download, documentation). Latest cut of Sqoop2 is 1.99.7 (download, documentation). Note that 1.99.7 is not compatible with 1.4.7 and not feature complete, it is not intended for production deployment.
Apache Sqoop(TM)是一種工具饵沧,旨在在Apache Hadoop和結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)(如關(guān)系數(shù)據(jù)庫(kù))之間高效地傳輸批量數(shù)據(jù) 。Sqoop于2012年3月成功畢業(yè)于孵化器兔跌,現(xiàn)在是Apache的頂級(jí)項(xiàng)目。
最新的穩(wěn)定版本是1.4.7裁僧。Sqoop2的最新版本為1.99.7贴届。請(qǐng)注意,1.99.7與1.4.7不兼容且功能不完整震桶,因此不適用于生產(chǎn)部署休傍。
Sqoop是一款開源的工具,主要用于在Hadoop(Hive)與傳統(tǒng)的數(shù)據(jù)庫(kù)(mysql蹲姐、oracle...)之間進(jìn)行數(shù)據(jù)的傳遞磨取,可以將一個(gè)關(guān)系型數(shù)據(jù)庫(kù)(例如: MySQL ,Oracle ,Postgres等)中的數(shù)據(jù)導(dǎo)進(jìn)到Hadoop的HDFS中人柿,也可以將HDFS的數(shù)據(jù)導(dǎo)進(jìn)到關(guān)系型數(shù)據(jù)庫(kù)中。
Sqoop項(xiàng)目開始于2009年忙厌,最早是作為Hadoop的一個(gè)第三方模塊存在凫岖,后來(lái)為了讓使用者能夠快速部署,也為了讓開發(fā)人員能夠更快速的迭代開發(fā)逢净,Sqoop獨(dú)立成為一個(gè)Apache項(xiàng)目哥放。
二、Sqoop原理
將導(dǎo)入或?qū)С雒罘g成MapReduce程序來(lái)實(shí)現(xiàn)爹土。
在翻譯出的MR中沒有Reduce階段只有Map階段甥雕,默認(rèn)4個(gè)Map。
三胀茵、Sqoop安裝
1社露、環(huán)境準(zhǔn)備
必須先配置好Java和Hadoop環(huán)境
2、下載和解壓安裝包
2.1琼娘、從官網(wǎng)或鏡像下載安裝包峭弟,本文以Sqoop1.4.6為例
#1.4.6安裝包
sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz
2.2、將安裝包解壓到指定的安裝目錄
#解壓安裝包到目錄:/opt/module/
tar -zxvf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz -C /opt/module/
3轨奄、配置
3.1孟害、進(jìn)入Sqoop根目錄的conf文件下,重命名配置文件
#重命名配置文件
mv sqoop-env-template.sh sqoop-env.sh
3.2挪拟、修改sqoop-env.sh
#配置Hadoop的安裝目錄
exportHADOOP_COMMON_HOME=/opt/module/hadoop-2.7.2
exportHADOOP_MAPRED_HOME=/opt/module/hadoop-2.7.2
#配置Hive的安裝目錄
export HIVE_HOME=/opt/module/hive
#配置Zookeeper的安裝目錄
export ZOOKEEPER_HOME=/opt/module/zookeeper-3.4.10
export ZOOCFGDIR=/opt/module/zookeeper-3.4.10/conf
#配置HBase的安裝目錄
export HBASE_HOME=/opt/module/hbase-1.3.1
3.3、拷貝JDBC驅(qū)動(dòng)(以連接MySQL數(shù)據(jù)庫(kù)為例)
#將JDBC驅(qū)動(dòng)拷貝到Sqoop的lib目錄下(此處以MySQl為例)
cp mysql-connector-java-5.1.27-bin.jar /opt/module/sqoop-1.4.6.bin__hadoop-2.0.4-alpha/lib/
4击你、測(cè)試玉组,驗(yàn)證是否成功
4.1、驗(yàn)證Sqoop是否配置正確
#在Sqoop根目錄下
bin/sqoop help
如果出現(xiàn)一些Warning警告丁侄,并伴隨著幫助命令的輸出惯雳,則證明配置沒有問(wèn)題
4.2、數(shù)據(jù)庫(kù)連接測(cè)試
#在Sqoop根目錄下
bin/sqoop list-databases
--connect jdbc:mysql://bigdata102:3306/
--username root
--password 123456
若列出所連接數(shù)據(jù)庫(kù)中的數(shù)據(jù)庫(kù)名則證明連接成功
四鸿摇、Sqoop常用命令及參數(shù)
1石景、常用命令
1.1 import
所屬類:ImportTool
功能:將數(shù)據(jù)導(dǎo)入大數(shù)據(jù)集群
1.2 export
所屬類:ExportTool
功能:將數(shù)據(jù)從大數(shù)據(jù)集群導(dǎo)出
1.3 import-all-tables
所屬類:ImportAllTablesTool
功能:導(dǎo)入數(shù)據(jù)庫(kù)下所有的表
1.4 codegen
所屬類:CodeGenTool
功能:關(guān)系型數(shù)據(jù)庫(kù)中的表映射為一個(gè)Java類,在該類中有各列對(duì)應(yīng)的各個(gè)字段
1.5 create-hive-table
所屬類:CreateHiveTableTool
功能:創(chuàng)建Hive表
1.6 eval
所屬類:EvalSqlTool
功能:查看SQL執(zhí)行結(jié)果
1.7 job
所屬類:JobTool
功能: 用來(lái)生成一個(gè)sqoop的任務(wù)拙吉,生成后潮孽,該任務(wù)并不執(zhí)行,除非使用命令執(zhí)行該任務(wù)筷黔。
1.8 list-databases
所屬類: ListDatabasesTool
功能: 列出所有數(shù)據(jù)庫(kù)名
1.9 list-tables
所屬類: ListTablesTool
功能: 列出某個(gè)數(shù)據(jù)庫(kù)下所有表
1.10 merge
所屬類: MergeTool
功能: 將HDFS中不同目錄下面的數(shù)據(jù)合在一起往史,并存放在指定的目錄中
1.11 metastore
所屬類: MetastoreTool
功能: 記錄sqoop job的元數(shù)據(jù)信息,如果不啟動(dòng)metastore實(shí)例佛舱,則默認(rèn)的元數(shù)據(jù)存儲(chǔ)目錄為:~/.sqoop椎例,如果要更改存儲(chǔ)目錄挨决,可以在配置文件sqoop-site.xml中進(jìn)行更改。
1.12 help
所屬類: HelpTool
功能:幫助信息
1.13 version
所屬類: VersionTool
功能:版本信息
2订歪、參數(shù)
2.1 公用參數(shù)
公用參數(shù):大多數(shù)命令都支持的參數(shù)
2.1.1 數(shù)據(jù)庫(kù)連接相關(guān)
參數(shù) | 作用 |
---|---|
--connect | 連接關(guān)系型數(shù)據(jù)庫(kù)的URL |
--connection-manager | 指定要使用的連接管理類 |
--driver | Hadoop根目錄 |
--help | 打印幫助信息 |
--password | 連接數(shù)據(jù)庫(kù)的密碼 |
--username | 連接數(shù)據(jù)庫(kù)的用戶名 |
--verbose | 在控制臺(tái)打印出詳細(xì)信息 |
2.1.2 import操作相關(guān)
參數(shù) | 說(shuō)明 |
---|---|
--enclosed-by <char> | 給字段值前加上指定的字符 |
--escaped-by <char> | 對(duì)字段中的雙引號(hào)加轉(zhuǎn)義符 |
--fields-terminated-by <char> | 設(shè)定每個(gè)字段是以什么符號(hào)作為結(jié)束脖祈,默認(rèn)為逗號(hào) |
--lines-terminated-by <char> | 設(shè)定每行記錄之間的分隔符,默認(rèn)是\n |
--mysql-delimiters | Mysql默認(rèn)的分隔符設(shè)置刷晋,字段之間以逗號(hào)分隔撒犀,行之間以\n分隔,默認(rèn)轉(zhuǎn)義符是\掏秩,字段值以單引號(hào)包裹或舞。 |
--optionally-enclosed-by <char> | 給帶有雙引號(hào)或單引號(hào)的字段值前后加上指定字符。 |
2.1.3 export操作相關(guān)
參數(shù) | 說(shuō)明 |
---|---|
--input-enclosed-by <char> | 對(duì)字段值前后加上指定字符 |
--input-escaped-by <char> | 對(duì)含有轉(zhuǎn)移符的字段做轉(zhuǎn)義處理 |
--input-fields-terminated-by <char> | 字段之間的分隔符 |
--input-lines-terminated-by <char> | 行之間的分隔符 |
--input-optionally-enclosed-by <char> | 給帶有雙引號(hào)或單引號(hào)的字段前后加上指定字符 |
--update-key <col-name> | 更新時(shí)參考的列 |
--update-mode <mode> | 更新模式 updateonly allowinsert |
2.1.4 hive相關(guān)
參數(shù) | 說(shuō)明 |
---|---|
--hive-delims-replacement <arg> | 用自定義的字符串替換掉數(shù)據(jù)中的\r\n和\013 \010等字符 |
--hive-drop-import-delims | 在導(dǎo)入數(shù)據(jù)到hive時(shí)蒙幻,去掉數(shù)據(jù)中的\r\n\013\010這樣的字符 |
--map-column-hive <arg> | 生成hive表時(shí)映凳,可以更改生成字段的數(shù)據(jù)類型 |
--hive-partition-key | 創(chuàng)建分區(qū),后面直接跟分區(qū)名邮破,分區(qū)字段的默認(rèn)類型為string |
--hive-partition-value <v> | 導(dǎo)入數(shù)據(jù)時(shí)诈豌,指定某個(gè)分區(qū)的值 |
--hive-home <dir> | hive的安裝目錄,可以通過(guò)該參數(shù)覆蓋之前默認(rèn)配置的目錄 |
--hive-import | 將數(shù)據(jù)從關(guān)系數(shù)據(jù)庫(kù)中導(dǎo)入到hive表中 |
--hive-overwrite | 覆蓋掉在hive表中已經(jīng)存在的數(shù)據(jù) |
--create-hive-table | 默認(rèn)是false抒和,即矫渔,如果目標(biāo)表已經(jīng)存在了,那么創(chuàng)建任務(wù)失敗摧莽。 |
--hive-table | 后面接要?jiǎng)?chuàng)建的hive表,默認(rèn)使用MySQL的表名 |
--table | 指定關(guān)系數(shù)據(jù)庫(kù)的表名 |
2.2 常用命令及其專有參數(shù)
2.2.1 import
參數(shù) | 說(shuō)明 |
---|---|
--append | 將數(shù)據(jù)追加到HDFS中已經(jīng)存在的DataSet中庙洼,如果使用該參數(shù),sqoop會(huì)把數(shù)據(jù)先導(dǎo)入到臨時(shí)文件目錄镊辕,再合并油够。 |
--as-avrodatafile | 將數(shù)據(jù)導(dǎo)入到一個(gè)Avro數(shù)據(jù)文件中 |
--as-sequencefile | 將數(shù)據(jù)導(dǎo)入到一個(gè)sequence文件中 |
--as-textfile | 將數(shù)據(jù)導(dǎo)入到一個(gè)普通文本文件中 |
--boundary-query <statement> | 邊界查詢,導(dǎo)入的數(shù)據(jù)為該參數(shù)的值(一條sql語(yǔ)句)所執(zhí)行的結(jié)果區(qū)間內(nèi)的數(shù)據(jù)征懈。 |
--columns <col1, col2, col3> | 指定要導(dǎo)入的字段 |
--direct | 直接導(dǎo)入模式石咬,使用的是關(guān)系數(shù)據(jù)庫(kù)自帶的導(dǎo)入導(dǎo)出工具,以便加快導(dǎo)入導(dǎo)出過(guò)程卖哎。 |
--direct-split-size | 在使用上面direct直接導(dǎo)入的基礎(chǔ)上鬼悠,對(duì)導(dǎo)入的流按字節(jié)分塊,即達(dá)到該閾值就產(chǎn)生一個(gè)新的文件 |
--inline-lob-limit | 設(shè)定大對(duì)象數(shù)據(jù)類型的最大值 |
--m或–num-mappers | 啟動(dòng)N個(gè)map來(lái)并行導(dǎo)入數(shù)據(jù)亏娜,默認(rèn)4個(gè)焕窝。 |
--query或--e <statement> | 將查詢結(jié)果的數(shù)據(jù)導(dǎo)入,使用時(shí)必須伴隨參--target-dir照藻,--hive-table袜啃,如果查詢中有where條件,則條件后必須加上$CONDITIONS關(guān)鍵字 |
--split-by <column-name> | 按照某一列來(lái)切分表的工作單元幸缕,不能與--autoreset-to-one-mapper連用(請(qǐng)參考官方文檔) |
--table <table-name> | 關(guān)系數(shù)據(jù)庫(kù)的表名 |
--target-dir <dir> | 指定HDFS路徑 |
--warehouse-dir <dir> | 與14參數(shù)不能同時(shí)使用群发,導(dǎo)入數(shù)據(jù)到HDFS時(shí)指定的目錄 |
--where | 從關(guān)系數(shù)據(jù)庫(kù)導(dǎo)入數(shù)據(jù)時(shí)的查詢條件 |
--z或--compress | 允許壓縮 |
--compression-codec | 指定hadoop壓縮編碼類晰韵,默認(rèn)為gzip(Use Hadoop codec default gzip) |
--null-string <null-string> | string類型的列如果null,替換為指定字符串 |
--null-non-string <null-string> | 非string類型的列如果null熟妓,替換為指定字符串 |
--check-column <col> | 作為增量導(dǎo)入判斷的列名 |
--incremental <mode> | mode:append或lastmodified |
--last-value <value> | 指定某一個(gè)值雪猪,用于標(biāo)記增量導(dǎo)入的位置 |
2.2.2 export
參數(shù) | 說(shuō)明 |
---|---|
--direct | 利用數(shù)據(jù)庫(kù)自帶的導(dǎo)入導(dǎo)出工具,以便于提高效率 |
--export-dir <dir> | 存放數(shù)據(jù)的HDFS的源目錄 |
-m或--num-mappers <n> | 啟動(dòng)N個(gè)map來(lái)并行導(dǎo)入數(shù)據(jù)起愈,默認(rèn)4個(gè) |
--table <table-name> | 指定導(dǎo)出到哪個(gè)RDBMS中的表 |
--update-key <col-name> | 對(duì)某一列的字段進(jìn)行更新操作 |
--update-mode <mode> | updateonly(默認(rèn)) allowinsert |
--input-null-string <null-string> | 請(qǐng)參考import該類似參數(shù)說(shuō)明 |
--input-null-non-string <null-string> | 請(qǐng)參考import該類似參數(shù)說(shuō)明 |
--staging-table <staging-table-name> | 創(chuàng)建一張臨時(shí)表只恨,用于存放所有事務(wù)的結(jié)果,然后將所有事務(wù)結(jié)果一次性導(dǎo)入到目標(biāo)表中抬虽,防止錯(cuò)誤官觅。 |
--clear-staging-table | 如果第9個(gè)參數(shù)非空,則可以在導(dǎo)出操作執(zhí)行前阐污,清空臨時(shí)事務(wù)結(jié)果表 |
2.2.3 codegen
參數(shù) | 說(shuō)明 |
---|---|
--bindir <dir> | 指定生成的Java文件休涤、編譯成的class文件及將生成文件打包為jar的文件輸出路徑 |
--class-name <name> | 設(shè)定生成的Java文件指定的名稱 |
--outdir <dir> | 生成Java文件存放的路徑 |
--package-name <name> | 包名,如com.z笛辟,就會(huì)生成com和z兩級(jí)目錄 |
--input-null-non-string <null-str> | 在生成的Java文件中功氨,可以將null字符串或者不存在的字符串設(shè)置為想要設(shè)定的值(例如空字符串) |
--input-null-string <null-str> | 將null字符串替換成想要替換的值(一般與5同時(shí)使用) |
--map-column-java <arg> | 數(shù)據(jù)庫(kù)字段在生成的Java文件中會(huì)映射成各種屬性,且默認(rèn)的數(shù)據(jù)類型與數(shù)據(jù)庫(kù)類型保持對(duì)應(yīng)關(guān)系手幢。該參數(shù)可以改變默認(rèn)類型捷凄,例如:--map-column-java id=long, name=String |
--null-non-string <null-str> | 在生成Java文件時(shí),可以將不存在或者null的字符串設(shè)置為其他值 |
--null-string <null-str> | 在生成Java文件時(shí)围来,將null字符串設(shè)置為其他值(一般與8同時(shí)使用) |
--table <table-name> | 對(duì)應(yīng)關(guān)系數(shù)據(jù)庫(kù)中的表名跺涤,生成的Java文件中的各個(gè)屬性與該表的各個(gè)字段一一對(duì)應(yīng) |
2.2.4 create-hive-table
參數(shù) | 說(shuō)明 |
---|---|
--hive-home <dir> | Hive的安裝目錄,可以通過(guò)該參數(shù)覆蓋掉默認(rèn)的Hive目錄 |
--hive-overwrite | 覆蓋掉在Hive表中已經(jīng)存在的數(shù)據(jù) |
--create-hive-table | 默認(rèn)是false管钳,如果目標(biāo)表已經(jīng)存在了钦铁,那么創(chuàng)建任務(wù)會(huì)失敗 |
--hive-table | 后面接要?jiǎng)?chuàng)建的hive表 |
--table | 指定關(guān)系數(shù)據(jù)庫(kù)的表名 |
2.2.5 eval
參數(shù) | 說(shuō)明 |
---|---|
--query或--e | 后跟查詢的SQL語(yǔ)句 |
2.2.6 import-all-tables
參數(shù) | 說(shuō)明 |
---|---|
--as-avrodatafile | 這些參數(shù)的含義均和import對(duì)應(yīng)的含義一致 |
--as-sequencefile | |
--as-textfile | |
--direct | |
--direct-split-size <n> | |
--inline-lob-limit <n> | |
--m或—num-mappers <n> | |
--warehouse-dir <dir> | |
-z或--compress | |
--compression-codec |
2.2.7 job
參數(shù) | 說(shuō)明 |
---|---|
--create <job-id> | 創(chuàng)建job參數(shù) |
--delete <job-id> | 刪除一個(gè)job |
--exec <job-id> | 執(zhí)行一個(gè)job |
--help | 顯示job幫助 |
--list | 顯示job列表 |
--meta-connect <jdbc-uri> | 用來(lái)連接metastore服務(wù) |
--show <job-id> | 顯示一個(gè)job的信息 |
--verbose | 打印命令運(yùn)行時(shí)的詳細(xì)信息 |
2.2.8 merge
參數(shù) | 說(shuō)明 |
---|---|
--new-data <path> | HDFS 待合并的數(shù)據(jù)目錄,合并后在新的數(shù)據(jù)集中保留 |
--onto <path> | HDFS合并后才漆,重復(fù)的部分在新的數(shù)據(jù)集中被覆蓋 |
--merge-key <col> | 合并鍵,一般是主鍵ID |
--jar-file <file> | 合并時(shí)引入的jar包佛点,該jar包是通過(guò)Codegen工具生成的jar包 |
--class-name <class> | 對(duì)應(yīng)的表名或?qū)ο竺祭模揷lass類是包含在jar包中的 |
--target-dir <path> | 合并后的數(shù)據(jù)在HDFS里存放的目錄 |
2.2.11 metastore
參數(shù) | 說(shuō)明 |
---|---|
--shutdown | 關(guān)閉metastore |
五、使用方法及案例
1超营、基本概念
1.1 導(dǎo)入數(shù)據(jù)
從關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)(Relational Database Management System:RDBMS)向大數(shù)據(jù)集群(HDFS鸳玩,Hive,HBase)傳輸數(shù)據(jù)演闭,稱為:導(dǎo)入
1.2 導(dǎo)出數(shù)據(jù)
從大數(shù)據(jù)集群向RDBMS傳輸數(shù)據(jù)不跟,稱為:導(dǎo)出
2、導(dǎo)入數(shù)據(jù)方法
2.1 RDBMS_to_HDFS
2.1.1 全表導(dǎo)入
#導(dǎo)入命令
bin/sqoop import \
#所要連接的數(shù)據(jù)庫(kù)URL
--connectjdbc:mysql://hadoop102:3306/company \
#連接數(shù)據(jù)庫(kù)的用戶和密碼
--username root \
--password 123456 \
#數(shù)據(jù)庫(kù)中要導(dǎo)出數(shù)據(jù)的表米碰,的表名
--table staff \
#指定導(dǎo)入數(shù)據(jù)在HDFS上存儲(chǔ)目錄
--target-dir /company \
#如果目標(biāo)目錄存在則刪除
--delete-target-dir \
#導(dǎo)入到HDFS上時(shí)窝革,表中字段用 \t 作為分隔符
--fields-terminated-by"\t" \
#指定導(dǎo)入任務(wù)的Map數(shù)量
--num-mappers 2 \
#基于id列购城,將數(shù)據(jù)切分成2片(--num-mappers的數(shù)量)所選列不能有null值,不然 #null值所在列無(wú)法導(dǎo)入虐译。最好選擇主鍵列瘪板,數(shù)字列
--split-by id #注意:只有在--num-mappers > 1 時(shí)才需指定該參數(shù)
2.1.2 導(dǎo)入指定列
在 2.1.1全表導(dǎo)入 的基礎(chǔ)上使用 --columns 參數(shù)
#只導(dǎo)入指定列:id和name --columns id,name
提示:columns中如果涉及到多列漆诽,用逗號(hào)分隔侮攀,分隔時(shí)不要添加空格
2.1.3 導(dǎo)入指定行
在 2.1.1全表導(dǎo)入 的基礎(chǔ)上使用 --where 參數(shù)
#只導(dǎo)入滿足指定條件的行 --where 'id=10'
2.1.4 導(dǎo)入SQL查詢結(jié)果
在 2.1.1全表導(dǎo)入 的基礎(chǔ)上使用 --query "SQL語(yǔ)句" 替換 --table 即可
#將SQL語(yǔ)句查詢結(jié)果導(dǎo)入 --query "select * from 表 where \$CONDITIONS and id <= 25"
注意!!!!(尖叫提示):
a、must contain'CONDITIONS前必須加轉(zhuǎn)移符,防止shell識(shí)別為自己的變量
2.2 RDBMS_to_Hive
bin/sqoop import \
--connectjdbc:mysql://hadoop102:3306/company \
--username root \
--password 123456 \
--table staff \
--num-mappers 1 \
--fields-terminated-by "\t" \
#將數(shù)據(jù)導(dǎo)入到Hive中
--hive-import \
#覆蓋掉在hive表中已經(jīng)存在的數(shù)據(jù)
--hive-overwrite \
#后面接要?jiǎng)?chuàng)建的hive表,默認(rèn)使用原表名
--hive-tablestaff_hive
注意9F杳场!該過(guò)程分為兩步:
第一步將數(shù)據(jù)導(dǎo)入到HDFS上的臨時(shí)目錄回季,默認(rèn)的是/user/HDFS用戶名/表名
第二步將導(dǎo)入到HDFS的數(shù)據(jù)遷移到Hive倉(cāng)庫(kù)
3家制、導(dǎo)出數(shù)據(jù)方法
3.1 Hive/HDFS_to_RDBMS
#執(zhí)行Sqoop導(dǎo)出命令
bin/sqoop export \
#導(dǎo)出的數(shù)據(jù)庫(kù)URL,用戶名及密碼
--connectjdbc:mysql://bigdata102:3306/test \
--username root \
--password 123456 \
#導(dǎo)出的數(shù)據(jù)要進(jìn)的表
--table staff2 \
#mapper個(gè)數(shù)
--num-mappers 1 \
#導(dǎo)出數(shù)據(jù)所在的路徑
--export-dir /company \
#指定字段間的分隔符
--input-fields-terminated-by"\t"
提示:Mysql中如果表不存在,不會(huì)自動(dòng)創(chuàng)建
4泡一、打包成腳本(實(shí)際使用案例)
4.1 MySQL導(dǎo)入HDFS
#!/bin/bash
#定義Sqoop命令路徑
sqoop=/opt/module/sqoop/bin/sqoop
#do_date為傳入的日期值颤殴,若未指定默認(rèn)當(dāng)天
do_date=`date -d '-1 day' +%F`
if [[ -n "$2" ]]; then
do_date=$2
fi
#定義
import_data(){
$sqoop import \
--connect jdbc:mysql://hadoop102:3306/test \
--username root \
--password 000000 \
--target-dir /origin_data/test/db/$1/$do_date \
--delete-target-dir \
--query "$2 and \$CONDITIONS" \
--num-mappers 1 \
--fields-terminated-by '\t' \
--compress \
--compression-codec lzop \
--null-string '\\N' \
--null-non-string '\\N'
hadoop jar /opt/module/hadoop-2.7.2/share/hadoop/common/hadoop-lzo-0.4.20.jar com.hadoop.compression.lzo.DistributedLzoIndexer /origin_data/test/db/$1/$do_date
}
import_order_info(){
import_data order_info "select
id,
final_total_amount,
order_status,
user_id,
out_trade_no,
create_time,
operate_time,
province_id,
benefit_reduce_amount,
original_total_amount,
feight_fee
from order_info
where (date_format(create_time,'%Y-%m-%d')='$do_date'
or date_format(operate_time,'%Y-%m-%d')='$do_date')"
}
import_coupon_use(){
import_data coupon_use "select
id,
coupon_id,
user_id,
order_id,
coupon_status,
get_time,
using_time,
used_time
from coupon_use
where (date_format(get_time,'%Y-%m-%d')='$do_date'
or date_format(using_time,'%Y-%m-%d')='$do_date'
or date_format(used_time,'$Y-%m-%d')='$do_date')"
}
import_order_status_log(){
import_data order_status_log "select
id,
order_id,
order_status,
operate_time
from order_status_log
where date_format(operate_time,'%Y-%m-%d')='$do_date'"
}
import_activity_order(){
import_data activity_order "select
id,
activity_id,
order_id,
create_time
from activity_order
where date_format(create_time,'%Y-%m-%d')='$do_date'"
}
import_user_info(){
import_data "user_info" "select
id,
name,
birthday,
gender,
email,
user_level,
create_time,
operate_time
from user_info
where (DATE_FORMAT(create_time,'%Y-%m-%d')='$do_date'
or DATE_FORMAT(operate_time,'%Y-%m-%d')='$do_date')"
}
import_order_detail(){
import_data order_detail "select
od.id,
order_id,
user_id,
sku_id,
sku_name,
order_price,
sku_num,
od.create_time
from order_detail od
join order_info oi
on od.order_id=oi.id
where DATE_FORMAT(od.create_time,'%Y-%m-%d')='$do_date'"
}
import_payment_info(){
import_data "payment_info" "select
id,
out_trade_no,
order_id,
user_id,
alipay_trade_no,
total_amount,
subject,
payment_type,
payment_time
from payment_info
where DATE_FORMAT(payment_time,'%Y-%m-%d')='$do_date'"
}
import_comment_info(){
import_data comment_info "select
id,
user_id,
sku_id,
spu_id,
order_id,
appraise,
comment_txt,
create_time
from comment_info
where date_format(create_time,'%Y-%m-%d')='$do_date'"
}
import_order_refund_info(){
import_data order_refund_info "select
id,
user_id,
order_id,
sku_id,
refund_type,
refund_num,
refund_amount,
refund_reason_type,
create_time
from order_refund_info
where date_format(create_time,'%Y-%m-%d')='$do_date'"
}
import_sku_info(){
import_data sku_info "select
id,
spu_id,
price,
sku_name,
sku_desc,
weight,
tm_id,
category3_id,
create_time
from sku_info where 1=1"
}
import_base_category1(){
import_data "base_category1" "select
id,
name
from base_category1 where 1=1"
}
import_base_category2(){
import_data "base_category2" "select
id,
name,
category1_id
from base_category2 where 1=1"
}
import_base_category3(){
import_data "base_category3" "select
id,
name,
category2_id
from base_category3 where 1=1"
}
import_base_province(){
import_data base_province "select
id,
name,
region_id,
area_code,
iso_code
from base_province
where 1=1"
}
import_base_region(){
import_data base_region "select
id,
region_name
from base_region
where 1=1"
}
import_base_trademark(){
import_data base_trademark "select
tm_id,
tm_name
from base_trademark
where 1=1"
}
import_spu_info(){
import_data spu_info "select
id,
spu_name,
category3_id,
tm_id
from spu_info
where 1=1"
}
import_favor_info(){
import_data favor_info "select
id,
user_id,
sku_id,
spu_id,
is_cancel,
create_time,
cancel_time
from favor_info
where 1=1"
}
import_cart_info(){
import_data cart_info "select
id,
user_id,
sku_id,
cart_price,
sku_num,
sku_name,
create_time,
operate_time,
is_ordered,
order_time
from cart_info
where 1=1"
}
import_coupon_info(){
import_data coupon_info "select
id,
coupon_name,
coupon_type,
condition_amount,
condition_num,
activity_id,
benefit_amount,
benefit_discount,
create_time,
range_type,
spu_id,
tm_id,
category3_id,
limit_num,
operate_time,
expire_time
from coupon_info
where 1=1"
}
import_activity_info(){
import_data activity_info "select
id,
activity_name,
activity_type,
start_time,
end_time,
create_time
from activity_info
where 1=1"
}
import_activity_rule(){
import_data activity_rule "select
id,
activity_id,
condition_amount,
condition_num,
benefit_amount,
benefit_discount,
benefit_level
from activity_rule
where 1=1"
}
import_base_dic(){
import_data base_dic "select
dic_code,
dic_name,
parent_code,
create_time,
operate_time
from base_dic
where 1=1"
}
case $1 in
"order_info")
import_order_info
;;
"base_category1")
import_base_category1
;;
"base_category2")
import_base_category2
;;
"base_category3")
import_base_category3
;;
"order_detail")
import_order_detail
;;
"sku_info")
import_sku_info
;;
"user_info")
import_user_info
;;
"payment_info")
import_payment_info
;;
"base_province")
import_base_province
;;
"base_region")
import_base_region
;;
"base_trademark")
import_base_trademark
;;
"activity_info")
import_activity_info
;;
"activity_order")
import_activity_order
;;
"cart_info")
import_cart_info
;;
"comment_info")
import_comment_info
;;
"coupon_info")
import_coupon_info
;;
"coupon_use")
import_coupon_use
;;
"favor_info")
import_favor_info
;;
"order_refund_info")
import_order_refund_info
;;
"order_status_log")
import_order_status_log
;;
"spu_info")
import_spu_info
;;
"activity_rule")
import_activity_rule
;;
"base_dic")
import_base_dic
;;
"first")
import_base_category1
import_base_category2
import_base_category3
import_order_info
import_order_detail
import_sku_info
import_user_info
import_payment_info
import_base_province
import_base_region
import_base_trademark
import_activity_info
import_activity_order
import_cart_info
import_comment_info
import_coupon_use
import_coupon_info
import_favor_info
import_order_refund_info
import_order_status_log
import_spu_info
import_activity_rule
import_base_dic
;;
"all")
import_base_category1
import_base_category2
import_base_category3
import_order_info
import_order_detail
import_sku_info
import_user_info
import_payment_info
import_base_trademark
import_activity_info
import_activity_order
import_cart_info
import_comment_info
import_coupon_use
import_coupon_info
import_favor_info
import_order_refund_info
import_order_status_log
import_spu_info
import_activity_rule
import_base_dic
;;
esac
4.2 Hive導(dǎo)出MySQL
#!/bin/bash
hive_db_name=test_hive
mysql_db_name=hive2mysql
export_data() {
/opt/module/sqoop/bin/sqoop export \
--connect "jdbc:mysql://hadoop102:3306/${mysql_db_name}?useUnicode=true&characterEncoding=utf-8" \
--username root \
--password 000000 \
--table $1 \
--num-mappers 1 \
--export-dir /warehouse/$hive_db_name/ads/$1 \
--input-fields-terminated-by "\t" \
--update-mode allowinsert \
--update-key $2 \
--input-null-string '\\N' \
--input-null-non-string '\\N'
}
case $1 in
"ads_uv_count")
export_data "ads_uv_count" "dt"
;;
"ads_user_action_convert_day")
export_data "ads_user_action_convert_day" "dt"
;;
"ads_gmv_sum_day")
export_data "ads_gmv_sum_day" "dt"
;;
"ads_user_topic")
export_data "ads_user_topic" "dt"
;;
"all")
export_data "ads_uv_count" "dt"
export_data "ads_user_action_convert_day" "dt"
export_data "ads_gmv_sum_day" "dt"
export_data "ads_user_topic" "dt"
;;
esac
關(guān)于導(dǎo)出update還是insert的問(wèn)題:
--update-mode:
updateonly 只更新,無(wú)法插入新數(shù)據(jù)
allowinsert 允許新增--update-key:
允許更新的情況下鼻忠,指定哪些字段匹配視為同一條數(shù)據(jù)涵但,進(jìn)行更新而不增加。多個(gè)字段用逗號(hào)分隔帖蔓。
?
六矮瘟、常見問(wèn)題及解決方案
1、Sqoop導(dǎo)入導(dǎo)出Null存儲(chǔ)一致性問(wèn)題(遇到)
Hive中的Null在底層是以“\N”來(lái)存儲(chǔ)塑娇,而MySQL中的Null在底層就是Null澈侠,為了保證數(shù)據(jù)兩端的一致性:
a 在導(dǎo)出數(shù)據(jù)時(shí)采用--input-null-string和--input-null-non-string兩個(gè)參數(shù)
b 導(dǎo)入數(shù)據(jù)時(shí)采用--null-string和--null-non-string
2鹿霸、Sqoop數(shù)據(jù)導(dǎo)出一致性問(wèn)題(遇到)
場(chǎng)景:如Sqoop在導(dǎo)出到Mysql時(shí)绑莺,使用4個(gè)Map任務(wù)献起,過(guò)程中有2個(gè)任務(wù)失敗昔脯,那此時(shí)MySQL中存儲(chǔ)了另外兩個(gè)Map任務(wù)導(dǎo)入的數(shù)據(jù)珊肃,此時(shí)老板正好看到了這個(gè)報(bào)表數(shù)據(jù)媚污。而開發(fā)工程師發(fā)現(xiàn)任務(wù)失敗后扔涧,會(huì)調(diào)試問(wèn)題并最終將全部數(shù)據(jù)正確的導(dǎo)入MySQL囤踩,那后面老板再次看報(bào)表數(shù)據(jù)珍特,發(fā)現(xiàn)本次看到的數(shù)據(jù)與之前的不一致
解決:
可以使用--staging-table –clear-staging
任務(wù)執(zhí)行成功首先在tmp臨時(shí)表中祝峻,然后將tmp表中的數(shù)據(jù)復(fù)制到目標(biāo)表中(這個(gè)時(shí)候可以使用事務(wù),保證事務(wù)的一致性)
3、 Sqoop在導(dǎo)入數(shù)據(jù)的時(shí)候數(shù)據(jù)傾斜
https://blog.csdn.net/lizhiguo18/article/details/103969906
sqoop 抽數(shù)的并行化主要涉及到兩個(gè)參數(shù):num-mappers:?jiǎn)?dòng)N個(gè)map來(lái)并行導(dǎo)入數(shù)據(jù)莱找,默認(rèn)4個(gè)酬姆;split-by:按照某一列來(lái)切分表的工作單元。
通過(guò)ROWNUM() 生成一個(gè)嚴(yán)格均勻分布的字段宋距,然后指定為分割字段
4轴踱、Sqoop數(shù)據(jù)導(dǎo)出Parquet(遇到)
ADS層數(shù)據(jù)用Sqoop往MySql中導(dǎo)入數(shù)據(jù)的時(shí)候,如果用了orc(Parquet)不能導(dǎo)入谚赎,需轉(zhuǎn)化成text格式
(1)創(chuàng)建臨時(shí)表淫僻,把Parquet中表數(shù)據(jù)導(dǎo)入到臨時(shí)表,把臨時(shí)表導(dǎo)出到目標(biāo)表用于可視化
(2)Sqoop里面有參數(shù)壶唤,可以直接把Parquet轉(zhuǎn)換為text
(3)ads層建表的時(shí)候就不要建Parquet表