我有一个远程运行的hadoop集群。我能够完成教程:
http://hadoop.apache.org/docs/r2.6.0/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html
在我的远程机器上,因为有一个内置的hadoop实例。不过,我希望在本地执行同样的任务。作为hadoop的新手,我不知道该怎么做。我想知道是否可以运行该程序并将结果发送回我的本地机器。我不知道如何登录到我的远程机器,然后运行MapReduce作业。
这是我在远程机器上的代码:
import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WordCount {
public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable>{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context
) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
public static class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values,
Context context
) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "word count");
conf.set("mapred.job.queue.name", "exp_dsa");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
我知道这对你来说有点晚了,但人们肯定可以从我的回应中获利,因为我正在寻求非常相似的设置,并能够远程运行作业(甚至从Eclipse)。
首先让我提一下,你不需要在你的机器上安装任何Hadoop分发来远程提交作业(至少在Hadoop2.6.0中,根据发布信息和你发布问题的日期,这在你的情况下似乎很好)。我将解释如何从Eclipse运行作业。
让我从配置开始。很少有资源可以说明如何实现这一点,但在没有额外配置的情况下,不同的解决方案都不适用于我。
在服务器上
-
假设您安装了Hadoop、Yarn和HDFS,那么您的第一步应该是正确配置系统变量(当然稍后您将需要它们)。我建议编辑名为
hadoop-env.sh
的文件(在我的情况下位于/etc/hadoop/conf/
),并包括以下行:export HADOOP_CONF_DIR=/etc/hadoop/conf/ export HADOOP_COMMON_HOME=/usr/lib/hadoop/ export HADOOP_HDFS_HOME=/usr/lib/hadoop-hdfs/ export HADOOP_YARN_HOME=/usr/lib/hadoop-yarn/ export HADOOP_MAPRED_HOME=/usr/lib/hadoop-mapreduce/
(其中
/usr/lib/hadoop/
对应于Hadoop的安装目录)。重新启动服务。 -
在
core-site.xml
中,您应该有以下配置:fs.defaultFS
,记下它的某个位置,并检查防火墙是否有一个打开的端口,以便外部客户端可以执行与数据相关的操作。如果您没有此配置,请将以下条目添加到文件中:<property> <name>fs.defaultFS</name> <value>hdfs://<host-name></value> <final>true</final> </property>
-
假设您已正确配置名称节点和数据节点。编辑
yarn-site.xml
文件并添加以下条目(或检查它们是否存在并记下配置)<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property> <property> <name>yarn.resourcemanager.address</name> <value><your-hostname>:8050</value> </property> <property> <name>yarn.application.classpath</name> <value> $HADOOP_CONF_DIR, $HADOOP_COMMON_HOME/*,$HADOOP_COMMON_HOME/lib/*, $HADOOP_HDFS_HOME/*,$HADOOP_HDFS_HOME/lib/*, $HADOOP_MAPRED_HOME/*,$HADOOP_MAPRED_HOME/lib/*, $HADOOP_YARN_HOME/*,$HADOOP_YARN_HOME/lib/* </value> </property>
(查看Hadoop文档以了解不同配置的含义)
-
使用以下条目修改
mapred-site.xml
文件:<property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>yarn.app.mapreduce.am.staging-dir</name> <value>/user</value> </property>
-
重新启动服务。服务器已基本就绪。检查是否所有需要的端口都可以从外部访问(以下网站上有相当完整的列表,其中只有一些应该是打开的,请与您的系统管理员联系)
在客户端
在Eclipse(简单的Java应用程序)中创建一个项目。创建你的Mapper和Reducer(这里有很多教程我不会给出任何例子)。现在在Main类中,您应该为您的工作提供以下配置(根据您的安全和系统限制,它可能会有所不同,所以如果您无法远程连接到服务器机器,您可能应该自己挖掘这个配置)
Configuration conf = new Configuration();
conf.set("yarn.resourcemanager.address", "<your-hostname>:8050"); // see step 3
conf.set("mapreduce.framework.name", "yarn");
conf.set("fs.defaultFS", "hdfs://<your-hostname>/"); // see step 2
conf.set("yarn.application.classpath",
"$HADOOP_CONF_DIR,$HADOOP_COMMON_HOME/*,$HADOOP_COMMON_HOME/lib/*,"
+ "$HADOOP_HDFS_HOME/*,$HADOOP_HDFS_HOME/lib/*,"
+ "$HADOOP_YARN_HOME/*,$HADOOP_YARN_HOME/lib/*,"
+ "$HADOOP_MAPRED_HOME/*,$HADOOP_MAPRED_HOME/lib/*");
Job job = Job.getInstance(conf);
if (args.length>0) {
job.setJar(args[0]); // see below, use this when submitting from Eclipse
} else {
job.setJarByClass(HadoopWorkloadMain.class); // use this when uploaded the Jar to the server and running the job directly and locally on the server
}
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(DoubleWritable.class);
job.setMapperClass(SomeMapper.class);
job.setCombinerClass(SomeReducer.class);
job.setReducerClass(SomeReducer.class);
FileInputFormat.addInputPath(job, new Path("/inputs/")); // existing HDFS directory
FileOutputFormat.setOutputPath(job, new Path("/results/")); // not existing HDFS directory
job.waitForCompletion(true);
类路径配置必须根据该资源进行设置。
这应该奏效。运行您的main并查看Hadoop的工作情况。无论如何,我祝你好运和耐心,这项听起来很容易的任务可能需要付出相当大的努力。
故障排除:
- 除了要包含在您的客户端构建路径中的明显Jars之外,您可能需要添加不太明显的Jars,请检查此SO问题,看看您应该额外包含什么
我在hadoop 2.7中遇到了同样的挑战,并通过添加以下配置解决了它。
conf.set("yarn.resourcemanager.address", "127.0.0.1:8032");
conf.set("mapreduce.framework.name", "yarn");
conf.set("fs.default.name", "hdfs://127.0.0.1:9000");
conf.set("mapreduce.job.jar",".\target\wc-mvn-0.0.1-SNAPSHOT.jar");
要实现这一点,您需要在本地拥有与Namenode相同的Hadoop分发和配置文件(core-site.xml、hdfs-site.xml和mapred-site.xml)副本。
然后,您可以使用hadoop命令从机器向远程集群提交作业。
除了Serhiy建议的所有步骤外,还必须按照下面文章中的建议使用WinUtils(如果用户在Windows上运行Eclipse)
Spark 1.6-在hadoop二进制路径中找不到winutils二进制文件
并将HADOOP_HOME路径设置为/bin目录的系统变量。