Sqoop工具模塊之sqoop-import

Sqoop工具模塊之sqoop-import

1、介紹

    import工具從RDBMS向HDFS導入單獨的表。表格中的每一行都表示爲HDFS中的單獨記錄。記錄能夠存儲爲文本文件(每行一個記錄),或以Avro或SequenceFiles的二進制表示形式存儲。java

一、命令格式

$ sqoop-import (generic-args) (import-args)

    Hadoop的通用參數必須在前,然後是導入參數,導入參數的順序隨意。mysql

2、導入參數

一、鏈接參數

    如下是鏈接數據庫的相應參數:算法

--connect <jdbc-uri>:指定JDBC鏈接字符串。
--connection-manager <class-name>:指定要使用的鏈接管理器類。
--driver <class-name>:手動指定要使用的JDBC驅動程序類。
--hadoop-mapred-home <dir>:覆蓋$ HADOOP_MAPRED_HOME--help打印使用說明。
--password-file:爲包含認證密碼的文件設置路徑。
-P:從控制檯讀取密碼。
--password <password>:設置驗證密碼。
--username <username>:設置驗證用戶名。
--verbose:在控制檯打印更多信息。
--connection-param-file <filename>:提供鏈接參數的可選屬性文件。
--relaxed-isolation:將鏈接事務隔離設置爲對映射器未提交的讀取。

    如下是安全驗證參數:sql

--validate:啓用對複製數據的驗證,僅支持單個表複製。
--validator <class-name>:指定要使用的驗證程序類。
--validation-threshold <class-name>:指定要使用的驗證閾值類。
--validation-failurehandler <class-name>:指定要使用的驗證失敗處理程序類。

二、導入控制參數

    如下是Sqoop在導入數據時,可選的控制導入數據內容的參數:shell

--append:將數據追加到HDFS中的現有數據集。
--as-avrodatafile:將數據導入Avro數據文件。
--as-sequencefile:將數據導入到SequenceFiles。
--as-textfile:以純文本形式導入數據(Sqoop導入的默認方式)。
--as-parquetfile:將數據導入Parquet文件。
--boundary-query <statement>:邊界查詢用於建立分割。
--columns <col,col,col…>:從表中選擇要導入列。
--delete-target-dir:刪除導入目標目錄(若是存在)。
--direct:若是數據庫存在,則使用直接鏈接器。
--fetch-size <n>:一次從數據庫讀取的條目數。
--inline-lob-limit <n>:設置內聯LOB的最大大小。
-m,--num-mappers <n>:使用n個map任務執行導入。
-e,--query <statement>:導入結果statement。
--split-by <column-name>:用於分割表單元的表格列。不能與--autoreset-to-one-mapper選項一塊兒使用 。
--split-limit <n>:每一個拆分大小的上限。這僅適用於整數和日期列。對於日期或時間戳字段,它以秒計算。
--autoreset-to-one-mapper:若是表中沒有主鍵而且沒有提供分割列,導入應該使用一個mapper。不能與--split-by <col>選項一塊兒使用。
--table <table-name>:導入的表名。
--target-dir <dir>:目標HDFS目錄。
--temporary-rootdir <dir>:導入期間建立的臨時文件的HDFS目錄(覆蓋默認的「_sqoop」)。
--warehouse-dir <dir>:表目的地的HDFS父級目錄。
--where <where clause>:在導入過程當中使用WHERE子句。
-z,--compress:啓用壓縮。
--compression-codec <c>:使用Hadoop編解碼器(默認gzip)。
--null-string <null-string>:要爲字符串列寫入空值的字符串。
--null-non-string <null-string>:要爲非字符串列寫入空值的字符串。
--null-string和--null-non-string參數都是可選的。若是未指定,那麼字符串「null」將被使用。

三、Hive參數

    如下是導入到Hive中時可選的參數:數據庫

--hive-home <dir>:覆蓋 $HIVE_HOME。
--hive-import:將表導入Hive(若是沒有設置,則使用Hive的默認分隔符。)
--hive-overwrite:覆蓋Hive表中的現有數據。
--create-hive-table:若是設置,那麼若是存在目標hivetable,做業將失敗。默認狀況下,此屬性爲false。
--hive-table <table-name>:設置導入到Hive時要使用的表名。
--hive-drop-import-delims:導入到Hive時,從字符串字段中刪除\n、\r和\01。
--hive-delims-replacement:在導入到Hive時,將字符串字段中的\n、\r和\01替換爲用戶定義的字符串。
--hive-partition-key:分配到分區的Hive字段的名稱。
--hive-partition-value <v>:做爲該任務導入到Hive中的分區鍵的字符串值。
--map-column-hive <map>:覆蓋從SQL類型到配置列的Hive類型的默認映射。若是在此參數中指定逗號,請使用URL編碼的鍵和值,例如,使用DECIMAL(1%2C%201)而不是DECIMAL(1,1)。

四、HBase參數

    如下是要導入HBase時可選的參數:apache

