程序员的自我修养
Home » Apache Sqoop2 » Sqoop2初步使用感受

Sqoop2初步使用感受

8条评论8,640次浏览

最近将公司各个运营点的集群逐步转移入CDH。第一个遇到的问题就是Sqoop2的使用问题。

具体说来,分为下面几个方面。

Date类型字段的parse错误

测试sqoop2的时候就简单的测了下varchar和number类型的数据,发现没问题后就写了报告。现在我知道错了。

实际使用过程中,发现遇到表中有Date类型的column时,所有的job都会报以下错误:

2015-01-28 16:22:29,964 INFO [IPC Server handler 0 on 55187] org.apache.hadoop.mapred.TaskAttemptListenerImpl: JVM with ID : jvm_1422410148386_0003_m_000002 asked for a task
2015-01-28 16:22:29,966 INFO [IPC Server handler 0 on 55187] org.apache.hadoop.mapred.TaskAttemptListenerImpl: JVM with ID: jvm_1422410148386_0003_m_000002 given task: attempt_1422410148386_0003_m_000000_0
2015-01-28 16:22:35,516 FATAL [IPC Server handler 2 on 55187] org.apache.hadoop.mapred.TaskAttemptListenerImpl: Task: attempt_1422410148386_0003_m_000000_0 - exited : org.joda.time.LocalDateTime.parse(Ljava/lang/String;)Lorg/joda/time/LocalDateTime;
2015-01-28 16:22:35,517 INFO [IPC Server handler 2 on 55187] org.apache.hadoop.mapred.TaskAttemptListenerImpl: Diagnostics report from attempt_1422410148386_0003_m_000000_0: Error: org.joda.time.LocalDateTime.parse(Ljava/lang/String;)Lorg/joda/time/LocalDateTime;
2015-01-28 16:22:35,524 INFO [AsyncDispatcher event handler] org.apache.hadoop.mapreduce.v2.app.job.impl.TaskAttemptImpl: Diagnostics report from attempt_1422410148386_0003_m_000000_0: Error: org.joda.time.LocalDateTime.parse(Ljava/lang/String;)Lorg/joda/time/LocalDateTime;
2015-01-28 16:22:35,542 INFO [AsyncDispatcher event handler] org.apache.hadoop.mapreduce.v2.app.job.impl.TaskAttemptImpl: attempt_1422410148386_0003_m_000000_0 TaskAttempt Transitioned from RUNNING to FAIL_CONTAINER_CLEANUP

查阅遍了sqoop的官网和wiki,找不到任何有关DateFormat的设置方法和类似的错误解决方法。StackOverflow和sqoop-user讨论组都发了帖子和邮件求助,目前还没人可以解决。

有人说可以在选择Table column names的时候cast一下date类型的字段,好不好使我不知道,但通过这个,我遇到了第二个恶心的地方。

Table column names的长度限制

Table column names的长度限制居然是可笑的50,50意味着什么?意味着这样的一个column选择都无法完成:SERV_ID,DURATION,BILLING_NBR,CALLING_NBR,CALLED_NBR。我才选择了5个字段而已,长度就超过了50了。实际业务中,宽表的字段往往有200+,根本不可能全部导入,只能选择自己需要的导入,而往往需要选择的字段就超过50个了,更何况是输入的字段的字符串长度。

对于这个荒唐的限制,我还以为是sqoop出问题了,于是clone了源代码看了看,发现,卧了个槽,还真是这么限制的,我完全想不到这么做的任何好处?技术上无法处理?怎么可能!

导入的varchar类型数据全部带上单引号

好吧,工作还要继续,那就先不导入Date类型的数据了,宽表再宽我也全部都导入好了。那么第三个问题来了,为何导入的varchar类型全部都要带上单引号?这样直接导致以前的业务逻辑全部要重写,全部都要将读入的数据去掉单引号,而且分隔符也不是hadoop默认的'\t'而是','。我已经不想吐槽了,一定是我使用的方式不对。

Partition Column的可笑规则

当设置多个loader的时候,也就是启动多个map来导入数据,这时候就需要Partition Column来进行任务的分隔,以保证每个map不会重复导入数据。这个设定不错,这样的话启动多个map导入数据的速度也会提高很多。

但是,理想很丰满,现实很骨干。官方推荐的Partition Column是主键,于是我也用主键。集群有10台机器,于是我设置10个loader。测试了10+张表后发现,所有的job中,8个map是不会导入任何数据的,1个map会导入大约1%的数据,剩下的99%的数据由1个map导入。

