天天看點

Sqoop導入關系資料庫到Hive1. 安裝 Sqoop2. 使用2.2 導入資料到 hdfs2.3 建立 hive 表2.4 導入資料到 hive2.5 增量導入2.6 合并 hdfs 檔案

sqoop 是 apache 下用于 rdbms 和 hdfs 互相導資料的工具。本文以 mysql 資料庫為例,實作關系資料庫導入到 hdfs 和 hive。

使用 rpm 安裝即可。

安裝完之後需要下載下傳 mysql jar 包到 sqoop 的 lib 目錄。

這裡使用 hive 的 metastore 的 mysql 資料庫作為關系資料庫,以 tbls 表為例,該表結構和資料如下:

檢視 sqoop 指令說明:

你也可以檢視某一個指令的使用說明:

你也可以使用别名來代替 <code>sqoop (toolname)</code>:

sqoop import 的一個示例如下:

你還可以使用 <code>--options-file</code> 來傳入一個檔案,使用這種方式可以重用一些配置參數:

/users/homer/work/import.txt 檔案内容如下:

使用 sqoop-import 指令可以從關系資料庫導入資料到 hdfs。

注意:

mysql jdbc url 請使用 ip 位址

如果重複執行,會提示目錄已經存在,可以手動删除

如果不指定 <code>--target-dir</code>,導入到使用者家目錄下的 tbls 目錄

你還可以指定其他的參數:

參數

說明

<code>--append</code>

将資料追加到hdfs中已經存在的dataset中。使用該參數,sqoop将把資料先導入到一個臨時目錄中,然後重新給檔案命名到一個正式的目錄中,以避免和該目錄中已存在的檔案重名。

<code>--as-avrodatafile</code>

将資料導入到一個avro資料檔案中

<code>--as-sequencefile</code>

将資料導入到一個sequence檔案中

<code>--as-textfile</code>

将資料導入到一個普通文本檔案中,生成該文本檔案後,可以在hive中通過sql語句查詢出結果。

<code>--boundary-query &lt;statement&gt;</code>

邊界查詢,也就是在導入前先通過sql查詢得到一個結果集,然後導入的資料就是該結果集内的資料,格式如:<code>--boundary-query 'select id,no from t where id = 3'</code>,表示導入的資料為id=3的記錄,或者 <code>select min(&lt;split-by&gt;), max(&lt;split-by&gt;) from &lt;table name&gt;</code>,注意查詢的字段中不能有資料類型為字元串的字段,否則會報錯

<code>--columns&lt;col,col&gt;</code>

指定要導入的字段值,格式如:<code>--columns id,username</code>

<code>--direct</code>

直接導入模式,使用的是關系資料庫自帶的導入導出工具。官網上是說這樣導入會更快

<code>--direct-split-size</code>

在使用上面direct直接導入的基礎上,對導入的流按位元組數分塊,特别是使用直連模式從postgresql導入資料的時候,可以将一個到達設定大小的檔案分為幾個獨立的檔案。

<code>--inline-lob-limit</code>

設定大對象資料類型的最大值

<code>-m,--num-mappers</code>

啟動n個map來并行導入資料,預設是4個,最好不要将數字設定為高于叢集的節點數

<code>--query,-e &lt;sql&gt;</code>

從查詢結果中導入資料,該參數使用時必須指定<code>–target-dir</code>、<code>–hive-table</code>,在查詢語句中一定要有where條件且在where條件中需要包含 <code>\$conditions</code>,示例:<code>--query 'select * from t where \$conditions ' --target-dir /tmp/t –hive-table t</code>

<code>--split-by &lt;column&gt;</code>

表的列名,用來切分工作單元,一般後面跟主鍵id

<code>--table &lt;table-name&gt;</code>

關系資料庫表名,資料從該表中擷取

<code>--delete-target-dir</code>

删除目标目錄

<code>--target-dir &lt;dir&gt;</code>

指定hdfs路徑

<code>--warehouse-dir &lt;dir&gt;</code>

與 <code>--target-dir</code> 不能同時使用,指定資料導入的存放目錄,适用于hdfs導入,不适合導入hive目錄

<code>--where</code>

從關系資料庫導入資料時的查詢條件,示例:<code>--where "id = 2"</code>

<code>-z,--compress</code>

壓縮參數,預設情況下資料是沒被壓縮的,通過該參數可以使用gzip壓縮算法對資料進行壓縮,适用于sequencefile, text文本檔案, 和avro檔案

<code>--compression-codec</code>

hadoop壓縮編碼,預設是gzip

<code>--null-string &lt;null-string&gt;</code>

可選參數,如果沒有指定,則字元串null将被使用