--column-family <family>:設置導入的目標列族。
--hbase-create-table:若是指定,則建立缺乏的HBase表。
--hbase-row-key <col>:指定哪一個輸入列用做行鍵若是輸入表包含複合鍵,那麼<col>必須以a的形式出現,逗號分隔組合鍵、列表、屬性。
--hbase-table <table-name>:指定要用做目標而不是HDFS的HBase表。
--hbase-bulkload:啓用批量加載。

五、Accumulo參數

    如下是要將數據導入Accumulo時可選的參數:編程

--accumulo-table <table-nam>:指定一個Accumulo表做爲導入目標表。
--accumulo-column-family <family>:設置導入的目標列族
--accumulo-create-table:若是指定,則建立沒有的Accumulo表。
--accumulo-row-key <col>:指定哪一個輸入列用做行鍵
--accumulo-visibility <vis>:(可選)指定一個可見性標記以應用於插入到Accumulo中的全部行。默認是空字符串。
--accumulo-batch-size <size>:(可選)設置Accumulo寫入緩衝區的大小(以字節爲單位)。默認值是4MB。
--accumulo-max-latency <ms>:(可選)爲Accumulo批處理寫入器設置最大等待時間(以毫秒爲單位)。缺省值是0。
--accumulo-zookeepers <host:port>:由Accumulo實例使用的Zookeeper服務器的逗號分隔列表。
--accumulo-instance <table-name>:目標Accumulo實例的名稱。
--accumulo-user <username>	:要導入爲的Accumulo用戶的名稱。
--accumulo-password <password>	:Accumulo用戶的密碼

3、文件格式

    Sqoop提供了兩種文件格式用於存儲導入的數據,分別是:分隔文本和SequenceFiles。緩存

一、分割文本

    分隔文本是默認的導入數據存儲格式。也可使用--as-textfile參數顯式指定。該方式將每一個基於字符串的表示形式的記錄寫入分割文件中,在各個行和列之間使用分隔符進行行列的劃分。分隔符能夠是逗號、製表符或其餘字符。如下是基於分割文本導入數據的示例:安全

1,這裏是一條消息,2010-05-01
2,新年快樂!,2010-01-01
3,另外一個消息,2009-11-12

    分隔文本適用於大多數非二進制數據類型。它也支持其餘工具的進一步操做,例如Hive。

二、SequenceFiles

    SequenceFiles是一種二進制格式,它將單個記錄存儲在自定義的特定的數據類型記錄中。這些數據類型表現爲Java類。Sqoop會自動生成這些數據類型。這種格式支持二進制表示中全部數據的準確存儲,適用於存儲二進制數據(例如,VARBINARY列)或將主要由自定義MapReduce程序操做的數據。從SequenceFiles讀取性能高於從文本文件讀取數據,由於記錄不須要被解析。

    Avro數據文件是一種緊湊且高效的二進制格式,可與使用其餘編程語言編寫的應用程序進行交互操做。Avro還支持版本控制,以便在添加或刪除列時,將之前導入的數據文件和新文件一塊兒處理。

三、壓縮

    默認狀況下,導入的數據未被壓縮。可使用-z或--compress參數的deflate(gzip)算法來壓縮數據,或使用--compression-codec參數指定Hadoop壓縮編解碼器。壓縮能夠用於SequenceFile,文本和Avro文件。

四、大對象

    Sqoop以特定的方式處理大型對象(BLOB和CLOB列)。若是這個數據確實很大,那麼這些列不該該像大多數列那樣徹底具體化在內存中進行操做。相反,他們的數據是以流的方式處理的。大型對象能夠內聯存儲其他的數據,在這種狀況下,在每次訪問時它們都徹底物化在內存中,或者它們能夠存儲在鏈接到主數據存儲的輔助存儲文件中。

    默認狀況下,小於16MB的大對象將內聯存儲到其餘數據中。若是大小較大,則將它們存儲在導入目標目錄的_lobs子目錄中的文件中。這些文件以針對大型記錄存儲優化的單獨格式存儲,能夠容納每一個記錄最多2^63字節的記錄。

    lob溢出到單獨文件的大小由--inline-lob-limit參數控制,該參數指定要保持內聯的最大lob大小(以字節爲單位)。若是將內聯LOB限制設置爲0,則全部大型對象都將放置在外部存儲中。

五、輸出行格式參數

--enclosed-by <char>:設置必需的字段包圍字符。
--escaped-by <char>:設置轉義字符。
--fields-terminated-by <char>:設置字段分隔符。
--lines-terminated-by <char>:設置行尾字符。
--mysql-delimiters:使用MySQL的默認分隔符集:字段:逗號(,)行:換行(\n)轉義:反斜槓(\)包含:單引號(’)。
--optionally-enclosed-by <char>:設置字段包圍字符。

六、分隔符

    導入數據到分隔文本時,分隔符的選擇很重要。若是字符串包含的字符中出現了分隔符,那麼會致使後續分析過程沒法清晰地解析導入的數據。

    例如,字符串"Hello, pleased to meet you"不該將字段結尾分隔符設置爲逗號。

