官方文档 已经比较详细,这里只是介绍几个简单的例子
导出到 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