Docker部署hadoop集群

  • 下载资源
  • 构建镜像
  • 启动容器
  • 搭建集群
    • 配置ssh免密
    • 节点职责安排
    • 修改配置文件
    • 启动集群
  • 测试
    • 上传
    • 下载
    • 执行wordcount程序
  • 补充
    • 配置历史服务器
    • 日志聚集
    • 单节点启动
    • Java客户端使用
      • HDFS
      • MapReduce

在这里插入图片描述

下载资源

java华为镜像下载地址:Index of java-local/jdk (huaweicloud.com)

hadoop历史版本下载:Index of /dist/hadoop/common (apache.org)

构建镜像

编写Dockerfile文件:

FROM centos:centos7# 配置resove.conf解决软件包获取不到的问题
RUN curl -O http://mirrors.aliyun.com/repo/Centos-7.repo
RUN mv -f Centos-7.repo /etc/yum.repos.d/CentOS-Base.repo
RUN yum makecache# 安装openssh-server和sudo软件包,并且将sshd的UsePAM参数设置成no  
RUN yum install -y openssh-server sudo
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
#安装openssh-clients
RUN yum install -y openssh-clients# 添加测试用户root,密码3238,并且将此用户添加到sudoers里  
RUN echo "root:3238" | chpasswd
RUN echo "root   ALL=(ALL)       ALL" >> /etc/sudoers
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
# 启动sshd服务并且暴露22端口  
RUN mkdir /var/run/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]ADD jdk-8u202-linux-x64.tar.gz /usr/local
RUN mv /usr/local/jdk1.8.0_202 /usr/local/jdk1.8
ENV JAVA_HOME /usr/local/jdk1.8
ENV PATH $JAVA_HOME/bin:$PATHADD hadoop-3.1.3.tar.gz /usr/local
RUN mv /usr/local/hadoop-3.1.3 /usr/local/hadoop
ENV HADOOP_HOME /usr/local/hadoop
ENV PATH $HADOOP_HOME/bin:$PATH

构建镜像:

docker build -t hadoop .

注:

  • 低版本docker会出现使用mv命令时报错:can’t remove : Directory not empty,可以先用COPY命令而不用ADD命令将压缩包复制到容器内,然后自己后面到容器内去解压。
  • 该Dockerfile文件构建出来的镜像体积有些臃肿,可以拉取我优化过体积的镜像,也可以参考文章 减小docker镜像体积的方法-CSDN博客 修改Dockerfile文件来优化体积。

如果觉得这些操作太麻烦了,想要更省事点,我还提供了已经构建好的两个不同版本的镜像。(你就说我够不够贴心吧)

  • 由Dockerfile文件构建出来的初始版本:docker pull biluoer/hadoop:3.1.3-base
  • 已经把文章里所有内容都配置好的完全版:
    docker pull biluoer/hadoop:3.1.3
    # 给拉取过来的镜像创建个新的tag
    docker tag biluoer/hadoop:3.1.3 hadoop
    # 然后删除旧tag
    docker rmi biluoer/hadoop:3.1.3
    # 运行三台容器后,进入hadoop2,就可以一键运行了
    docker exec -it hadoop2 bash
    # 一键运行,回车走你
    my-hadoop start
    
    注:若拉取失败,可参考文章 docker的安装和常用命令-CSDN博客 的配置镜像源部分。

启动容器

# 创建桥接网络,bridge是默认驱动,可以不加
docker network create [--driver bridge] hadoop-net
#创建桥接网络,并指定子网配置,范围:192.168.1.1-192.168.1.254
docker network create --subnet=192.168.1.0/24 hadoop-net# 启动三台(一主二从)并指定网络,文件下载端口9864、DataNode客户端访问端口9866
# hadoop2,开放nn-web端口9870、历史服务器web端口19888,NameNode客户端连接端口8020
docker run -itd --hostname hadoop2 --name hadoop2 --net hadoop-net --ip 192.168.1.2 -p 9870:9870 -p 9864:9864 -p 19888:19888 -p 8020:8020 -p 9866:9866 hadoop
# hadoop3,开放yarn-web端口8088
docker run -itd --hostname hadoop3 --name hadoop3 --net hadoop-net --ip 192.168.1.3 -p 8088:8088 hadoop
# hadoop4,开放2nn-web端口9868(根据hdfs-site.xml配置,非必须)
docker run -itd --hostname hadoop4 --name hadoop4 --net hadoop-net --ip 192.168.1.4 -p 9868:9868 hadoop