1.分隔符種類

    分隔符能夠被指定爲:

    1.一個字符(--fields-terminated-by X)

    2.一個轉義字符(--fields-terminated-by \t)。支持的轉義字符是:

    \b(退格)、\n(新行)、\r(回車)、\t(製表符)、\"(雙引號)、\\'(單引號)、\\(反斜槓)、\0(NUL)。

    \0(NUL):表示在字段或行之間插入NUL字符,若是使用--enclosed-by、--optionally-enclosed-by或--escaped-by參數能夠控制禁用/啓用。

    3.UTF-8字符代碼點的八進制表示。形式爲:\0ooo,其中OOO是八進制的值。

    例如:--fields-terminated-by \001會產生^A字符。

    4.UTF-8字符代碼點的十六進制表示。形式爲:\0xhhh,其中hhh是十六進制的值。

    例如:--fields-terminated-by \0x10會產生回車符。

2.包含字符和轉義字符

    默認用於字段的分隔符是逗號(,),行數據的分隔符是換行符(\n),不用引號或者轉義字符。

    注意:若是在導入數據的字段中包含逗號或換行符,會致使數據分割模糊、不可分。爲了明確解析,二者都必須啓用。例如,經過--mysql-delimiters。

    若是沒法提供明確的分隔符,請使用包含字符和轉義字符。包含字符和轉義字符的組合能夠明確地解析行。

    例如:假設數據集的一列包含如下值:

Some string, with a comma.
Another "string with quotes"

    如下參數將提供能夠明確解析數據的分隔符:

$ sqoop import --fields-terminated-by , --escaped-by \\ --enclosed-by '\"' ...

    注意,爲了防止shell破壞包含字符,使用單引號將參數值引發來。

    以上命令應用於上述數據集的結果是:

"Some string, with a comma.","1","2","3"...
"Another \"string with quotes\"","4","5","6"...

    這裏導入的字符串顯示在附加列("1","2","3"等)的上下文中,以演示包含和轉義的所有效果。只有在分隔符字符出如今導入的文本中時,包含字符纔是必需的。所以能夠將包含字符指定爲可選:

$ sqoop import --optionally-enclosed-by '\"' (the rest as above)...

    導入數據的結果將是如下形式:

"Some string, with a comma.",1,2,3...
"Another \"string with quotes\"",4,5,6...

    注意:

    儘管Hive支持轉義字符,但它不能處理換行字符的轉義。此外,它不支持將可能包含內聯字符串中的字段分隔符的字符括起來的概念。所以,建議您在使用Hive時,選擇明確的字段和記錄終止分隔符,而不須要轉義和包含字符;這是因爲Hive的輸入解析能力有限。若是將數據導入Hive時不使用--escaped-by,--enclosed-by或--optionally-enclosed-by參數指定分隔符,則Sqoop將報警。

    --mysql-delimiters參數是一個簡短的參數,它使用mysqldump的默認分隔符。若是將mysqldump分隔符與direct模式(使用--direct)一塊兒使用,則能夠實現很是快速的導入。

    分隔符的選擇對於分割文本模式導入重要,使用--as-sequencefile導入到SequenceFiles仍然相關。生成類的toString()方法將使用前面指定的分隔符,所以輸出數據的後續格式將依賴於選擇的分隔符。

七、輸入解析參數

--input-enclosed-by <char>:設置必需的字段封閉器
--input-escaped-by <char>:設置輸入轉義字符
--input-fields-terminated-by <char>:設置輸入字段分隔符
--input-lines-terminated-by <char>:設置輸入的行尾字符
--input-optionally-enclosed-by <char>:設置字段包圍字符

    當Sqoop將數據導入到HDFS時,它會生成一個Java類,它能夠從新解釋它在進行分隔格式導入時建立的文本文件。分隔符的選擇有以下參數:

    --fields-terminated-by:此項將控制數據如何寫入磁盤,以及生成的parse()方法如何從新解釋這些數據。parse()方法使用的分隔符能夠獨立於輸出參數,經過--input-fields-terminated-by來選擇。

4、參數詳解

一、鏈接數據庫相關參數

    Sqoop旨在將數據庫中的表導入HDFS。

1.鏈接地址

    要鏈接數據庫須要使用--connect參數。此參數的值爲要鏈接的數據庫的地址,形式和數據庫驅動地址同樣。

    例如:如下是鏈接MySQL數據庫的命令。

$ sqoop import --connect jdbc:mysql://database.example.com/employees

    Sqoop支持多種數據庫。Sqoop會自動處理以jdbc:mysql://開頭的鏈接字符串。Sqoop也可使用其餘JDBC兼容的數據庫。

    步驟以下:

    首先,爲要導入的數據庫類型下載相應的JDBC驅動的jar包。

    而後,將jar包拷貝到$SQOOP_HOME/lib目錄中。若是是用RPM或Debian的方式安裝的話,目錄爲:/usr/lib/sqoop/lib。

    最後,將數據庫驅動類提供給Sqoop的--driver參數,做爲此參數的值。

    例如:常用的MySQL驅動:com.mysql.jdbc.Driver

