最近在研究如何使用sqoop2来做数据etl。sqoop2采用了mapreduce机制,可以让多个节点同时抽取数据,这样可以提高效率。理念不错,但是这个软件由于是开源产品,做得并不是很完善,我在使用它连接oracle数据库的时候,就掉坑里了。
按照教程,使用sqoop2-shell命令行工具,对etl过程进行配置,其中涉及到oracle的连接串配置。我从网上找了一个oracle jdbc 连接例子试了一下,能够连通,就用例子里的jdbc url来配置sqoop2了。这个url长得如下:
jdbc:Oracle:thin://:1521:orcl
结果就悲剧了,在监控里提示job被分配到一个节点后,节点连接oracle数据库失败,提示jdbcurl=null。
由于不理解问题原因,我研究了5、6天,才最终决定要从研究为啥jdbcurl变成空了入手。
翻了好多代码,终于知道sqoop2会根据用户设置的jdbc url,重写一遍,用于提供给每个mapper class.如果你用户提供的url不能正确解析,那么传给mapper的就是空。 这个重写的工作,就在 OracleJdbcCommonInitializer.setMapperConnectionDetails里。非常讽刺的是,这个类会先拿用户提供的url连一次数据库,连通了,然后才重写jdbc url。如果这个时候,解析用户的url失败,就会报错。但是,这样的做法不是脱裤子放屁么?你解析不了,完全可以原样传给mapper呀。
看了一下解析jdbc url的函数,发现我的url的确写得有问题,斜杠的位置放错了,应该放在@后面,或者直接删除。而且事后去网上找url例子,发现我这么写的居然找不到了。运气好,还是不好呢?
改好url,节点就不再提示连接数据库的问题了,接下来是类型不匹配的问题。这个还需要继续研究。
org.apache.sqoop.connector.jdbc.oracle.util.OracleDataChunkExtent cannot be cast to org.apache.sqoop.connector.jdbc.oracle.util.OracleDataChunk