查看日志,发现每个map的where语句类似如下:

导入了0条数据:
Using query: SELECT SERV_ID,DURATION,BILLING_NBR,CALLING_NBR FROM oradb4.T_NBIL_EVT_TGVAS_M_201412 WHERE 754187899923.1 <= SERV_ID AND SERV_ID < 754375550328.2

Sqoop2具体如何分隔的我不太清楚,就算是选出最小的主键和最大的主键,然后分隔成10份也不会出现这种一个map导入0条数据的情况吧?而且还是8个map导入0条数据,1个map导入1%的数据,1个map导入99%的数据。你是要采用多么可笑的策略才能弄出这样的结果的?难不成是选出最大的主键,然后分隔成10份?如果是这样我还真对不起你,对不起我的起始主键不是从1开始,这是我的错!

log日志的无限膨胀

Sqoop2导入数据时每隔一段时间or每隔多少行数据就会输出一条日志,类似:

2015-01-29 10:25:26,997 [main] DEBUG org.apache.sqoop.job.mr.SqoopMapper - Extracted data: 754000264762,0,'13319969983','13319969983'

这其实是一个很好的功能,让使用者知道目前还在导数据,大致导到了哪条数据。但是哥哥你能不能将输出的频率降低点,我导入一个2000W行的数据日志就差不多200MB了,要不是比原始数据大小要小很多我还以为你全量输出了。大数据你懂吗,就是数据量很大,你这么个日志输出法就不怕效率低下存储空间被占用么?

形同虚设的where condition

创建任务时除了可以选择columns以外还可以设置where语句,这个必备的功能居然是个摆设!!也就是完全无法使用。

官方文档、wiki上没有关于这个的任何示例和文档,google一下就会发现stackoverflow和google论坛上全部都是关于这个conditions如何使用的问题。

自行尝试各种输入可能性后任然报错,最后终于找到了一篇文章中介绍了如何使用,但实验后发现还是无法使用。不过这篇文章还是很有用的,至少让我猜出来Boundary query这个属性的作用了。但不用尝试我就相信这个属性也绝对不好使。

现在问题来了,又不能选择columns,又不能设置where语句,那你sqoop2还有啥作用?我用sqlplus去好么?

最后

无处可吐槽,只有在博客上发一篇博文泻泻心中的怒火了。

工作还得继续,只能继续解决这些可笑的问题了,可惜官网和wiki的资料如此之少,半天看完了,也解决不了任何问题。实在不行只能转回去研究如何让datax和cdh协同工作了。

补充——Date类型字段的parse错误

Date类型字段的parse错误总算搞定了。今天绝望中尝试了一下导入timestamp类型的数据,结果终于————还是失败了,但这次的失败不是一般的失败,这次的失败终于TM的多输出了几行错误信息:

java.lang.NoSuchMethodError: org.joda.time.LocalDateTime.parse
...

哥你要是早说是找不到方法我分分钟给你把jar包加进去好吗?

然后搜了下joda-time的包,发现namenode所挂载的文件夹(/mnt/disk02/yarn/nm/)下面已经有了,但还是报错,目测是啥东西不好使了。

/mnt/disk02/yarn/nm/usercache/sqoop2/filecache/110/joda-time-2.4.jar
/mnt/disk02/yarn/nm/usercache/sqoop2/filecache/66/joda-time-2.4.jar
/mnt/disk01/yarn/nm/usercache/sqoop2/filecache/12/joda-time-2.4.jar
/mnt/disk01/yarn/nm/usercache/sqoop2/filecache/23/joda-time-2.4.jar
/mnt/disk01/yarn/nm/usercache/sqoop2/filecache/34/joda-time-2.4.jar
/mnt/disk01/yarn/nm/filecache/29/joda-time-1.6.jar
/yarn/nm/usercache/sqoop2/filecache/121/joda-time-2.4.jar
/yarn/nm/usercache/sqoop2/filecache/99/joda-time-2.4.jar
/yarn/nm/usercache/sqoop2/filecache/55/joda-time-2.4.jar
/yarn/nm/usercache/sqoop2/filecache/88/joda-time-2.4.jar
/yarn/nm/usercache/sqoop2/filecache/44/joda-time-2.4.jar
/yarn/nm/usercache/sqoop2/filecache/77/joda-time-2.4.jar

然后尝试了下将joda-time-2.4.jar拷贝到/var/lib/hadoop-yarn/下面,并分发到所有机器上相同的位置,重启集群,不好使。