$ sqoop import --driver com.mysql.jdbc.Driver \
    --connect <connect-string> ...

    例如:要鏈接到SQLServer數據庫,首先要下載驅動jar包並將其拷貝到Sqoop lib路徑中。而後運行Sqoop。命令以下:

$ sqoop import --driver com.microsoft.jdbc.sqlserver.SQLServerDriver \
    --connect <connect-string> ...

    使用JDBC鏈接到數據庫時,可使用--connection-param-file選項經過屬性文件選擇性地指定額外的JDBC參數。這個文件的內容被解析爲標準Java屬性,並在建立鏈接時傳遞給驅動程序。

    注意:經過可選屬性文件指定的參數僅適用於JDBC鏈接。任何使用非JDBC鏈接的快速路徑鏈接器都將忽略這些參數

2.用戶名密碼

    --username參數用來提供數據庫的用戶名。

    Sqoop提供了幾種不一樣的提交密碼的方法,下面詳細描述數據庫提供安全和不安全的密碼提交方式。

安全提交密碼的方式

    將密碼保存在具備400權限的用戶主目錄中的文件中,並使用--password-file參數指定該文件的路徑,這是輸入密碼的首選方法。

    Sqoop會從文件中讀取密碼,並使用安全的方式將它傳遞給MapReduce集羣,而沒必要在配置中公開密碼。包含密碼的文件能夠位於本地磁盤或HDFS上。

例如:

$ sqoop import --connect jdbc:mysql://database.example.com/employees \
    --username venkatesh --password-file ${user.home}/.password

    注意:Sqoop將讀取密碼文件的所有內容用做密碼。包括空格字符。須要確保密碼文件僅包含屬於密碼的字符。

    在命令行中,可使用echo -n來存儲密碼,這樣將不會產生多餘字符。

    例如:存儲secret爲密碼,可使用以下命令:

echo -n "secret" > password.file

    提供密碼的另外一種方式是使用-P參數,它將從控制檯提示符處讀取密碼。

保護密碼的方式

    Hadoop 2.6.0提供了一個API來將密碼存儲與應用程序分開。有一個新的credential命令行工具來管理密碼及其別名。密碼與其別名一塊兒存儲在密碼保護的密鑰庫中。密鑰庫密碼能夠經過環境變量提供給命令行的密碼提示,也能夠默認爲軟件定義的常量。Hadoop文檔中有關於此功能的使用說明。

    一旦使用Credential Provider工具存儲密碼而且Hadoop配置已經適當更新後,全部應用程序均可以選擇使用別名代替實際密碼,並在運行時解析別名以供使用密碼。

    因爲用於存儲憑證提供程序的密鑰庫或相似技術是經過組件共享的,所以各類應用程序,各類數據庫和其餘密碼能夠安全地存儲在其中,而且只有別名才須要在配置文件中公開,從而保護密碼免受可見。

    若是Sqoop依賴的Hadoop支持這種功能的話,那麼Sqoop也容許使用這種功能。此功能引入了一個新選項--password-alias來在命令行上提供別名,而不是實際的密碼。此選項的參數值是與實際密碼關聯的存儲器上的別名。用法示例以下所示:

$ sqoop import --connect jdbc:mysql://database.example.com/employees \
    --username dbuser --password-alias mydb.password.alias

    若是命令行的首選項不是此選項,則能夠將別名保存在--password-file選項提供的文件中。除此以外,Sqoop配置參數org.apache.sqoop.credentials.loader.class應該設置爲提供別名解析的類名:org.apache.sqoop.util.password.CredentialProviderPasswordLoader

    示例用法以下(假設.password.alias具備真實密碼的別名):

$ sqoop import --connect jdbc:mysql://database.example.com/employees \
    --username dbuser --password-file ${user.home}/.password-alias

    注意:

    --password參數是不安全的,由於其餘用戶可能經過程序的輸出從命令行參數中讀取密碼,密碼仍然使用不安全的方式在MapReduce集羣的節點之間傳輸。例如:

$ sqoop import --connect jdbc:mysql://database.example.com/employees \
    --username aaron --password 12345

二、控制導入數據相關參數

    Sqoop一般以表格爲單位的方式導入數據。導入的數據各個節點都是可選的,例如要導入的表、表中的字段、表中的數據等等。

1.選擇表

    --table參數用來選擇要導入的表。

    例如:--table employees。

    該參數還能夠標識數據庫中的一張表或其餘相似表的實體。

    默認狀況下,表格中的全部列都被選中用於導入。導入的數據以「天然順序」寫入HDFS。

    例如:包含列A,B和C的表數據導入結果以下:

A1,B1,C1
A2,B2,C2
...

2.選擇字段

    導入的列是可選的,使用--columns參數控制列的數量以及排序。使用「,」號進行列分割。

    例如:

--columns "name,employee_id,jobtitle"