注:如果某些功能用不到,就不需要开放相关的端口。

搭建集群

配置ssh免密

首先对主hadoop2配置:

可以先用ping命令测试下连通性:ping hadoop2

如果没有ping通,在/etc/hosts文件里加上:

192.168.1.2     hadoop2
192.168.1.3     hadoop3
192.168.1.4     hadoop4
docker exec -it hadoop0 bash
#生成秘钥对
ssh-keygen
#剩下的一路回车即可
#分发公钥到其他主机,让hadoop2可以免密登录hadoop2、3、4
ssh-copy-id hadoop2
ssh-copy-id hadoop3
ssh-copy-id hadoop4
#同样的方法,让hadoop3、Hadoop4可以免密登录另外2台主机,其中hadoop4可配可不配,但hadoop2和hadoop3一定要配置

节点职责安排

各节点的职责可通过配置文件自定义;NN、2NN、RM在不同服务器上可以减少资源争用、减小单点故障风险,方便扩展和维护。

hadoop2hadoop3hadoop4
HDFSNameNode、DataNodeDataNodeSecondaryNameNode、DataNode
YARNNodeManagerResourceManager、NodeManagerNodeManager

修改配置文件

进入/usr/local/hadoop/etc/hadoop目录,涉及的配置文件有:hadoop-env.sh、core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml、works(2.x叫slaves)。

默认配置文件位置:

默认配置文件所在位置
core-default.xmlhadoop-common-3.1.3.jar/core-defaultxml
hdfs-default.xmlhadoop-hdfs-3.1.3.jar/hdfs-defaultxml
yarn-default.xmlhadoop-yarn-common-3.1.3.jar/yarn-defaultxml
mapred-default.xmlhadoop-mapreduce-client-core-3.1.3.jar/mapred-defaultxml

注:以下操作都是是hadoop2上,配置文件中的其他配置都是可加可不加的,并且除其他配置外的配置大多都有默认值,不是必须要加的,默认值可以通过查看默认配置文件来获取。

  • hadoop-env.sh(末尾加上,必须)
export JAVA_HOME=/usr/local/jdk1.8
  • core-site.xml
<configuration><!--指定NameNode的地址--><property><name>fs.defaultFS</name><value>hdfs://hadoop2:8020</value></property><!--指定hadoop数据的存储目录--><property><name>hadoop.tmp.dir</name><value>/usr/local/hadoop/data</value></property><!--配置HDFS网页登录使用的静态用户为root,用什么用户启动的集群,就配置什么用户,不然网页上进行删除文件等操作会没有权限--><property><name>hadoop.http.staticuser.user</name><value>root</value></property><!--其他配置--><!--配置垃圾桶(Trash)的清理时间间隔(以分钟为单位),默认值0,表示禁用垃圾桶功能(垃圾桶是一个用于存储被删除文件或目录的临时区域)--><property><name>fs.trash.interval</name><value>1440</value></property>
</configuration>
  • hdfs-site.xml
<configuration><!--nn-web端访问地址--><property><name>dfs.namenode.http-address</name><value>hadoop2:9870</value></property><!--2nn-web端访问地址--><property><name>dfs.namenode.secondary.http-address</name><value>hadoop4:9868</value></property><!--其他配置--><!--设置HDFS中文件的副本数,默认值3--><property><name>dfs.replication</name><value>1</value></property><!--是否启用文件/目录的权限检查,false任何用户可读写,默认值true--><property><name>dfs.permissions</name><value>false</value></property>
</configuration>
  • yarn-site.xml