<code>--null-non-string &lt;null-string&gt;</code>

示例程式:

參照上表,使用 sql 語句查詢時,需要指定 <code>$conditions</code>

上面指令通過 <code>-m 1</code> 控制并發的 map 數。

這時候檢視 hdfs 中資料(觀察分隔符是否為制表符):

指定空字元串:

如果需要指定壓縮:

附:可選的檔案參數如下表。

<code>--enclosed-by &lt;char&gt;</code>

給字段值前後加上指定的字元,比如雙引号,示例:<code>--enclosed-by '\"'</code>,顯示例子:”3”,”jimsss”,”[email protected]

<code>--escaped-by &lt;char&gt;</code>

給雙引号作轉義處理,如字段值為”測試”,經過 <code>--escaped-by "\\"</code> 處理後,在hdfs中的顯示值為:<code>\"測試\"</code>,對單引号無效

<code>--fields-terminated-by &lt;char&gt;</code>

設定每個字段是以什麼符号作為結束的,預設是逗号,也可以改為其它符号,如句号<code>.</code>,示例如:<code>--fields-terminated-by</code>

<code>--lines-terminated-by &lt;char&gt;</code>

設定每條記錄行之間的分隔符,預設是換行串,但也可以設定自己所需要的字元串,示例如:<code>--lines-terminated-by "#"</code> 以#号分隔

<code>--mysql-delimiters</code>

mysql預設的分隔符設定,字段之間以<code>,</code>隔開,行之間以換行<code>\n</code>隔開,預設轉義符号是<code>\</code>,字段值以單引号<code>'</code>包含起來。

<code>--optionally-enclosed-by &lt;char&gt;</code>

enclosed-by是強制給每個字段值前後都加上指定的符号,而<code>--optionally-enclosed-by</code>隻是給帶有雙引号或單引号的字段值加上指定的符号,故叫可選的

生成與關系資料庫表的表結構對應的hive表:

<code>--hive-home &lt;dir&gt;</code>

hive的安裝目錄,可以通過該參數覆寫掉預設的hive目錄

<code>--hive-overwrite</code>

覆寫掉在hive表中已經存在的資料

<code>--create-hive-table</code>

預設是false,如果目标表已經存在了,那麼建立任務會失敗

<code>--hive-table</code>

後面接要建立的hive表

<code>--table</code>

指定關系資料庫表名

執行下面的指令會将 mysql 中的資料導入到 hdfs 中,然後建立一個hive 表,最後再将 hdfs 上的檔案移動到 hive 表的目錄下面。

說明:

可以在 hive 的表名前面指定資料庫名稱

可以通過 <code>--create-hive-table</code> 建立表,如果表已經存在則會執行失敗

接下來可以檢視 hive 中的資料:

直接檢視檔案内容:

從上面可見,資料導入到 hive 中之後分隔符為預設分隔符,參考上文你可以通過設定參數指定其他的分隔符。

另外,sqoop 預設地導入空值(null)為 null 字元串,而 hive 使用 \n 去辨別空值(null),故你在 import 或者 export 時候,需要做相應的處理。在 import 時,使用如下指令:

在導出時,使用下面指令:

一個完整的例子如下:

<code>--check-column (col)</code>

用來作為判斷的列名,如id

<code>--incremental (mode)</code>

append:追加,比如對大于last-value指定的值之後的記錄進行追加導入。lastmodified:最後的修改時間,追加last-value指定的日期之後的記錄

<code>--last-value (value)</code>

指定自從上次導入後列的最大值(大于該指定的值),也可以自己設定某一值

将hdfs中不同目錄下面的資料合在一起,并存放在指定的目錄中,示例如:

其中,<code>–class-name</code> 所指定的 class 名是對應于 person.jar 中的 person 類,而 person.jar 是通過 codegen 生成的

<code>--new-data &lt;path&gt;</code>

hdfs中存放資料的一個目錄,該目錄中的資料是希望在合并後能優先保留的,原則上一般是存放越新資料的目錄就對應這個參數。

<code>--onto &lt;path&gt;</code>

hdfs中存放資料的一個目錄,該目錄中的資料是希望在合并後能被更新資料替換掉的,原則上一般是存放越舊資料的目錄就對應這個參數。

<code>--merge-key &lt;col&gt;</code>

合并鍵,一般是主鍵id

<code>--jar-file &lt;file&gt;</code>

合并時引入的jar包,該jar包是通過codegen工具生成的jar包

<code>--class-name &lt;class&gt;</code>

對應的表名或對象名,該class類是包含在jar包中的。

<code>--target-dir &lt;path&gt;</code>

合并後的資料在hdfs裡的存放目錄