3.選擇數據內容

    導入的數據也是可選的,使用--where參數能夠附加一個WHERE子句來選擇要導入的數據。默認狀況下,Sqoop生成表單的語句以下:

SELECT <column list> FROM <table name>

    例如:--where "id > 400"。只有列id值大於400的行纔會被導入。

4.選擇數據分割邊界

    默認狀況下,sqoop使用select min(<split-by>),max(<split-by>) from <table name>查詢找出建立分割的邊界。在某些狀況下,這個查詢不是最優化的,因此可使用--boundary-query參數指定列做爲邊界。

5.導入查詢結果集

    Sqoop也能夠導入任意SQL查詢的結果集。除了使用的--table,--columns和--where參數,還能夠指定--query的參數,其參數值爲簡單SQL語句。

    導入查詢結果集時,必須使用--target-dir參數指定目標目錄。

    若是要啓動多個mapper並行執行導入的話,則每一個mapper都須要執行查詢的語句,這樣就須要Sqoop推斷出每一個進程須要執行的任務邊界,那麼就須要使用--split-by指定一個列來進行任務邊界判斷的依據,這個列最好是整數類型並且沒有跳躍值的列,這樣可使每一個進程可以獲得均分的任務。

    例如:

$ sqoop import \
  --query 'SELECT a.*, b.* FROM a JOIN b on (a.id == b.id) WHERE $CONDITIONS' \
  --split-by a.id --target-dir /user/foo/joinresults

    或者,查詢能夠被執行一次並連續導入,方法是指定一個映射任務-m 1:

$ sqoop import \
  --query 'SELECT a.*, b.* FROM a JOIN b on (a.id == b.id) WHERE $CONDITIONS' \
  -m 1 --target-dir /user/foo/joinresults

    注意:

    1.若是使用雙引號(「)將查詢語句引發來的話,則必須使用\$CONDITIONS進行轉義,而不是$CONDITIONS, 轉義以後shell纔會將其視爲shell變量。雙引號查詢語句以下所示:

"SELECT * FROM x WHERE a='foo' AND \$CONDITIONS"

    2.在當前版本的Sqoop中使用SQL查詢的功能僅限於簡單查詢,其中不能包含模糊查詢和where子句中的OR條件。使用複雜的查詢,可能會致使意想不到的結果。

三、控制並行相關參數

    從數據庫導入數據的時候可使用-m或--num-mappers參數來增長導入任務的並行。這些參數中的每個參數值都是整數,該值與使用的並行度相對應。默認狀況下,使用四個任務。有些數據庫可能會經過將此值增長到8或16來提升性能。

    注意:

    1.不要將並行度提升到大於MapReduce集羣中可用的最大數量,若是超過,任務將連續運行,並可能增長執行導入所需的時間。

    2.不要將並行度設置的高於數據庫能夠合理支持的程度。例如:將100個併發客戶端鏈接到數據庫可能會增長數據庫服務器的負載,從而致使性能受到影響。

    在執行並行導入時,Sqoop須要一個能夠分割工做負載的標準。Sqoop使用列來分割工做量。默認狀況下,Sqoop將識別表中的主鍵列(若是存在)並將其用做拆分列。分割列的低值和高值從數據庫中檢索,而且mapper任務在總範圍的大小均勻的份量上進行操做。

    例如:有一個表的主鍵列id最小值爲0,最大值爲1000,而且Sqoop指向使用4個任務,則Sqoop將運行四個進程,每一個進程都執行以下的SQL語句:

SELECT * FROM sometable WHERE id >= lo AND id < hi

    每一個mapper任務的(lo, hi)的值分別對應爲(0,250),(250,500),(500,750)和(750,1001)。

    若是主鍵的實際值在其範圍內不均勻分佈,則可能致使任務不平衡。應該明確地選擇與--split-by參數不一樣的列。

    例如,--split-by employee_id。

    Sqoop目前不能在多列索引上拆分。若是表格沒有索引列,或者有多列鍵,那麼必須手動選擇拆分列。

    可使用--split-limit參數替換--num-mapers參數。使用--split-limit參數會限制所建立的拆分部分的大小。若是建立的分割大小大於此參數中指定的大小,則分割將根據此限制調整大小,而且分割的數量也根據此 項變化。若是根據--num-mappers參數計算出的分割大小超過了--split-limit參數設置的大小,那麼將增長實際的mapper數量。若是--split-limit 參數中指定的值爲0或負數,則該參數將被所有忽略,分割大小將根據mapper的數量計算。

    若是一個表沒有定義主鍵而且--split-by <col>參數也沒有指定,那麼導入將會失敗,除非使用--num-mappers 1選項或使用--autoreset-to-one-mapper選項將mapper的數量顯式設置爲1。--autoreset-to-one-mapper選項一般與import-all-tables工具一塊兒使用,自動處理沒有主鍵的表。

