sqoop源码解析-----从mysql到hive为例

    上班这么久了,大部分时间都是在大数据平台组件的基础上做一些小的开发,既然是在别人的东西上修改,除了百度或者谷歌搜索前人的讲解,自己阅读源码一定是必不可少的。但是源码里代码量那么大,往往一时间多很难找到整个程序的入口,这时候 往往容易让人感觉到烦躁而不想动,下次碰到这样的情况,应该怎么入手呢?刚好今天在研究根据具体业务需求修改sqoop源码,实现从mysql到hive的单分区key,多分区value的导入的功能。具体来说就是根据mysql的日期字段,在hive中根据不同日期生成不同的分区表。

    说了这么多,那就赶紧开始吧,首先我们在github上找到sqoop的源码,或者直接从官网下载源码离线包。

sqoop源码解析-----从mysql到hive为例_第1张图片

    这就是sqoop源码的整个目录结构了,我们用命令行调用sqoop的时候,会调用bin目录下的sqoop文件,这时候看一下sqoop文件的内容,看到文件的最后一行有调用具体类的名称了:

sqoop源码解析-----从mysql到hive为例_第2张图片

    好的,找到这里,我们就可以前往src/java/org/apache/sqoop找到sqoop.java文件了,打开它,直接拉到代码最后,果然,有我们最熟悉的main函数,找到main函数就可以顺藤摸瓜了:

sqoop源码解析-----从mysql到hive为例_第3张图片

    再往上找到runTool方法,可以看到这个方法又调用了它的另一个重载方法,继续找


sqoop源码解析-----从mysql到hive为例_第4张图片

    看到这里,可以看到这个方法将我们命令行的参数,通过OptionsFileUtil这个类解析之后,解析出第一个参数,这里被官方定义为toolName,对应我们的命令行,应该就是sqoop后面的第一个参数,例如import。好的,找到这个toolName之后,它就调用了一个runSqoop方法,这就正式的将我们命令后面的一大串参数传到核心方法里了。

    继续找runSqoop方法,发现它是直接调用ToolRunner.run这个方法,ToolRunner在哪儿呢?看最上面的import那一堆东西,原来是调用的hadoop的方法,我们在github上直接找这个,它在hadoop/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/这个里面,打开它,找到run方法

sqoop源码解析-----从mysql到hive为例_第5张图片sqoop源码解析-----从mysql到hive为例_第6张图片

    哇,又是层层调用,不管了,继续刨根问底:

sqoop源码解析-----从mysql到hive为例_第7张图片

    奇怪了,这里怎么又找回去了呢,汗,赶紧回到sqoop.java里去找,果然,里面还有一个run方法,结果它又调用的是另一个run方法。调用个没完了,别着急,看看这个tool哪儿来的。ctrl+F找tool,哈哈,原来这个tool是sqoop tool定义的tool,好说了,打开SqoopTool.java就行了(src/java/org/apache/sqoop/tool/SqoopTool.java)。

sqoop源码解析-----从mysql到hive为例_第8张图片

    打开后我们看到,这不就是注册tool的代码嘛,这个import是我们从mysql到hive里导数据要用的,可以,我们直接去找ImportTool.java好了(src/java/org/apache/sqoop/tool/)。

sqoop源码解析-----从mysql到hive为例_第9张图片

    打开ImportTool.java,可以看到这个类继承自BaseSqoopTool,既然这样,那就顺便看看这个类呗,打开它,

sqoop源码解析-----从mysql到hive为例_第10张图片

    这不就是我们的命令嘛,继续查,我们从mysql导入hive是需要用到hive-import的,查查这个关键字HIVE_IMPORT_ARG用在哪些地方了

sqoop源码解析-----从mysql到hive为例_第11张图片

    可以看到,代码里进行了判断,如果我们的命令行里有这个参数,代码里会调用一个SqoopOptions对象的setHiveImport方法,并将参数设置为true。

sqoop源码解析-----从mysql到hive为例_第12张图片

    进入src/java/org/apache/sqoop/SqoopOptions.java类,看到

    这时候,再回到ImportTools类,找到它的run方法,这个run方法继承自SqoopTools,是各个工具类的执行体。

sqoop源码解析-----从mysql到hive为例_第13张图片sqoop源码解析-----从mysql到hive为例_第14张图片 

    可以看到,因为前面的SqoopOptions对象将doHiveImport设置为true了,所以这里就直接调用了importTable方法,往上看到这个方法可以发现这里codeGenerator先根据tablename生成数据库记录对应的实体类,而manager负责将数据从源库中查询出来。最后判定如果含有hive-import,则调用HiveImport.java里的ImportTable方法。找到这个方法(/src/java/org/apache/sqoop/hive/HiveImport.java)。

sqoop源码解析-----从mysql到hive为例_第15张图片

    可以看到HiveImport.java更简单,首先,它调用和他同目录的TableDefWriter,获取DDL和DML语句以及warehouseDir 的地址,然后生成一个临时的脚本文件来存放这些DDL和DML。接着调用自己的excuteScript方法执行临时脚本,最后删除他们。

sqoop源码解析-----从mysql到hive为例_第16张图片

sqoop源码解析-----从mysql到hive为例_第17张图片

sqoop源码解析-----从mysql到hive为例_第18张图片

    终于到执行的步骤啦,我们找到executeScript方法,好嘛, 这家伙直接采用了反射的方法,直接调用Hive的主类,自己加载去了,真会偷懒。后面就是Hive的源码啦,这里就不解析了。哼,如果这么算来,sqoop算对hadoop组件的二次开发,那我们这岂不是就是三次开发了。

, sqoop源码解析-----从mysql到hive为例_第19张图片

 

你可能感兴趣的:(二次开发)