官方文檔 已經比較詳細,這里只是介紹幾個簡單的例子
導出到 HDFS
按列導出
sqoop import \
--connect jdbc:mysql://${host}:${port}/${db} \
--username ${user} \
--password ${passwd} \
--table foos \
--columns 'id,name,click,editdate' \
--where 'click >= 100' \
--delete-target-dir \
--target-dir /path/to/foos \
--hive-delims-replacement " " \
--fields-terminated-by '\001' \
--num-mappers 1
參數說明
-
--connect
,--username
,--password
數據庫連接參數 -
--table
需要導出的表名 -
--columns
需要導出的列,用,
分隔且不能重復 -
--delete-target-dir
導出的目標位置已經存在時,先刪除該目錄,沒有這個參數導出會終止 -
--target-dir
導出的目標位置 -
--hive-delims-replacement
替換文本字段中的\n
,\r
,\001
字符。Hive 會把\r
和\n
都當初新行來對待,如果導出的文本中包含這些字符,需要使用此參數 -
--fields-terminated-by
導出文件的列分隔符,導出的列包含復雜的文本字段,則必須使用\001
作為分隔符,這是由于 sqoop 只會替換\n
,\r
,\001
字符,如果分隔符為\t
且文本字段中包含\t
,就會導致列錯位 -
--num-mappers
并發的任務數量。建議設置為1
減少數據庫壓力。注意設置為大于1
的值時,sqoop 會額外啟動幾個重復的任務(通常是2個)來競爭資源
按查詢語句導出
sqoop import \
--connect jdbc:mysql://${host}:${port}/${db} \
--username ${user} \
--password ${passwd} \
--query "select id,name,click,editdate,'$day' as nowtime from foos where click >= 100 and \$CONDITIONS" \
--delete-target-dir \
--target-dir /path/to/foos \
--fields-terminated-by '\001' \
--hive-delims-replacement " " \
--num-mappers 4 \
--split-by id
--query
導出數據使用的查詢語句,條件中必須包含 $CONDITIONS
,用于并行導入任務。并行導入的條件由 --split-by
控制。查詢語句導出比較靈活,如可以導出重復的字段和使用數據庫函數轉換格式等,本例中添加了一個數據庫中沒有的 nowtime
字段作為輸出
導出到 HBase
sqoop import \
--connect jdbc:mysql://${host}:${port}/${db} \
--username ${user} \
--password ${passwd} \
--table foos \
--columns "id,name,click,editdate" \
--where "editdate > $start" \
--hbase-table foos \
--hbase-row-key id \
--column-family cf \
--num-mappers 1
和導出到 HDFS 的方式大致相同。目標位置從 HDFS 目錄變為 HBase 的表名、RowKey 和 列族。一次只能導出數據到一個列族中
增量導出
用 last_value 的方式來代替時間戳進行增量更新也會遇到之前數據不斷滾動導致丟失的問題(提交hadoop的任務太慢了)
參數 --check-column
, --incremental
, --last-value
用于指定增量導出的行為。下例中導出 editdate > 1469700476
的數據到 HBase.
注意增量導出用于時間戳字段時,可能會遇到更新很頻繁的數據遺漏問題。sqoop 在查詢前會獲取 check-column
的最新值,但是提交任務到 hadoop 的有較大的延遲,可能已經有很多數據被修改而沒有被導出
增量導出時候保存為任務執行,sqoop 會記錄任務最后一次更新的值
sqoop import \
--connect jdbc:mysql://${host}:${port}/${db} \
--username ${user} \
--password ${passwd} \
--table foos \
--columns ${columns} \
--hbase-table foos \
--hbase-row-key id \
--column-family cf \
--check-column editdate \
--incremental append \
--last-value 1469700476 \
--num-mappers 1 \
--verbose
保存任務
先修改 $SQOOP_HOME/conf/sqoop-site.xml
配置允許保存密碼
<property>
<name>sqoop.metastore.client.record.password</name>
<value>true</value>
</property>
創建任務
sqoop job --create update_foos -- import \
--connect jdbc:mysql://${host}:${port}/${db} \
--username ${user} \
--password ${passwd} \
--table foos \
--columns ${columns} \
--hbase-table foos \
--hbase-row-key id \
--column-family cf \
--check-column editdate \
--incremental append \
--num-mappers 1 \
--verbose
然后從一個比較近的時間點開始執行
sqoop job --exec update_foos -- --last-value 1469700476
再查看任務信息,發現 incremental.last.value
屬性已經更新
sqoop job --show update_foos