四、控制分佈式緩存相關參數

    每次啓動Sqoop做業時,Sqoop都會將$ SQOOP_HOME / lib文件夾中的jar包複製到做業緩存中。當由Oozie啓動時則不用,由於Oozie使用它本身的Sqoop共享庫,它將Sqoop依賴關係保留在分佈式緩存中。Oozie將在第一個Sqoop做業期間對Sqoop依賴關係的每一個工做節點執行本地化,並將工做節點上的jar包重用於子做業。

    在Oozie啓動時使用Sqoop命令中的--skip-dist-cache選項,將跳過Sqoop複製依賴關係到做業緩存並保存大量I/O的步驟。

五、控制導入過程

    默認狀況下,導入過程將使用供應商提供的JDBC導入通道。一些數據庫可使用特定的數據移動工具以更高性能的方式執行導入。

    MySQL提供的mysqldump工具能夠很是快速地將數據從MySQL導出到其餘系統。Sqoop能夠經過--direct參數指定該工具導入,比使用JDBC性能更高。

    默認狀況下,Sqoop將數據導入HDFS中一個名爲foo的目錄中。

    例如,用戶名是someuser,則導入工具會將數據寫入/user/someuser/foo/(files)中。

    可使用--warehouse-dir參數調整導入的這個目錄。

    例如:

$ sqoop import --connnect <connect-str> --table foo --warehouse-dir /shared

    該命令將數據寫入目錄/shared/foo/目錄下的文件中。

    能夠明確地選擇目標目錄,以下所示:

$ sqoop import --connnect <connect-str> --table foo --target-dir /dest

    上述命令將文件導入到/dest目錄中。--target-dir與--warehouse-dir不相容。只能使用二者之一。

    使用direct模式時,能夠指定應傳遞給底層工具的其餘參數。若是參數--是在命令行上 出現的,則--後的參數將直接發送到底層工具。

    例如,如下內容將調整mysqldump使用的字符集:

$ sqoop import --connect jdbc:mysql://server.foo.com/db --table bar \
    --direct -- --default-character-set=latin1

    默認狀況下,數據將導入到新的目標位置。若是目標目錄已經存在於HDFS中,Sqoop將拒絕導入並覆蓋該目錄的內容。

    若是使用--append參數,Sqoop會將數據導入臨時目錄,而後以不與該目錄中現有文件名衝突的方式將文件重命名爲正常目標目錄。

六、控制事務隔離

    默認狀況下,Sqoop在mapper中導入數據使用讀提交事務隔離。這可能不是全部ETL工做流程中的理想選擇,而且可能但願減小隔離保證。Sqoop使用--relaxed-isolation選項能夠指定讀取的事物隔離級別。

    --read-uncommitted隔離級別不支持全部數據庫(例如Oracle),所以指定選項--relaxed-isolation可能沒法在全部數據庫的支持。

七、控制類型映射

    Sqoop預先配置爲將大多數SQL類型映射到適當的Java或Hive類型。默認映射可能並不適合每一個場景,可使用--map-column-java(用於更改映射到Java)或--map-column-hive(用於更改Hive映射)進行更改。

--map-column-java <mapping>:指定已配置列從SQL到Java類型的映射。
--map-column-hive <mapping>:指定從SQL到配置列Hive類型的映射。

    Sqoop以<列名稱> = <新類型>形式的逗號分隔映射列表。

    例如:

$ sqoop import ... --map-column-java id = String,value = Integer

    注意:在--map-column-hive選項中須要逗號分割,應使用URL編碼的鍵和值,例如,使用DECIMAL(1%2C%201)而不是DECIMAL(1,1)。若是某些配置的映射不可用,Sqoop會拋出異常。

八、結構名稱處理

    當sqoop從企業存儲導入數據時,表名和列名可能不是有效的Java標識符或Avro/Parquet標識符。爲了解決這個問題,sqoop將這些字符翻譯爲_做爲建立的一部分。任何以_(下劃線)字符開頭的列名將被翻譯爲具備兩個下劃線字符。

    例如:_AVRO將被轉換爲__AVRO。

    在HCatalog導入的狀況下,當映射到HCatalog列時,列名將轉換爲小寫。

九、增量導入

    Sqoop提供了一種增量導入模式,可用於檢索比之前導入的一組行更新的行數據。

    如下參數控制增量導入:

--check-column (col):要導入某些行時要檢查的列。(該列不能是CHAR/NCHAR/VARCHAR/VARNCHAR/LONGVARCHAR/LONGNVARCHAR類型)。
--incremental (mode):指定Sqoop如何肯定哪些行是新的。此項參數的值有append和lastmodified兩個。
--last-value (value):指定先前導入中的檢查列的最大值。

1.增量導入方式

    Sqoop支持兩種方式的增量導入:append和lastmodified。可使用該--incremental參數來指定要執行的增量導入的方式。

1>append

    append方式在導入表格時,必須指定起始行id列所對應的值。能夠經過--check-column指定該行包含的列。Sqoop導入行的檢查列的值是否大於--last-value參數指定的值。

