Sqoop导入导出Null存储一致性问题
Hive中的Null在底层是以“\N”来存储,而MySQL中的Null在底层就是Null,为了保证数据两端的一致性,转化的过程中遇到null-string,null-non-string数据都转化成指定的类型,通常指定成"\N"。在导出数据时采用–input-null-string “\N” --input-null-non-string “\N” 两个参数。导入数据时采用–null-string “\N” --null-non-string “\N”。
Sqoop数据导出一致性问题
场景1:如Sqoop在导出到Mysql时,使用4个Map任务,过程中有2个任务失败,那此时MySQL中存储了另外两个Map任务导入的数据,此时老板正好看到了这个报表数据。而开发工程师发现任务失败后,会调试问题并最终将全部数据正确的导入MySQL,那后面老板再次看报表数据,发现本次看到的数据与之前的不一致,这在生产环境是不允许的。
实现方式
使用—staging-table选项,将hdfs中的数据先导入到辅助表中,当hdfs中的数据导出成功后,辅助表中的数据在一个事务中导出到目标表中(也就是说这个过程要不完全成功,要不完全失败)。
为了能够使用staging这个选项,staging表在运行任务前或者是空的,要不就使用—clear-staging-table配置,如果staging表中有数据,并且使用了—clear-staging-table选项,sqoop执行导出任务前会删除staging表中所有的数据。
注意:–direct导入时staging方式是不可用的,使用了—update-key选项时staging方式也不能用。
sqoop export \
--connect url \
--username root \
--password 123456 \
--table app_cource_study_report \
--columns watch_video_cnt,complete_video_cnt,dt \
--fields-terminated-by "\t" \
--export-dir "/user/hive/warehouse/tmp.db/app_cource_study_analysi_${day}" \
--staging-table app_cource_study_report_tmp \
--clear-staging-table \
--input-null-string '\\N' \
--null-non-string "\\N"
Sqoop底层运行的任务是什么
只有Map阶段,没有Reduce阶段的任务。
Map task并行度设置大于1的问题
并行度导入数据的 时候 需要指定根据哪个字段进行切分 该字段通常是主键或者是自增长不重复的数值类型字段,否则会报下面的错误。
Import failed: No primary key could be found for table. Please specify one with --split-by or perform a sequential import with ‘-m 1’.
那么就是说当map task并行度大于1时,下面两个参数要同时使用
–split-by id 指定根据id字段进行切分
–m n 指定map并行度n个
Sqoop 在导入数据的时候数据倾斜
Sqoop 抽数的并行化主要涉及到两个参数:num-mappers:启动 N 个 map 来并行导入
数据,默认 4 个;split-by:按照某一列来切分表的工作单元。
通过 ROWNUM() 生成一个严格均匀分布的字段,然后指定为分割字段
Sqoop 数据导出 Parquet(项目中遇到的问题)
Ads 层数据用 Sqoop 往 MySql 中导入数据的时候,如果用了 orc(Parquet)不能导入, 需转化成 text 格式
(1)创建临时表,把 Parquet 中表数据导入到临时表,把临时表导出到目标表用于可视 化
(2)Sqoop 里面有参数,可以直接把 Parquet 转换为 text
(3)ads 层建表的时候就不要建 Parquet 表