<configuration><!--指定YARN-NodeManager需要运行的辅助服务--><property><name>yarn.nodemanager.aux-services</name><value>mapreduce_shuffle</value></property><!--指定ResourceManager的地址--><property><name>yarn.resourcemanager.hostname</name><value>hadoop3</value></property><!-- 环境变量的继承,3.1的bug,缺少HADOOP_MAPRED_HOME,3.2后就不需要此配置了--><property><name>yarn.nodemanager.env-whitelist</name>		<value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME,PATH,LANG,TZ</value></property><!--其他配置--><!--启用YARN的日志聚合功能,把各个节点的日志收集到一起存放--><property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property><!--设置日志聚集服务器地址--><property> <name>yarn.log.server.url</name> <value>http://hadoop2:19888/jobhistory/logs</value></property><!-- 设置日志保留时间为7天--><property><name>yarn.log-aggregation.retain-seconds</name><value>604800</value></property>
</configuration>
  • mapred-site.xml
<configuration><!-- 指定MapReduce程序运行在Yarn上 --><property><name>mapreduce.framework.name</name><value>yarn</value></property><!--其他配置--><!--历史服务器端地址--><property><name>mapreduce.jobhistory.address</name><value>hadoop102:10020</value></property><!--历史服务器web端地址--><property><name>mapreduce.jobhistory.webapp.address</name><value>hadoop102:19888</value></property>
</configuration>

配置完成上述内容后,可以使用rsync进行配置文件的从hadoop2分发到其余容器。

rsync是一个同步工具,只会同步发生了变更的文件。

为了实现一次性分发,可以写一个脚本实现:xsync