1>lastmodified

    Sqoop支持的備用表更新策略稱爲lastmodified模式。

    當源表的行更新時,每次更新都會將最後更新的列的值設置爲當前的時間戳,若是行檢查的列的時間戳比--last-value指定的時間戳新,那麼該行會被導入。

    在增量導入結束時,--last-value應爲後續導入指定的值打印到屏幕上。在運行後續導入時,--last-value會指定上次的值以確保導入新的數據。這是增量導入自動處理的,這也是執行循環增量導入的首選機制。

十、Hive相關參數

    Sqoop的導入工具的主要功能是將數據上傳到HDFS中的文件中。若是Hive Metastore與HDFS集羣相關聯,則Sqoop還能夠將數據導入到Hive中,並執行CREATE TABLE語句來定義Hive中的數據佈局。將數據導入Hive中很是簡單,只須要在命令中加入--hive-import參數便可。

1.覆蓋表格

    若是Hive中表已經存在,可使用--hive-overwrite參數指定要替換表。而後將數據導入HDFS或省略此步驟,Sqoop還將生成一個Hive腳本,其中包含CREATE TABLE語句和LOAD DATA INPATH語句。

2.指定目錄

    腳本將在安裝了Sqoop的機器上運行。若是安裝了多個Hive,或者沒有配置hive的環境變量$PATH,可使用--hive-home參數來指定Hive的安裝目錄。Sqoop的$PATH通常爲:$HIVE_HOME/bin/hive

    注意:將數據導入到Hive中不能使用--as-avrodatafile和--assequencefile兩種文件的存儲方式。

3.指定分隔符

    若是數據庫的數據內容包含Hive的缺省行分隔符(\n和\r字符)或列分隔符(\01字符)的字符串字段,則使用Sqoop將數據導入到Hive中時會遇到問題。

    可使用--hive-drop-import-delims選項在導入時刪除這些字符,以保證數據與Hive的文本數據格式兼容。或者,可使用該--hive-delims-replacement選項在導入時將這些字符替換爲自定義的字符串,以保證數據與Hive的文本數據格式兼容。

    使用Hive的默認分隔符時使用這兩個參數。

    若是使用--hive-import參數並無設置分隔符,則使用Hive的默認分隔符:字段分隔符爲^A,記錄分隔符爲\n。

    Sqoop將默認導入NULL值做爲字符串null。Hive使用字符串\N來表示NULL值,所以在將數據導入Hive中時NULL將沒法被正確識別。

    若是想要在數據導入Hive時正確地處理NULL,可使用參數--null-string和--null-non-string。

    若是想要在數據導出Hive時正確的處理NULL,可使用參數--input-null-string和--input-null-non-string。

    由於sqoop在生成的代碼中須要使用這些參數,因此須要正確地將值轉義\N爲\\N:

$ sqoop import ... --null-string '\\N' --null-non-string '\\N'

4.指定表名

    Hive中使用的表名默認狀況下與源表的名稱相同。也可使用--hive-table選項控制輸出表名稱。

5.指定分區

    Hive能夠將數據放入分區以提升查詢性能。Sqoop能夠經過指定--hive-partition-key和--hive-partition-value參數將數據導入Hive的特定分區。分區值必須是一個字符串。有關分區的更多詳細信息,請參閱Hive文檔。

6.指定壓縮

    --compress和--compression-codec選項能夠將數據壓縮以後導入Hive中。

    壓縮導入到Hive中的表格的一個缺點是壓縮的編碼不能切分,從而致使不能並行mapper任務處理。

    lzop編解碼器支持分割。使用此壓縮編解碼器導入表格時,Sqoop將根據索引文件自動的對數據進行切分並建立正確的Hive表格式。此功能目前必須使用lzop編解碼器對錶的全部分區進行壓縮。

十一、HBase相關參數

    Sqoop支持HDFS和Hive以外的其餘導入目標。Sqoop一樣也支持將數據導入HBase中的表中。

    1.建立表

    若是目標表和列族不存在,則Sqoop做業將退出並顯示錯誤。在運行導入以前,應該建立目標表。

    也可使用--hbase-create-table參數,讓Sqoop使用HBase配置中的默認參數建立目標表和列族(若是它們不存在)。

2.選定目標表

    --hbase-table參數指定HBase接收數據的表。導入每一行的數據的操做都會轉換爲HBase Put操做。

3.指定行鍵

    每行的行鍵取自輸入的一列,默認狀況下,Sqoop將使用分隔列做爲行鍵。若是沒有指定分割列,它將使用源表的主鍵列(若是有的話)做爲行鍵。

    --hbase-row-key參數能夠指定行鍵列。

    若是導入的表具備聯合主鍵,--hbase-row-key必須以逗號分隔聯合主鍵。在這種狀況下,HBase的行鍵將經過下劃線分割聯合主鍵的形式來生成。注意:只有--hbase-row-key在指定了參數的狀況下,Sqoop才能正常導入具備聯合主鍵的表。

