1.hive表export到mysql
#!/bin/bash
db_name=gmall
mysql_table=$1
hdfsPath=/warehouse/${db_name}/ads/${mysql_table}
export_data() {
sqoop export \
--connect "jdbc:mysql://hadoop01:3306/${db_name}?useUnicode=true&characterEncoding=utf-8" \
--username root \
--password root \
--table ${mysql_table} \
--num-mappers 1 \
--export-dir ${hdfsPath}\
--input-fields-terminated-by "\t" \
--update-mode allowinsert \
--update-key "tm_id,category1_id,stat_mn" \
--input-null-string '\\N' \
--input-null-non-string '\\N'
}
case ${mysql_table} in
"ads_uv_count")
export_data "ads_uv_count"
;;
"ads_user_action_convert_day")
export_data "ads_user_action_convert_day"
;;
"ads_gmv_sum_day")
export_data "ads_gmv_sum_day"
;;
"all")
export_data "ads_uv_count"
export_data "ads_user_action_convert_day"
export_data "ads_gmv_sum_day"
;;
esac
参数说明:
–update-mode
updateonly 只更新,无法插入新数据
allowinsert 允许新增
–update-key
允许更新的情况下,指定哪些字段匹配视为同一条数据,进行更新而不增加。多个字段用 逗号分隔
–input-null-string、–input-null-non-string
分别表示,将字符串列和非字符串列的空串和“null”转换成’\N’。
Hive中的Null在底层是以“\N”来存储,而MySQL中的Null在底层就是Null,为了保证数据两端的一致性。在导出数据时采用–input-null-string和–input-null-non-string两个参数。导入数据时采用–null-string和–null-non-string
参考:http://sqoop.apache.org/docs/1.4.6/SqoopUserGuide.html
2.mysql表import到hive
sqoop import \
--connect jdbc:mysql://hadoop01:3306/$db_name \
--username root \
--password root \
--target-dir /tmp/mysql-sqoop-hdfs/$db_name/db/$1/$db_date \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--query "$2" 'and $CONDITIONS;'
3.sqoop数据导出一致性的问题
sqoop export \
--connect jdbc:mysql://192.168.226.88:3306/user_behavior \
--username root \
--password root \
--table table_target \
--columns watch_video_cnt,complete_video_cnt,dt \
--fields-terminated-by "\t" \
--export-dir "${hdfspath}" \
--staging-table table_tmp \
--clear-staging-table \
--input-null-string '\\N' \
--input-null-non-string '\\N'
问题:
如Sqoop在导出到Mysql时,使用4个Map任务,过程中有2个任务失败,那此时MySQL中存储了另外两个Map任务导入的数据,此时老板正好看到了这个报表数据。而开发工程师发现任务失败后,会调试问题并最终将全部数据正确的导入MySQL,那后面老板再次看报表数据,发现本次看到的数据与之前的不一致,这在生产环境是不允许的。
解决方法:
–staging-table +临时表名
该参数是用来保证在数据导入关系数据库表的过程中事务安全性的,因为在导入的过程中可能会有多个事务,那么一个事务失败会影响到其它事务,比如导入的数据会出现错误或出现重复的记录等等情况,那么通过该参数可以避免这种情况。创建一个与导入目标表同样的数据结构,保留该表为空在运行数据导入前,所有事务会将结果先存放在该表中,然后最后由该表通过一次事务将结果写入到目标表中。
–clear-staging-table
如果该staging-table非空,则通过该参数可以在运行导入前清除staging-table里的数据
4.sqoop底层运行的任务
只有map阶段,没有reduce阶段的任务