笨鸟的平凡之路-sqoop将mysql数据导入hive多分区表时加载emoji数据出错解决方案

问题出现:

最近在做mysql数据导入到hive多分区表的工作。在测试时发现hive数据总条数多出源表数据几倍。从mysql查看几条数据与hive对应的数据进行对比,发现mysql一条数据在hive中被加载成多行数据。如下图:
原始description_shop一条数据:
😊😊😊 Bem-vindos a minha loja! 😊😊😊
📢📢 Oferecemos a você os melhores produtos e artigos para sua casa!
🌟🌟 Nossa missão é atender você da melhor maneira, não se esqueça de nos avaliar com 5 estrelas!
🎈🎈 Siga nossa loja e receba um cupom adicional!
💕💕 Boas compras!
在这里插入图片描述
mysql中取10条数据结果:
MySQL数据
hive中取10条数据结果:
Hive数据
问题出现了,mysql中1条数据在hive中被加载成了多行。

有同学第一时间可能想到我的sqoop语句中是否将-m 指定为1,来,下面上测试脚本:

#1.建hive分区表,先将分区表建好
#2.修改需要导入的表和批次
tablename='shopinfo1'
#3.一级分区
locate='test'
#4.二级分区
batch='1'

#5.将mysql数据导入到hdfs中
sqoop import --connect "jdbc:mysql://192.168.0.213:3306/test" --username root --password 111111 --table $tablename --target-dir /user/hive/warehouse/shopinfo1/locate=$locate/batch=$batch --append --fields-terminated-by '\t' -m 1

#6.增加hive分区表及指定数据目录
#7.刷新分区表
hive -e 'ALTER TABLE shopinfo1 ADD PARTITION(locate="'$locate'",batch="'$batch'") LOCATION "'/user/hive/warehouse/shopinfo1/locate=$locate/batch=$batch'";'

很明显,我已经指定了 -m 1,即指定执行MapReduce的个数为1。

解决方案:

1.使用parquet存储方式。
将hive分区表改成以parquet方式存储数据,同时在利用Sqoop导入数据的时候也要指定parquet存储方式
过程:

#5.将mysql数据导入到hdfs中
sqoop import --connect "jdbc:mysql://192.168.0.213:3306/test" --username root --password 111111 --table $tablename --target-dir /user/hive/warehouse/shopinfo1/locate=$locate/batch=$batch --append --fields-terminated-by '\t' -m 1 --as-parquetfile

在这里插入图片描述
HDFS上数据:
在这里插入图片描述

2.利用优化参数–direct
sqoop参数中有优化mysql导数速度的关键参数–direct。
该参数的作用是利用直连模式,使用mysqldump加快速度。
但是使用该参数需要注意以下问题:

  • 【WARN manager.DirectMySQLManager: Direct-mode import from MySQL does not support column】direct方式仅仅支持所有的列 有column的话direct就无效了
  • 【Error: java.io.IOException: Cannot run program “mysqldump”: error=2, No such file or directory】 需要把mysqldump复制到从节点:scp /usr/bin/mysqldump cm-slave1:/usr/bin/
  • 使用direct会使得–null-non-string –null-string无效

过程:

#5.将mysql数据导入到hdfs中
sqoop import --connect "jdbc:mysql://192.168.0.213:3306/test" --username root --password 111111 --table $tablename --target-dir /user/hive/warehouse/shopinfo1/locate=$locate/batch=$batch --append --fields-terminated-by '\t' -m 1 --direct

在这里插入图片描述
HDFS上数据:
在这里插入图片描述

两种方案的MR区别:

1.改用parquet存储方式的MR过程是Map阶段读取了每条数据
在这里插入图片描述
2.添加–direct参数的MR过程Map阶段一次性读取全部数据
在这里插入图片描述

展示解决后的效果:

1.使用parquet方式
在这里插入图片描述

2.使用–direct方式
在这里插入图片描述

总结,mysql数据的编码格式是utf8mb4,hive编码格式utf8.不管用parquet存储还是–direct参数优化,都不能将emoji表情数据完整的存储。

如果有同学有更好的处理方式,希望不吝赐教🌹🌹🌹

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值