#!/bin/bash
#1. 判断参数个数
if [ $# -lt 1 ]
thenecho Not Enough Arguement!exit;
fi
#2. 遍历集群所有机器
for host in hadoop2 hadoop3 hadoop4
doecho ==================== $host ====================#3. 遍历所有目录,挨个发送for file in $@do#4. 判断文件是否存在if [ -e $file ]then#5. 获取父目录pdir=$(cd -P $(dirname $file); pwd)#6. 获取当前文件的名称fname=$(basename $file)ssh $host "mkdir -p $pdir"rsync -av $pdir/$fname $host:$pdirelseecho $file does not exists!fidone
done

然后授权其执行权限和复制到/bin中,以便全局使用

chmod +x xsync
cp xsync /bin/
#安装(hadoop2、3、4都需要)
yum -y install rsync
#配置xsync脚本,并复制到/bin目录下#分发
xsync /usr/local/hadoop/etc/hadoop/
#也可以使用相对路径,需要当前路径为/usr/local/hadoop/etc/hadoop
xsync ./
  • 配置works文件:
echo "hadoop2" > workers
echo "hadoop3" >> workers
echo "hadoop4" >> workers
xsync workers

启动集群

注意:格式 化 NameNode,会产生新的集群 id,导致 NameNode 和 DataNode 的集群 id 不一致,集群找不到已往数据。如果集群在运行过程中报错,需要重新格式化 NameNode 的话,一定要先停止namenode 和 datanode 进程,并且要删除所有机器的 data 和 logs 目录,然后再进行格式化。

  1. 启动 HDFS(hadoop2上)
#第一次启动,需要格式化NameNode,成功后会在hadoop根目录下生成data目录
hdfs namenode -format
#启动hdfs
/usr/local/hadoop/sbin/start-dfs.sh
#如果报错找不到变量,在sbin/start-dfs.sh、stop-dfs.sh顶部加上以下内容:缺啥加啥
HDFS_NAMENODE_USER=root
HDFS_DATANODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
#启动成功后,使用jps命令可以在hadoop2上看到DataNode和NameNode,hadoop3上看到DataNode,hadoop4上看到DataNode和SecondaryNameNode
jps
#nn-web页面:192.168.30.3:9870,2nn-web页面:192.168.30.3:9868
#停止hdfs
/usr/local/hadoop/sbin/stop-dfs.sh
  1. 启动yarn(在配置了 ResourceManager 的节点上启动才行)
#以下所有操作都在:hadoop3上
/usr/local/hadoop/sbin/start-yarn.sh
#如果报错找不到变量,在sbin/start-yarn.sh、stop-yarn.sh顶部加上以下内容:缺啥加啥
YARN_RESOURCEMANAGER_USER=root
YARN_NODEMANAGER_USER=root
#如果报错Permission denied,则hadoop3也要配置对其他主机的免密登录
#启动成功后,使用jps命令可以看到在hadoop2上多了NodeManager,hadoop3上多了ResourceManager和NodeManager,hadoop4上多了NodeManager
#yarn页面:192.168.30.3:8088
#停止yarn
/usr/local/hadoop/sbin/stop-yarn.s
  1. 便捷启动和便捷检查:在/root/bin/下编写集群启听脚本和jps-all脚本

    最后授权和分发:

    chmod +x my-hadoop
    chmod +x jps-all
    #临时将/root/bin目录添加到PATH中
    export PATH=$PATH:/root/bin
    xsync /root/bin/
    # 使用my-hadoop和jps-all
    my-hadoop start/stop
    jps-all
    
    • my-hadoop.
    #!/bin/bash
    if [ $# -lt 1 ]
    thenecho "No Args Input..."exit ;
    fi
    #也可以直接使用 HADOOP_HOME,而不需要新定义一个变量
    hadoop_home=/usr/local/hadoop
    case $1 in
    "start")echo "==================== 启动 hadoop 集群 ==================="echo " --------------- 启动 hdfs ---------------"ssh hadoop2 "$hadoop_home/sbin/start-dfs.sh"echo "---------------- 启动 yarn ---------------"ssh hadoop3 "$hadoop_home/sbin/start-yarn.sh"echo "---------------- 启动 historyserver ---------------"ssh hadoop2 "$hadoop_home/bin/mapred --daemon start historyserver"
    ;;
    "stop")echo "==================== 关闭 hadoop 集群 ==================="echo "---------------- 关闭 historyserver ---------------"ssh hadoop2 "$hadoop_home/bin/mapred --daemon stop historyserver"echo "---------------- 关闭 yarn ---------------"ssh hadoop3 "$hadoop_home/sbin/stop-yarn.sh"echo "---------------- 关闭 hdfs ---------------"ssh hadoop2 "$hadoop_home/sbin/stop-dfs.sh"
    ;;
    *)echo "Input Args Error..."
    ;;
    esac
    
    • jps-all
    #!/bin/bash
    for host in hadoop2 hadoop3 hadoop4
    doecho =============== $host ===============ssh $host "/usr/local/jdk1.8/bin/jps"
    done
    

测试

上传

文件保存位置为:/usr/local/hadoop/data/dfs/data/current/

#创建文件夹(fs-FileSystem),是否成功可以访问9870,去查看菜单Utilities下的“Browse the file system”页面
hadoop fs -mkdir /input
#上传文件,上传成功后可以到页面上去预览和下载
hadoop fs -put /bin/xsync /input

下载

#方式1:在浏览器页面下载
#方式2:通过get命令下载(到当前路径)
hadoop fs -get /input/xsync

发现浏览器方式预览和下载文件会失败,是因为没有配置hostname和ip的对应关系,需要配置。(注意容器一定开放了端口:9864)

打开C:\Windows\System32\drivers\etc\hosts,加上以下内容:

192.168.30.3 hadoop2
192.168.30.3 hadoop3
192.168.30.3 hadoop4
#为了方便访问,还可以加上这个
192.168.30.3 hadoop

执行wordcount程序

注意:集群模式下,输入路径和输出路径需要都是HDFS的路径。

#统计input目录下所有文件的单词种类和对应的数量
hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input /output
#访问ip:8088可以看到程序的执行情况,程序执行完成后访问ip:9870的文件系统,执行结果在output目录下的文件中

补充