4.指定列族

    --column-family參數指定列族,每一個輸出列將被放置在同一個列族中。

    注意:此參數與direct模式導入(參數--direct)不兼容。

    Sqoop將當前全部值序列化爲HBase,方法是將每一個字段轉換爲其字符串表示(就像在文本模式中導入HDFS同樣),而後將此字符串的UTF-8字節插入到目標單元格中。Sqoop將跳過除行鍵列之外的全部列中包含空值的行。

5.批量加載

    --hbase-bulkload參數能夠執行批量加載而不是直接寫入,能夠減輕HBase的負載。

三、Accumulo相關參數

    Sqoop支持將數據導入Accumulo中。

    因爲本人對Accumulo這項技術不是很瞭解,此處暫時不作介紹,看官方文檔的介紹和HBase差很少,這裏只將參數列出,留待之後作補充。

四、自定義參數

    用戶能夠經過修改配置文件conf/sqoop-site.xml來指定參數。參數能夠像Hadoop配置文件中同樣指定,例如:

<property>
<name>property.name</name>
<value>property.value</value>
</property>

    也能夠在命令行中使用通用參數指定,例如:

sqoop import -D property.name = property.value ...

5、應用

    如下應用示例說明如何在各類狀況下使用導入工具。

一、基礎應用

    從數據庫導入表名爲EMPLOYEES的表的數據:

$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES

    數據庫鏈接驗證:

$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
--username SomeUser -P
Enter password: (hidden)

    選擇導入的列:

$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
    --columns "employee_id,first_name,last_name,job_title"

    控制並行導入(指定8個mappper):

$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
    -m 8

    將數據存儲在SequenceFiles中,並將生成的類名稱設置爲com.foocorp.Employee:

$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
    --class-name com.foocorp.Employee --as-sequencefile

    指定分隔符:

$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
    --fields-terminated-by '\t' --lines-terminated-by '\n' \
    --optionally-enclosed-by '\"'

    導入數據到Hive中:

$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
    --hive-import

    導入新增數據:

$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
    --where "start_date > '2010-01-01'"

    指定分割列:

$ sqoop import --connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
    --split-by dept_id

    驗證是否導入成功:

$ hadoop fs -ls EMPLOYEES
Found 5 items
drwxr-xr-x   - someuser somegrp          0 2010-04-27 16:40 /user/someuser/EMPLOYEES/_logs
-rw-r--r--   1 someuser somegrp    2913511 2010-04-27 16:40 /user/someuser/EMPLOYEES/part-m-00000
-rw-r--r--   1 someuser somegrp    1683938 2010-04-27 16:40 /user/someuser/EMPLOYEES/part-m-00001
-rw-r--r--   1 someuser somegrp    7245839 2010-04-27 16:40 /user/someuser/EMPLOYEES/part-m-00002
-rw-r--r--   1 someuser somegrp    7842523 2010-04-27 16:40 /user/someuser/EMPLOYEES/part-m-00003

$ hadoop fs -cat EMPLOYEES/part-m-00000 | head -n 10
0,joe,smith,engineering
1,jane,doe,marketing
...

    增量導入:

$ sqoop import --connect jdbc:mysql://db.foo.com/somedb --table sometable \
    --where "id > 100000" --target-dir /incremental_dataset --append

    使用validation對數據進行驗證:

$ sqoop import --connect jdbc:mysql://db.foo.com/corp \
    --table EMPLOYEES --validate

二、從數據庫到HDFS

    將關係型數據庫導入數據到HDFS:

sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \
--username root --password 123  --table trade_detail \
--columns 'id, account, income, expenses'

    指定輸出路徑、指定數據分隔符:

sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \
--username root --password 123  --table trade_detail \
--target-dir '/sqoop/td' --fields-terminated-by '\t'

    指定Map數量 -m

sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \
--username root --password 123 --table trade_detail \
--target-dir '/sqoop/td1' --fields-terminated-by '\t' -m 2

    增長where條件, 注意:條件必須用引號引發來

sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \
--username root --password 123  --table trade_detail \
--where 'id>3' --target-dir '/sqoop/td2'

    增長query語句(使用 \ 將語句換行)

sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \
--username root --password 123 \
--query 'SELECT * FROM trade_detail where id > 2 AND $CONDITIONS' \
--split-by trade_detail.id --target-dir '/sqoop/td3'

    注意:

    若是使用--query這個命令的時候,須要注意的是where後面的參數,AND $CONDITIONS這個參數必須加上,並且存在單引號與雙引號的區別,若是--query後面使用的是雙引號,那麼須要在$CONDITIONS前加上\即\$CONDITIONS。

    若是設置map數量爲1個時即-m 1,不用加上--split-by ${tablename.column},不然須要加上。

三、從數據庫到HIVE

    將關係型數據庫導入數據到hive:

sqoop import --connect jdbc:mysql://192.168.1.10:3306/test \
--username root --password 123  --table person \
--hive-import --hive-table hivetab1 -m 1

 

上一篇:Sqoop簡介以及安裝

下一篇:Sqoop工具模塊之sqoop-import-all-tables

相關文章
相關標籤/搜索