继续尝试将其拷贝到/opt/cloudera/parcels/CDH-5.3.0-1.cdh5.3.0.p0.30/lib/hadoop/lib/下面,分发,重启,终于好使了。

继续吐槽,joda-time这种重要的jar包,为何还要用户手动去分发?再说log中的错误提示也太应付了吧?明明是找不到方法,结果显示出来就一个parse错误。

补充——Partition Column的可笑规则

仔细的查了下测试导入的表,发现:

最小主键值:754000249518
最大主键值:755876753569

10个map对应的sql语句中的条件和数据库中查找出来的真实数量:

754000249518 <= SERV_ID AND SERV_ID < 754187899923.1 760845
754187899923.1 <= SERV_ID AND SERV_ID < 754375550328.2 0
754375550328.2 <= SERV_ID AND SERV_ID < 754563200733.3 0
754563200733.3 <= SERV_ID AND SERV_ID < 754750851138.4 0
754750851138.4 <= SERV_ID AND SERV_ID < 754938501543.5 0
754938501543.5 <= SERV_ID AND SERV_ID < 755126151948.6 24425871
755126151948.6 <= SERV_ID AND SERV_ID < 755313802353.7 60
755313802353.7 <= SERV_ID AND SERV_ID < 755501452758.8 0
755501452758.8 <= SERV_ID AND SERV_ID < 755689103163.9 0
755689103163.9 <= SERV_ID AND SERV_ID <= 755876753569.0 566

与之前的猜测一样,确实是选出最小和最大的Partition Column,然后等分成10份。

算我错怪你了,原来确实是数据主键分布不均匀造成的。遇到这种情况,要么换一个Partition Column,要么将map的数量设置成机器数量的多倍。

(转载本站文章请注明作者和出处 程序员的自我修养 – SelfUp.cn ,请勿用于任何商业用途)
分类:Apache Sqoop2
标签:,
8条评论
  1. wu说道:

    这个最近在用。最后字符串分号的问题怎么解决的呢?

  2. 李阳博客说道:

    最近我也在使用Sqoop,功能还是有些不完善啊。

  3. 匿名说道:

    我用着sqoop感觉还可以,select 几十个字段也没事,估计是版本低。。

  4. sf说道:

    楼主的问题,我都遇到。。。没办法项目已经定型了,最后都硬着头皮一个一个的改了源码

  5. 匿名说道:

    哈哈 看楼主的吐槽乐死了 where子句是可以写的 同样找不到资料 一点点试出来的
    select id from xxxx where ${CONDITIONS} and 1=1 and 2=2 limit 4

  6. 匿名说道:

    :razz: 楼主是属于会聊天的。
    我想问,sqoop发了几个版本了,应该没这些问题了吧。

发表评论


profile
  • 文章总数:81篇
  • 评论总数:241条
  • 分类总数:32个
  • 标签总数:45个
  • 运行时间:1253天

大家好,欢迎来到selfup.cn。

这不是一个只谈技术的博客,这里记录我成长的点点滴滴,coding、riding and everthing!

最新评论
  • Anonymous: :?: :razz: :sad:
  • Anonymous: 牛
  • Anonymous: 楼主你好,我偶尔也会 遇到Reconnect due to socket error: java.nio.channels.ClosedCha...
  • Anonymous: sdfs
  • Anonymous: :arrow: :neutral: :cry:
  • Anonymous: java.io.NotSerializableExcepti on: DStream checkpointing has been enabled but the DStreams with their...
  • wick: HI,请问一下,U,S,V得到 ,怎么得到近似矩阵 (用spark java),谢谢。
  • Michael Whitaker: Thank you for this blog, it was very helpful in troubleshooting my own issues. It seems that no...
  • Anonymous: :mad:
  • Anonymous: :???:
  • Anonymous: :mad: :mad: :mad:
  • 洋流: 哥们,我问个问题,你 把testOnborrow去掉了。。 如果得到的jedis资源...
  • 洋流: 哥们,我问个问题,你 把testOnborrow去掉了。。 如果得到的jedis资源...
  • Anonymous: :razz: :evil: :grin:
  • 张瑞昌: 有很多,比较常见的是 Jacob迭代法,一次迭代O (n^3),迭代次数不清楚 ...
  • Anonymous: :mrgreen:
  • lc277: 你好 我想问下一般删除节点 要多久,要删除的datano de大概用了1t,解除...
  • Anonymous: 你好 我想问下一般删除节点 要多久,要删除的datano de大概用了1t,解除...
  • Anonymous: :smile: :grin: :eek:
  • 李雪璇: 想要完整代码,可以帮 忙发给我吗