配置历史服务器

在yarn的web网页上,点击具体程序的history,发现页面打开失败。为了查看程序的历史执行情况,就需要配置历史服务器。

  1. 在mapred-site.xml中加上如下的配置:
<!--历史服务器端地址-->
<property><name>mapreduce.jobhistory.address</name><value>hadoop102:10020</value>
</property>
<!--历史服务器web端地址-->
<property><name>mapreduce.jobhistory.webapp.address</name><value>hadoop102:19888</value>
</property>
  1. 分发配置和启动,启动后用jsp检查启动是否成功
xsync etc/hadoop/ 
/usr/local/hadoop/bin/mapred --daemon start historyserver
jps
#停止历史服务器进程
/usr/local/hadoop/bin/mapred --daemon stop historyserver

日志聚集

日志聚集概念:应用运行完成以后,将程序运行日志信息上传到 HDFS 系统上。这样可以方便的查看到程序运行详情,方便开发调试。

注意:开启日志聚集功能,需要重新启动 NodeManager 、ResourceManager 和 HistoryServer。

  1. 修改yarn-site.xml,加上以下配置:
<!-- 开启日志聚集功能 -->
<property><name>yarn.log-aggregation-enable</name><value>true</value>
</property>
<!-- 设置日志聚集服务器地址 -->
<property> <name>yarn.log.server.url</name> <value>http://hadoop2:19888/jobhistory/logs</value>
</property>
<!-- 设置日志保留时间为 7 天 -->
<property><name>yarn.log-aggregation.retain-seconds</name><value>604800</value>
</property>
  1. 分发配置和启动
xsync $HADOOP_HOME/ect/hadoop/
# hadoop2上输入以下命令停止HistoryServer
$HADOOP_HOME/bin/mapred --daemon stop historyserver
# hadoop3上输入以下命令停止NM、RM,然后启动
$HADOOP_HOME/sbin/stop-yarn.sh
$HADOOP_HOME/sbin/start-yarn.sh
# hadoop2上
$HADOOP_HOME/bin/mapred --daemon start historyserver

单节点启动

#分别启动/停止 HDFS 组件
hdfs --daemon start/stop namenode/datanode/secondarynamenode
# 启动/停止 YARN
yarn --daemon start/stop resourcemanager/nodemanager

Java客户端使用

HDFS

使用步骤如下:

  1. 需要先下载hadoop3.1.0到本地,并用 cdarlint/winutils: winutils.exe hadoop.dll and hdfs.dll binaries for hadoop windows (github.com) 这里面对应版本的bin目录替换掉原来的bin目录
  2. 然后创建环境变量HADOOP_HOME,值为之前下载并解压好的hadoop3.1.0的目录,并在环境变量path里加上%HADOOP_HOME%/bin
  3. 双击hadoop的bin目录下的winutils.exe,如果黑窗口一闪而过就没问题
  4. 创建一个maven项目,在pom文件里添如下的依赖:
<dependencies><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>3.1.3</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.36</version></dependency>
</dependencies>
  1. 在resources目录下创建log4j.properties文件,内容如下:
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
  1. 最后编写程序程序:
public class HdfsClientTest {private FileSystem fs;@Beforepublic void init() throws Exception {// 客户端地址URI uri = new URI("hdfs://hadoop2:8020");// 配置Configuration config = new Configuration();// 让NameNode返回的DataNode地址不用使用ip地址,而是使用主机名,解决上传/下载文件失败的问题// 注意前提是:// 		1.在hosts文件里配置了主机名和ip的映射//		2.主机开放了端口9866,通过“hadoop dfsadmin -report”可以查看DataNode的ip和端口config.set("dfs.client.use.datanode.hostname", "true");// 用户String user = "root";// 创建客户端fs = FileSystem.get(uri, config, user);}public void close() throws IOException {fs.close();}@Testpublic void testMkdir() throws Exception {fs.mkdirs(new Path("/test"));}/*** 参数优先级排序:客户端代码中设置的值 > ClassPath下的用户自定义配置文* 件 > 服务器的自定义配置(xxx-site.xml)> 服务器的默认配置(xxx-default.xml)*/@Testpublic void testUpload() throws Exception {// 参数1:上传后是否删除源文件,参数2:是否允许覆盖,参数3:源文件路径,参数4:目标文件路径fs.copyFromLocalFile(false, true, new Path("D:\\Download\\hadoop\\input\\hello.txt"),	}@Testpublic void testDownload() throws Exception {// 参数1:是否删除源文件,参数2:源文件路径,参数3:目标文件路径, 参数4:是否开启文件的crc校验fs.copyToLocalFile(false, new Path("/README.md"),new Path("D:\\Download\\"), true);}@Testpublic void testDelete() throws Exception {// 参数1:要删除的文件路径,参数2:是否递归删除fs.delete(new Path("/test"), true);}@Testpublic void testRenameAndMove() throws IOException {// 重命名// fs.rename(new Path("/README.md"), new Path("/readme.md"));// 移动fs.rename(new Path("/readme.md"), new Path("/test/README.md"));}
}

按照上述步骤操作会发现创建文件夹没有问题,但上传文件会失败。原因是上传文件时Java客户端会直接和DataNode打交道,而NameNode返回的DataNode信息是它的局域网ip和端口,所以Java客户端就没办法连接上DataNode进行写文件了。解决方法如下:

  1. 配置类加上配置:config.set("dfs.client.use.datanode.hostname", "true")

