• CENTOS上的网络安全工具(十)MapReduce调试环境构建


            紧接上一篇,为了把MapReduce的示例搞明白,需要先把Hadoop上的java编译调试环境给整出来,毕竟,一些执行流程的具体细节被封装在了框架中,仅仅靠公开的源代码静态的解读还是太费事了。有了调试器就要方便得多,理解起来也会省事不少。

            一、构建基于CODE的Java编程调试环境

           1.安装配置Maven插件

            在已经安装好Single Node工作模式的Hadoop节点上,按照之前介绍过的方法,首先构建VSCODE环境。要在CODE上构建Java编程环境,需要安装Extension Pack For Java 插件包,主要安装了核Maven有关的6个插件:

            插件安装完成后记得重启一下VSCODE,否则在使用maven构建框架的时候有一定可能性会遇到莫名其妙退出的情况……

            新建一个testmr文件夹作为工作空间(比如本例在/root/testmr处),在该文件下环境下启动CODE。然后在文件标签页下面,也就是testmr这个空的工作空间下,右键,选择从Maven原型创建新项目:

             选择maven-archetype-quickstart构建一个Java框架

             在弹出的版本选择中,捡版本高的整吧:

             取个自己的组织名字(比如com.pigshome),注意这个名字后面会需要用到:

             给生成的框架起个名字(比如testmapreduce),框架会在testmr工作目录下生成一个名为testmapreduce的目录,并存放生成的App文件及测试文件。

             接下来会弹出一个对跨狂,要求选择项目所在的目录,我们将/root/testmr工作目录就作为项目的目录,所以选好了直接右上角的“selectDestination Folder”点击就行,然后等待CODE转啊转,此时是Maven在执行框架生成任务:

             转到进入交互式模式的时候,Maven会询问一些配置选择,不停的回车啊回车就可以了。

             到这里,框架就算生成完了。Maven会弹出一个对话框询问是新打开一个CODE还是使用当前这个。选open会新开一个,选add to worksapce就使用当前的。

            点开工作空间中testmapreduce的目录,会发现其下src目录下,有main、test两个子目录。我们主要在main下折腾,所以可以点开其下的App.java文件,这是一个java版本的hello world。

             选择调试标签,点击“运行和调试”,会启动当前打开的文件,也就是App.java。环境配置正常的话,应该会不出意外的输出“hello world!”。

            2.认识Pom.xml

            话说Maven作为java的编译环境构建者,其主要的环境配置信息是存储在名为Pom.xml的文件中的,这个在我们打开testmapreduce文件夹的时候就会发现,其内容如下所示:

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0modelVersion>
    5. <groupId>com.pigshomegroupId>
    6. <artifactId>testmapreduceartifactId>
    7. <version>1.0-SNAPSHOTversion>
    8. <name>testmapreducename>
    9. <url>http://www.example.comurl>
    10. <dependencies>
    11. <dependency>
    12. <groupId>junitgroupId>
    13. <artifactId>junitartifactId>
    14. <version>4.11version>
    15. <scope>testscope>
    16. dependency>
    17. dependencies>
    18. <build>
    19. <pluginManagement>
    20. <plugins>
    21. <plugin>
    22. <artifactId>maven-clean-pluginartifactId>
    23. <version>3.1.0version>
    24. plugin>
    25. <plugin>
    26. <artifactId>maven-resources-pluginartifactId>
    27. <version>3.0.2version>
    28. plugin>
    29. <plugin>
    30. <artifactId>maven-compiler-pluginartifactId>
    31. <version>3.8.0version>
    32. plugin>
    33. <plugin>
    34. <artifactId>maven-surefire-pluginartifactId>
    35. <version>2.22.1version>
    36. plugin>
    37. <plugin>
    38. <artifactId>maven-jar-pluginartifactId>
    39. <version>3.0.2version>
    40. plugin>
    41. <plugin>
    42. <artifactId>maven-install-pluginartifactId>
    43. <version>2.5.2version>
    44. plugin>
    45. <plugin>
    46. <artifactId>maven-deploy-pluginartifactId>
    47. <version>2.8.2version>
    48. plugin>
    49. <plugin>
    50. <artifactId>maven-site-pluginartifactId>
    51. <version>3.7.1version>
    52. plugin>
    53. <plugin>
    54. <artifactId>maven-project-info-reports-pluginartifactId>
    55. <version>3.0.0version>
    56. plugin>
    57. plugins>
    58. pluginManagement>
    59. build>
    60. project>

            但在pom.xml文件中,目前除了properties组和dependencies组需要我们更改——实际一般dependencies就够了,其它可以暂时不关心。

            ——本文关于环境搭建的主要内容我们参考了VSCode+Maven+Hadoop开发环境搭建一文。该文中使用属性定义了版本号,故而在发生版本替代时,可以比较简单的更新一下属性的值就行。不过,在我们的试验中,更换版本号的事还是较少发生的,所以就不折腾了。:)

            二、配置MapReduce调试环境

            1.配置Hadoop依赖项仓库

             在Maven的仓库里搜索Hadoop的配置方法,按照Hadoop的要求增加依赖项。建议不要随意添加,那样可能会造成一些莫名奇妙的错误,比如dfs无法启动之类。

     

            再度核实一下版本号,别弄错了

             以hadoop-client为例

             点击3.3.3(因为我的hadoop安装版本是3.3.3)

            从Maven中复制 

    1. <dependency>
    2. <groupId>org.apache.hadoopgroupId>
    3. <artifactId>hadoop-clientartifactId>
    4. <version>3.3.3version>
    5. <scope>providedscope>
    6. dependency>

            将其放入dependencies组中。此时pom.xml如下所示:

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0modelVersion>
    5. <groupId>com.pigshomegroupId>
    6. <artifactId>testmapreduceartifactId>
    7. <version>1.0-SNAPSHOTversion>
    8. <name>testmapreducename>
    9. <url>http://www.example.comurl>
    10. <properties>
    11. <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    12. <maven.compiler.source>1.7maven.compiler.source>
    13. <maven.compiler.target>1.7maven.compiler.target>
    14. properties>
    15. <dependencies>
    16. <dependency>
    17. <groupId>junitgroupId>
    18. <artifactId>junitartifactId>
    19. <version>4.11version>
    20. <scope>testscope>
    21. dependency>
    22. <dependency>
    23. <groupId>org.apache.hadoopgroupId>
    24. <artifactId>hadoop-clientartifactId>
    25. <version>3.3.3version>
    26. <scope>providedscope>
    27. dependency>
    28. <dependency>
    29. <groupId>org.apache.hadoopgroupId>
    30. <artifactId>hadoop-commonartifactId>
    31. <version>3.3.3version>
    32. dependency>
    33. <dependency>
    34. <groupId>org.apache.hadoopgroupId>
    35. <artifactId>hadoop-hdfsartifactId>
    36. <version>3.3.3version>
    37. <scope>testscope>
    38. dependency>
    39. <dependency>
    40. <groupId>org.apache.hadoopgroupId>
    41. <artifactId>hadoop-yarn-apiartifactId>
    42. <version>3.3.3version>
    43. dependency>
    44. dependencies>
    45. <build>
    46. <pluginManagement>
    47. <plugins>
    48. <plugin>
    49. <artifactId>maven-clean-pluginartifactId>
    50. <version>3.1.0version>
    51. plugin>
    52. <plugin>
    53. <artifactId>maven-resources-pluginartifactId>
    54. <version>3.0.2version>
    55. plugin>
    56. <plugin>
    57. <artifactId>maven-compiler-pluginartifactId>
    58. <version>3.8.0version>
    59. plugin>
    60. <plugin>
    61. <artifactId>maven-surefire-pluginartifactId>
    62. <version>2.22.1version>
    63. plugin>
    64. <plugin>
    65. <artifactId>maven-jar-pluginartifactId>
    66. <version>3.0.2version>
    67. plugin>
    68. <plugin>
    69. <artifactId>maven-install-pluginartifactId>
    70. <version>2.5.2version>
    71. plugin>
    72. <plugin>
    73. <artifactId>maven-deploy-pluginartifactId>
    74. <version>2.8.2version>
    75. plugin>
    76. <plugin>
    77. <artifactId>maven-site-pluginartifactId>
    78. <version>3.7.1version>
    79. plugin>
    80. <plugin>
    81. <artifactId>maven-project-info-reports-pluginartifactId>
    82. <version>3.0.0version>
    83. plugin>
    84. plugins>
    85. pluginManagement>
    86. build>
    87. project>

            看看是否设置成功,在App.java中加入hadoop的支持:

    1. package com.pigshome;
    2. import java.util.Random;
    3. import org.apache.hadoop.conf.Configuration;
    4. import org.apache.hadoop.conf.Configured;
    5. import org.apache.hadoop.fs.FileSystem;
    6. import org.apache.hadoop.fs.Path;
    7. import org.apache.hadoop.io.LongWritable;
    8. import org.apache.hadoop.io.Text;
    9. import org.apache.hadoop.mapreduce.*;
    10. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    11. import org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat;
    12. import org.apache.hadoop.mapreduce.lib.map.InverseMapper;
    13. import org.apache.hadoop.mapreduce.lib.map.RegexMapper;
    14. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    15. import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
    16. import org.apache.hadoop.mapreduce.lib.reduce.LongSumReducer;
    17. import org.apache.hadoop.util.Tool;
    18. import org.apache.hadoop.util.ToolRunner;
    19. /**
    20. * Hello world!
    21. *
    22. */
    23. public class App
    24. {
    25. public static void main( String[] args )
    26. {
    27. System.out.println( "Hello World!" );
    28. }
    29. }

            仍然能够成功运行,证明导入是成功的,虽然黄线部分会警告说导入的包都没用过

            2. 导入MapReduce项目

             如上篇最后所述,Hadoop示例教程中使用了Grep,一个对输入文件中每行字符进行正则匹配并统计命中的MapReduce算法。Grep的源文件在hadoop/share/hadoop/mapreuce/sources/目录下,名字为hadoop-mapreduce-examples-3.3.3-sources.jar

            (1)拷贝源文件

            使用jar命令将其解压出来,找到Grep.java文件。

    1. [root@pig1 testmr]# mkdir examples
    2. [root@pig1 testmr]# cd examples
    3. [root@pig1 examples]# jar -xvf /root/hadoop/share/hadoop/mapreduce/sources/hadoop-mapreduce-examples-3.3.3-sources.jar
    4. 已创建: META-INF/
    5. 已解压: META-INF/MANIFEST.MF
    6. 已解压: META-INF/LICENSE.txt
    7. 已解压: META-INF/NOTICE.txt
    8. 已创建: org/
    9. 已创建: org/apache/
    10. 已创建: org/apache/hadoop/
    11. 已创建: org/apache/hadoop/examples/
    12. 已创建: org/apache/hadoop/examples/dancing/
    13. 已创建: org/apache/hadoop/examples/terasort/
    14. 已创建: org/apache/hadoop/examples/terasort/2009-write-up/
    15. 已创建: org/apache/hadoop/examples/pi/
    16. 已创建: org/apache/hadoop/examples/pi/math/
    17. 已解压: org/apache/hadoop/examples/WordCount.java
    18. 已解压: org/apache/hadoop/examples/WordMedian.java
    19. 已解压: org/apache/hadoop/examples/BaileyBorweinPlouffe.java
    20. 已解压: org/apache/hadoop/examples/MultiFileWordCount.java
    21. 已解压: org/apache/hadoop/examples/dancing/OneSidedPentomino.java
    22. 已解压: org/apache/hadoop/examples/dancing/DancingLinks.java
    23. 已解压: org/apache/hadoop/examples/dancing/DistributedPentomino.java
    24. 已解压: org/apache/hadoop/examples/dancing/Pentomino.java
    25. 已解压: org/apache/hadoop/examples/dancing/Sudoku.java
    26. 已解压: org/apache/hadoop/examples/dancing/package.html
    27. 已解压: org/apache/hadoop/examples/dancing/puzzle1.dta
    28. 已解压: org/apache/hadoop/examples/Join.java
    29. 已解压: org/apache/hadoop/examples/AggregateWordCount.java
    30. 已解压: org/apache/hadoop/examples/WordMean.java
    31. 已解压: org/apache/hadoop/examples/ExampleDriver.java
    32. 已解压: org/apache/hadoop/examples/terasort/TeraSortConfigKeys.java
    33. 已解压: org/apache/hadoop/examples/terasort/TeraScheduler.java
    34. 已解压: org/apache/hadoop/examples/terasort/GenSort.java
    35. 已解压: org/apache/hadoop/examples/terasort/TeraGen.java
    36. 已解压: org/apache/hadoop/examples/terasort/Random16.java
    37. 已解压: org/apache/hadoop/examples/terasort/TeraValidate.java
    38. 已解压: org/apache/hadoop/examples/terasort/TeraOutputFormat.java
    39. 已解压: org/apache/hadoop/examples/terasort/TeraSort.java
    40. 已解压: org/apache/hadoop/examples/terasort/TeraInputFormat.java
    41. 已解压: org/apache/hadoop/examples/terasort/2009-write-up/1PBTaskTime.png
    42. 已解压: org/apache/hadoop/examples/terasort/2009-write-up/100TBTaskTime.png
    43. 已解压: org/apache/hadoop/examples/terasort/2009-write-up/500GBTaskTime.png
    44. 已解压: org/apache/hadoop/examples/terasort/2009-write-up/Yahoo2009.tex
    45. 已解压: org/apache/hadoop/examples/terasort/2009-write-up/tera.bib
    46. 已解压: org/apache/hadoop/examples/terasort/2009-write-up/1TBTaskTime.png
    47. 已解压: org/apache/hadoop/examples/terasort/Unsigned16.java
    48. 已解压: org/apache/hadoop/examples/terasort/TeraChecksum.java
    49. 已解压: org/apache/hadoop/examples/terasort/package.html
    50. 已解压: org/apache/hadoop/examples/SecondarySort.java
    51. 已解压: org/apache/hadoop/examples/DBCountPageView.java
    52. 已解压: org/apache/hadoop/examples/pi/Parser.java
    53. 已解压: org/apache/hadoop/examples/pi/TaskResult.java
    54. 已解压: org/apache/hadoop/examples/pi/DistSum.java
    55. 已解压: org/apache/hadoop/examples/pi/DistBbp.java
    56. 已解压: org/apache/hadoop/examples/pi/SummationWritable.java
    57. 已解压: org/apache/hadoop/examples/pi/Container.java
    58. 已解压: org/apache/hadoop/examples/pi/Combinable.java
    59. 已解压: org/apache/hadoop/examples/pi/math/Modular.java
    60. 已解压: org/apache/hadoop/examples/pi/math/Summation.java
    61. 已解压: org/apache/hadoop/examples/pi/math/LongLong.java
    62. 已解压: org/apache/hadoop/examples/pi/math/Montgomery.java
    63. 已解压: org/apache/hadoop/examples/pi/math/Bellard.java
    64. 已解压: org/apache/hadoop/examples/pi/math/package.html
    65. 已解压: org/apache/hadoop/examples/pi/math/ArithmeticProgression.java
    66. 已解压: org/apache/hadoop/examples/pi/Util.java
    67. 已解压: org/apache/hadoop/examples/pi/package.html
    68. 已解压: org/apache/hadoop/examples/Grep.java
    69. 已解压: org/apache/hadoop/examples/AggregateWordHistogram.java
    70. 已解压: org/apache/hadoop/examples/Sort.java
    71. 已解压: org/apache/hadoop/examples/WordStandardDeviation.java
    72. 已解压: org/apache/hadoop/examples/QuasiMonteCarlo.java
    73. 已解压: org/apache/hadoop/examples/RandomWriter.java
    74. 已解压: org/apache/hadoop/examples/RandomTextWriter.java
    75. 已解压: org/apache/hadoop/examples/package.html
    76. [root@pig1 examples]# ls
    77. META-INF org

             将其拷贝到CODE项目中的源码目录下。根据JAVA的默认项目框架,源代码应该在工作目录testmapreduce下的src/main/java/com/pigshome下,当然这里com/pigshome是我的项目标识。

    1. [root@pig1 examples]# cp org/apache/hadoop/examples/Grep.java ../testmapreduce/src/main/java/com/pigshome
    2. [root@pig1 examples]# cd ../testmapreduce/src/main/java/com/pigshome
    3. [root@pig1 pigshome]# ls
    4. App.java Grep.java
    5. [root@pig1 pigshome]#

            所以,需要在Grep中,将下图中红线指出包名改成我们自己的包名,如com.pigshome,和App.java中的一样。

             (2)配置输入参数

            如同示例一样,需要准备一个输入目录,并将hadoop/etc/hadoop/下的几个xml文件当小白鼠。至于输入目录,其实随便找个地方就行,我们是就在测试程序的同目录下建了一个input目录

    1. [root@pig1 testmr]# mkdir input
    2. [root@pig1 testmr]# cp /root/hadoop/etc/hadoop/*.xml input
    3. [root@pig1 testmr]# ls
    4. examples input testmapreduce
    5. [root@pig1 testmr]# ls input
    6. capacity-scheduler.xml hdfs-rbf-site.xml kms-acls.xml yarn-site.xml
    7. core-site.xml hdfs-site.xml kms-site.xml
    8. hadoop-policy.xml httpfs-site.xml mapred-site.xml
    9. [root@pig1 testmr]#

            准备好以后,需要配置项目的launch.json文件,用来指定调试启动时的命令行参数。

            在CODE的调试标签页中选择自定义lauch.json文件, 生成launch.json文件如下所示:

            因为我们的main/java/com/pigshome目录下有App.java和Grep.java两个文件,所以生成的launch.json文件中包含了当前文件、App、Grep共3个启动选择项。所以,根据这个文件夹底下的文件不同,可能launch.json文件的项数会有不同。我们需要更改的是Grep这个启动项的参数。

            参考上一篇中我们测试时候的参数,指定我们准备的输入文件夹的位置,在Lauch Grep的组中增加"args"选项,填入输入参数。

    1. {
    2. // 使用 IntelliSense 了解相关属性。
    3. // 悬停以查看现有属性的描述。
    4. // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    5. "version": "0.2.0",
    6. "configurations": [
    7. {
    8. "type": "java",
    9. "name": "Launch Current File",
    10. "request": "launch",
    11. "mainClass": "${file}"
    12. },
    13. {
    14. "type": "java",
    15. "name": "Launch App",
    16. "request": "launch",
    17. "mainClass": "com.pigshome.App",
    18. "projectName": "testmapreduce"
    19. },
    20. {
    21. "type": "java",
    22. "name": "Launch Grep",
    23. "request": "launch",
    24. "mainClass": "com.pigshome.Grep",
    25. "projectName": "testmapreduce",
    26. "args": "/root/testmr/input /root/testmr/output 'dfs[a-z.]+'"
    27. }
    28. ]
    29. }

             因为有3个启动项,所以在调试菜单中需要选择一下:

             选择Launch Grep,然后启动,执行完毕后,可以直接在终端中输入cat output/* 参看结果。

            当然,这是因为我们的工作目录就下testmr下,而参数指明了output生成在testmr下。这里需要提一下,前面我们并没有手工生成output,因为hadoop并不希望我们代劳。如果这个目录已经存在,Grep程序会报错……

            3.准备源代码支持

            一般来说,在Maven的支持下,作为开源项目的Hadoop,其内部实现的源码应该是可以在我们搭建的调试环境中,以右键“转到定义”或者“转到引用”等直接查看的。但不幸的是,在我搭建的3.3.4环境下,尚能看到RegexMapper.java源文件,在3.3.3环境下,就看不到了,Maven会给出无法找到源文件的错误,所以其自己根据调用关系逆向分析,生成一个空的RegexMapper类。

            更崩溃的是,我搭的两个一摸一样的3.3.4的环境,虽然都能看见RegexMapper类的源码,但一个有Configuration的源码,另一个死活都没有。

            一开始我以为是我的maven设置除了问题,一通找,包括在settings.json文件中增加maven.downloadsources选项也没有用。还好后来意识到一件事,顺着这个思路不仅搞定了这个问题,捎带脚着也解决了离线环境下的调试环境构建问题:

            首先捋清楚的是,maven是一个jar依赖包构建工具(这句话很普通,含义很关键)。一个java程序会用到很多jar包,并且这些jar包之间还会有复杂的依赖关系,手工添加会相当麻烦,所以要maven来帮忙。——这个听起来是不是十分的耳熟,这个怎么这么像yum呢……

            其次,我们在pom.xml中填写的那些东西,实际和我们在yum.repo.d目录下构建repo文件时写的没什么两样。那些内容,只不过是知道maven到mvnrepository网站上去下载对应的jar包罢了。这个也和yum异曲同工。

            所以,源码问题大概率是库本身就有问题(出于更重莫名原因的没有下载下来),没有下载到我们需要的依赖项和源文件。碰到这种库问题的时候,我们有这么2种方法去解决: 一是更换源,不过有可能新的源也不见得有;二是构建本地源,就像yum的createrepo一样。但是我也没啥兴趣去研究maven的命令,不知道如何下载并构建本地源,但是有一点是比较容易的——就是等maven下载好了,我们拷贝并且改造一下:

            最后,我们只需要知道,maven下载的库是存放在~/.m2文件夹下的,这是个隐藏文件夹,所以ls需要-a一下,使用窗口要记得打开“显示隐藏文件”。和hadoop相关的在repository/org/apache/hadoop目录下        

             对于Configuration的源文件,在hadoop-common/3.3.4下面,如果这个文件夹下只有hadoop-common-3.3.4.jar而没有hadoop-common-3.3.4-sources.jar,那么是不可能看见源代码的。解决方法也很简单,找到hadoop-common-3.3.4-sources.jar并且拷贝过来就行。这个文件,要么在能够看见源码的环境的对应地方,要么可以直接从hadoop网站上去下载的hadoop-3.3.4-src.tar.gz里面找到。

            到这里,再打一个节吧,贴的图太多了,每次往上翻都很难受,再开一贴。

  • 相关阅读:
    关于maven读取settings.xml文件的优先级问题
    HTTP —— HTTP 响应详解, 构造 HTTP 请求
    弘辽科技:超级推荐爆款拉新怎么设置?爆款拉新怎么玩?
    ABAP 屏幕开发-仿采购订单
    python列表和元组的作业
    ipv6一致性-NDP测试
    我的react面试题笔记整理(附答案)
    混合牛奶 | 贪心算法 (USACO练习题)
    面向对象14:抽象类
    初始网络原理
  • 原文地址:https://blog.csdn.net/lhyzws/article/details/126311841