使用sqoop import 命令从postgresql导入数据到hive中,发现数据行数变多了,但是任务没有跑错,非常奇怪。
导入语句为:
sqoop import --connect jdbc:postgresql://*.*.*.*:5432/database_name --username name111 --password password111 --table table111 --hive-import --hive-database database111 --hive-table hive_table111 --hive-overwrite --delete-target-dir --hive-drop-import-delims --null-string '' --null-non-string '' -m5
导入前pgsql数据量为3698条,但是导入后再hive中的数据量为3938,数据竟然变多了。最后发现将参数-m5,改为-m1即可解决问题。
为什么呢?
我们先来了解一下参数-m的含义以及sqoop导入的原理。
首先用户输入一个 Sqoop import 命令,Sqoop 会从关系型数据库中获取元数据信息,比如要操作数据库表的 schema是什么样子,这个表有哪些字段,这些字段都是什么数据类型等。它获取这些信息之后,会将输入命令转化为基于 Map 的 MapReduce作业,这样 MapReduce作业中有很多 Map 任务,每个 Map 任务从数据库中读取一片数据,这样多个 Map 任务实现并发的拷贝,把整个数据快速的拷贝到 HDFS 上。
而决定切分成多少个map就是参数-m的作用,-m5代表切分为5个map,-m1代表切分为1个map,即不用切分。
而决定用什么字段来切分,就是用--split-by来制定的。当sqoop import 没有定义--split-by时,默认使用源数据表的key作为切分字段。
split-by 根据不同的参数类型有不同的切分方法,如int型,Sqoop会取最大和最小split-by字段值,然后根据传入的num-mappers来 确定划分几个区域。比如select max(split_by),min(split-by) from得到的max(split-by)和min(split-by)分别为1000和1,而num-mappers(-m)为2的话,则会分成两个区域 (1,500)和(501-1000),同时也会分成2个sql给2个map去进行导入操作,分别为select XXX from table where split-by>=1 and split-by<500和select XXX from table where split-by>=501 and split-by<=1000.最后每个map各自获取各自SQL中的数据进行导入工作。
那回到最开始的问题,为什么切分数目不一样,结果就不一样呢?理论上无论怎么切分,导入的数据都应该是一样的,但现在甚至还多了?这是因为,用来切分的字段不友好,不是int型或者有排序规律的。
这种id内容是没有排序规则的,比如本来10条id切两份得到(5,5),现在切出来时(5,6),有一个id重复了,就导致数量变多了。
所以解决办法有两个:
一是将 -m5 改成 -m1 直接不切分;
二是 --split-by制定另外的字段,换一个int型的或者有明确排序顺序的字段。
除了以上这种原因导致数据变多,语句缺少 --hive-drop-import-delims 也可能导致问题的出现,解决如下:
关于在sqoop导入数据的时候,数据量变多的解决方案。
今天使用sqoop导入一张表,我去查数据库当中的数据量为650条数据,但是我将数据导入到hive表当中的时候出现了563条数据,这就很奇怪了,我以为是数据错了,然后多导入了几次数据发现还是一样的问题。
然后我去查数据字段ID的值然后发现建了主键的数据怎么可能为空的那。然后我去看数据库当中的数据发现,数据在存入的时候不知道加入了什么鬼东西,导致数据从哪一行截断了,导致多出现了三条数据。下面是有问题的字段。
这里我也不知道数据为啥会是这样,我猜想是在导入数据的时候hive默认行的分割符号是按照\n的形式导入进来的,到这里遇到了这样的字符就对其按照下一行进行对待将数据截断了。
然后我测试了一直自定义的去指定hive的行的分割符号,使用--lines-terminated-by 指定hive的行的分割符号,但是不幸的是好像这个是不能改的。他会报下面的错误:
FAILED: SemanticException 1:424 LINES TERMINATED BY only supports newline '\n' right now. Error encountered near token ''\164'' 于是上网找资料,然后发现可以使用一个配置清除掉hive当中默认的分割符号,然后导入数据,配置如下: --hive-drop-import-delims 这个参数是去掉hive默认的分割符号,加上这个参数然后在使用--fields-terminated-by 指定hive的行的分割符号 最终数据导入成功,数据量和原来数库当中的数据一致。
上面是sqoop脚本的部分内容,下面是执行完hive之后,hive创建的表,字段之间默认的分割符号。
至此问题得到了解决。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]