无法通过map reduce java程序访问Hadoop hdfs文件系统

Posted

技术标签:

【中文标题】无法通过map reduce java程序访问Hadoop hdfs文件系统【英文标题】:Unable to access Hadoop hdfs file system through map reduce java program 【发布时间】:2017-03-05 23:07:54 【问题描述】:

我的 Hadoop 版本是 - 2.6.0 -cdh5.10.0 我正在使用 Cloudera Vm。

我正在尝试通过我的代码访问 hdfs 文件系统以访问文件并将其添加为输入或缓存文件。

当我尝试通过命令行访问 hdfs 文件时,我能够列出这些文件。

命令:

[cloudera@quickstart java]$ hadoop fs -ls hdfs://localhost:8020/user/cloudera 
Found 5items
-rw-r--r--   1 cloudera cloudera        106 2017-02-19 15:48 hdfs://localhost:8020/user/cloudera/test
drwxr-xr-x   - cloudera cloudera          0 2017-02-19 15:42 hdfs://localhost:8020/user/cloudera/test_op
drwxr-xr-x   - cloudera cloudera          0 2017-02-19 15:49 hdfs://localhost:8020/user/cloudera/test_op1
drwxr-xr-x   - cloudera cloudera          0 2017-02-19 15:12 hdfs://localhost:8020/user/cloudera/wc_output
drwxr-xr-x   - cloudera cloudera          0 2017-02-19 15:16 hdfs://localhost:8020/user/cloudera/wc_output1

当我尝试通过我的 map reduce 程序访问相同的东西时,我收到 File Not Found 异常。 我的 Map reduce 示例配置代码是:

public int run(String[] args) throws Exception 
		
		Configuration conf = getConf();
		
		if (args.length != 2) 
			System.err.println("Usage: test <in> <out>");
			System.exit(2);
		
		
		ConfigurationUtil.dumpConfigurations(conf, System.out);
		
		LOG.info("input: " + args[0] + " output: " + args[1]);
		
		Job job = Job.getInstance(conf);
		
		job.setJobName("test");
		
		job.setJarByClass(Driver.class);
		job.setMapperClass(Mapper.class);
		job.setReducerClass(Reducer.class);

		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(Text.class);
		
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(DoubleWritable.class);
		
		
		job.addCacheFile(new Path("hdfs://localhost:8020/user/cloudera/test/test.tsv").toUri());
		
		
		FileInputFormat.addInputPath(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path(args[1]));
		
		
		boolean result = job.waitForCompletion(true);
		return (result) ? 0 : 1;
	

上面 sn -p 中的行 job.addCacheFile 返回 FileNotFound Exception。

2)我的第二个问题是:

我在 core-site.xml 中的条目指向默认 hdfs 文件系统 URI 的 localhost:9000。但是在命令提示符下,我只能在端口 8020 而不是在 9000 访问默认 hdfs 文件系统。当我尝试使用端口 9000,我最终遇到了 ConnectionRefused 异常。我不确定从哪里读取配置。

我的 core-site.xml 如下:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>
  <!--  
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/Users/student/tmp/hadoop-local/tmp</value>
   <description>A base for other temporary directories.</description>
  </property>
-->
  
 <property>
  <name>fs.default.name</name>
  <value>hdfs://localhost:9000</value>
  <description>Default file system URI.  URI:scheme://authority/path scheme:method of access authority:host,port etc.</description>
</property>
 
</configuration>

我的 hdfs-site.xml 如下:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>

	<property>
		<name>dfs.name.dir</name>
		<value>/tmp/hdfs/name</value>
		<description>Determines where on the local filesystem the DFS name
			node should store the name table(fsimage).</description>
	</property>

	<property>
		<name>dfs.data.dir</name>
		<value>/tmp/hdfs/data</value>
		<description>Determines where on the local filesystem an DFS data node should store its blocks.</description>
	</property>
	
	<property>
		<name>dfs.replication</name>
		<value>1</value>
		<description>Default block replication.Usually 3, 1 in our case
		</description>
	</property>
</configuration>

我收到以下异常:

java.io.FileNotFoundException: hdfs:/localhost:8020/user/cloudera/test/   (No such file or directory)
  at java.io.FileInputStream.open(Native Method)
  at java.io.FileInputStream.<init>(FileInputStream.java:146)
  at java.io.FileInputStream.<init>(FileInputStream.java:101)
  at java.io.FileReader.<init>(FileReader.java:58)
  at hadoop.TestDriver$ActorWeightReducer.setup(TestDriver.java:104)
  at org.apache.hadoop.mapreduce.Reducer.run(Reducer.java:168)
  at        org.apache.hadoop.mapred.ReduceTask.runNewReducer(ReduceTask.java:627)
at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:389)
at org.apache.hadoop.mapred.LocalJobRunner$Job$ReduceTaskRunnable.run(LocalJobRunner.java:319)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)

任何帮助都会很有用!

【问题讨论】:

您可以分享您在尝试通过 Map reduce 访问文件时给出的参数 @siddhartha jain :hadoop test.jar path-to-driverclass hdfs-path-to-input 输出 你能发布程序抛出的异常吗 @HariSingh :我已经更新了帖子,但收到了例外。 @user1477232 如果您会看到日志 hdfs:/localhost:8020/user/cloudera/test/ 它正在尝试从这条路径获取,但我认为它应该是 hdfs://localhost:8020 /user/cloudera/test/ 所以给三个斜杠 (hdfs:///localhost:8020/) 或者不给出完整路径直接写 (/user/cloudera/test) 默认它将采用 hdfs 路径 【参考方案1】:

您不需要提供完整路径作为从 hdfs 访问文件的参数。 Namenode 自己(来自 core-site.xml)将添加 hdfs://host_address 的前缀。您只需要提及您要访问的文件以及您的情况下的目录结构应该是 /user/cloudera/test

来到您的 2 问题端口号 8020 是 hdfs 的默认端口。这就是为什么即使您没有提及它,您也可以在端口 8020 访问 hdfs。 connectionrefused 异常的原因是因为 hdfs 从 8020 开始,这就是端口 9000 不期待任何请求的原因,因此它拒绝了连接。

有关默认端口的更多详细信息,请参阅here

【讨论】:

我尝试给 /user/cloudera/test 但它没有工作。我收到 FileNotFoundException。" connectionrefused 异常的原因是因为 hdfs 从 8020 开始,这就是端口 9000 不期待任何请求的原因因此它拒绝了连接。”我应该如何解决这个问题? 将 core-site.xml 中的端口更改为 8020

以上是关于无法通过map reduce java程序访问Hadoop hdfs文件系统的主要内容,如果未能解决你的问题,请参考以下文章

在使用 java 运行 Hadoop map reduce 作业时抛出空指针异常

hadoop mapreduce 进程都有哪些

HA分布式集群二hive配置

Hadoop Map Reduce 程序

Yarn中的Map和Reduce的优化

您如何在 map/reduce 中实现排名和排序?