  2. 通过hadoop dfsadmin -report查看DataNode的ip和端口,在C:\Windows\System32\drivers\etc\hosts配置好ip和主机名的映射和开放端口(默认是9866)。由于我们三个容器部署在一台服务器上,并且之前已经配置好了hostname和ip的映射关系,9866端口也开放了,所以这一步不需要做任何操作。

补充:这里可能出现报错:Got error, status=ERROR, status message , ack with firstBadLink as 192.168.1.2:9866,这个报错时有时无;当有报错时,通过在网页端查看文件的副本信息可以发现:有两个副本上传成功,而另一个失败了。但成功的两个副本所在DataNode并不是固定的,我把日志级别设置为debug后研究了一番,但还是没弄清原因,等待有缘人提供解决方法。

MapReduce

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException;/*** KEYIN:mapper阶段输入数据的key的类型,LongWritable——偏移量* VALUEIN:mapper阶段输入数据的value的类型,Text——一行文本内容* KEYOUT:mapper阶段输出数据的key的类型,Text——单词* VALUEOUT:mapper阶段输出数据的value的类型,IntWritable——单词出现次数*/
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {private final Text outK = new Text();private final IntWritable outV = new IntWritable(1);@Overrideprotected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context) throws IOException, InterruptedException {String[] words = value.toString().split(" ");for (String word : words) {outK.set(word);context.write(outK, outV);}}
}/*** KEYIN:reduce阶段输入的key的类型* VALUEIN:reduce阶段输入的value的类型* KEYOUT:reduce阶段输出的key的类型* VALUEOUT:reduce阶段输出的value的类型*/
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {private final IntWritable outV = new IntWritable();@Overrideprotected void reduce(Text key, Iterable<IntWritable> values, Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {int sum = 0;for (IntWritable value : values) {sum += value.get();}outV.set(sum);context.write(key, outV);}
}public class WordCountDriver {public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {// 1 获取配置信息,或者job对象实例Configuration conf = new Configuration();Job job = Job.getInstance(conf);// 2 设置jar加载路径job.setJarByClass(WordCountDriver.class);// 3 设置map和reduce类job.setMapperClass(WordCountMapper.class);job.setReducerClass(WordCountReducer.class);// 4 设置map输出job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(IntWritable.class);// 5 设置最终输出job.setOutputKeyClass(Text.class);job.setOutputValueClass(IntWritable.class);// 6 设置输入和输出路径// FileInputFormat.setInputPaths(job, new Path("D:\\Download\\hadoop\\input"));// FileOutputFormat.setOutputPath(job, new Path("D:\\Download\\hadoop\\output"));FileInputFormat.setInputPaths(job, new Path(args[0]));FileOutputFormat.setOutputPath(job, new Path(args[1]));// 7 提交jobboolean result = job.waitForCompletion(true);System.out.println(result ? "job执行成功" : "job执行失败");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/93245.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/93245.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/93245.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常用的T-SQL命令

文章目录1. 数据库操作2. 表操作3. 数据插入、更新、删除4. 数据查询5. 存储过程6. 事务处理7、如何使用T-SQL在表中设置主键和外键&#xff1f;1. 设置主键&#xff08;PRIMARY KEY&#xff09;方法1&#xff1a;创建表时定义主键方法2&#xff1a;通过ALTER TABLE添加主键2. …

C++面试题及详细答案100道( 31-40 )

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

给纯小白的 Python 操作 Excel 笔记

&#x1f9f0; 1. 先装工具电脑键盘按 Win R&#xff0c;输入 cmd&#xff0c;回车&#xff0c;把下面一行粘进去回车&#xff0c;等它跑完。 bashpip install openpyxl——————————————————&#x1f6e0;️ 2. 打开一个空白的 Excel 打开 Jupyter Notebook…

HTML 常用属性介绍

目录 HTML 属性 HTML 属性速查表 一、通用属性&#xff08;所有元素适用&#xff09; 二、链接与引用相关属性 三、表单与输入控件属性 四、媒体与多媒体属性 五、事件属性&#xff08;常用 JavaScript 事件&#xff09; 六、其他常用属性 核心通用属性 id 属性 cla…

HTML5练习代码集:学习与实践核心特性

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;HTML5作为新一代网页标准&#xff0c;对Web开发提供了更丰富的功能和工具。本练习代码集专门针对HTML5的核心特性&#xff0c;包括语义化标签、离线存储、多媒体支持、图形绘制等&#xff0c;以及CSS3的3D效果和…

【RH134知识点问答题】第 10 章:控制启动过程

目录 1. 请简要说明 RHEL9 的启动过程。 2. 系统重启和关机的命令分别是什么? 3. Systemd target 是什么&#xff1f; 4. 重置丢失的 root 密码需要哪些步骤&#xff1f; 5. 如何让系统日志在重启后持久保留 1. 请简要说明 RHEL9 的启动过程。 答&#xff1a;①开机自检…

Apollo10.0学习之固态雷达与IMU的外参标定

固态雷达&#xff08;如Livox、禾赛等非旋转式激光雷达&#xff09;与IMU&#xff08;惯性测量单元&#xff09;的外参标定&#xff08;Extrinsic Calibration&#xff09;是自动驾驶、机器人定位&#xff08;如LIO-SAM、FAST-LIO&#xff09;的关键步骤。1. 标定原理 外参标定…

HTML5实现古典音乐网站源码模板1

文章目录 1.设计来源1.1 网站首页1.2 古典音乐界面1.3 著名人物界面1.4 古典乐器界面1.5 历史起源界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&#xff1a;xcLeigh 文章地址&#xff1a;http…

40 C++ STL模板库9-容器2-vector

C STL模板库9-容器2-vector 文章目录C STL模板库9-容器2-vector一、基础概念1. 类型成员&#xff08;Type Members&#xff09;2. 模板参数二、构造函数1. 语法2. 示例三、元素访问1. 函数说明2. 示例代码四、容量操作1. 函数说明2. 关键点说明3. 关键操作解析4. 操作示例五、修…

GPT-5系列文章2——新功能、测试与性能基准全解析

引言 2025年8月&#xff0c;OpenAI正式发布了其新一代旗舰模型GPT-5。与业界此前期待的AGI(人工通用智能)突破不同&#xff0c;GPT-5更像是OpenAI对现有技术的一次深度整合与用户体验优化。本文将全面解析GPT-5的新特性、实际测试表现以及官方发布的基准数据&#xff0c;帮助开…

利用cursor+MCP实现浏览器自动化释放双手

小伙伴们&#xff0c;我们今天利用cursorMCP实现浏览器自动化&#xff0c;释放双手&#xff0c;工作效率嘎嘎提升&#xff01;前期准备&#xff1a;安装node.js网址&#xff1a;https://nodejs.org/zh-cn下载下来安装即可。 下载browser-tools-mcp扩展程序&#xff1a;下载扩展…

指针/边界索引混淆梳理

在处理数组/链表等数据结构时&#xff0c;时常混淆长度和指针序号。处理技巧&#xff1a;使用0-base索引。则区间长度 rightIndex - LeftIndex 1总长度 lastIndex - firstIndex 1链表创建一个dummy节点&#xff0c;添加到head前&#xff0c;则可认为从索引0开始。末尾指针判…

LeetCode 刷题【43. 字符串相乘】

43. 字符串相乘 自己做 解1&#xff1a;矩阵计数 class Solution { public:string multiply(string num1, string num2) {int len1 num1.size();int len2 num2.size();if (num1[0] 0 || num2[0] 0) //结果为0的情况return "0";//存储计算过程的矩阵vector…

NLP数据增强方法及实现-A

目录 词替换 主要参考&#xff1a;paddlenlp/data_aug模块 词替换数据增强策略也即将句子中的词随机替换为其他单词进行数据增强&#xff0c;这里我们将介绍如何使用paddlenlp.dataaug.WordSubstitute进行词级别替换的数据增强。 WordSubstitute 参数介绍&#xff1a;aug_ty…

EhViewer安卓ios全版本类下载安装工具的完整路径解析

开发一款类似EhViewer的下载安装工具&#xff08;集下载管理、应用部署等功能于一体&#xff09;&#xff0c;需要经历从需求锚定到落地发布的系统性流程。以下从需求拆解到技术落地的全维度指南&#xff0c;将帮你理清开发脉络&#xff0c;避开常见陷阱。安装 GitHub - huangy…

MySQL 主键详解:作用与使用方法

在 MySQL 数据库中&#xff0c;主键&#xff08;Primary Key&#xff09; 是表结构设计中最重要的约束之一。它不仅是数据唯一性的保障&#xff0c;也是多表关联、查询优化的核心工具。本文将从 主键的作用 和 主键的用法 两个方面进行讲解&#xff0c;并配合代码示例帮助理解一…

lib.dom.d.ts

lib.dom.d.ts 是一个 TypeScript 类型声明文件&#xff0c;它是 TypeScript 标准库的一部分&#xff0c;用于定义浏览器 DOM&#xff08;文档对象模型&#xff09;相关的类型和接口。这个文件为开发者提供了浏览器中所有内置的 DOM 类型的定义&#xff0c;包括 localStorage、d…

Spring 工具类:StopWatch

StopWatch 是 Spring 框架提供的一个简单而强大的计时工具类&#xff0c;用于测量代码块的执行时间。它特别适合在开发阶段进行性能分析、调试和优化。 基本使用方法 // 创建 StopWatch 实例&#xff08;可指定 ID&#xff09; StopWatch stopWatch new StopWatch("性能分…

解决 VSCode 运行 Python 时 ModuleNotFoundError: No module named ‘open_webui‘ 问题

目录 1. 问题原因分析 2. 解决思路 3. 解决步骤 3.1 打开或创建 .vscode/launch.json 3.2 添加调试配置 3.3 配置说明 3.4 运行测试 4. 总结 在使用 VSCode 调试 Python 项目时&#xff0c;我们经常会遇到类似下面的错误&#xff1a; Exception has occurred: ModuleN…

Python基础-数据结构

数据结构 Python提供了四种主要的内置数据结构&#xff1a;列表&#xff08;List&#xff09;、元组&#xff08;Tuple&#xff09;、字典&#xff08;Dictionary&#xff09;和集合&#xff08;Set&#xff09;。每种数据结构都有其特定的用途和特性。 Python数据结构概览&…