我是一个Hadoop爱好者,仍处于学习阶段,出于好奇我尝试了一些东西,我想让servlet调用Hadoop作业。我尝试了两种方法,但都失败了。等等,首先有人能告诉我这是否可行吗?如果是这样的话,请用一些实时的例子来启发我(不要告诉我Hue),或者你可以简单地说我疯了,在浪费时间。
好吧,如果你正在读这篇文章,那么我没有疯。现在请看一下我的代码,告诉我我做错了什么!!!
package com.testingservlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
/**
* Servlet implementation class HelloServlets
*/
@WebServlet("/HelloServlets")
public class HelloServlets extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public HelloServlets() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// TODO Auto-generated method stub
/*******************************************************************
* *Approach 1
*
* Using the Hadoop code directly into servlets
* *****************************************************************
*/
String localPath = "/home/asadgenx/filelist.txt";
FileSystem fs = FileSystem.get( new Configuration());
Path workingDir = fs.getWorkingDirectory();
out.println("DestinationPath path:"+workingDir);
Path hdfsDir = new Path(workingDir+"/servelets");
out.println("DestinationPath Directory:"+workingDir);
fs.mkdirs(hdfsDir);
out.println("Source path:"+localPath);
Path localFile = new Path(localPath);
Path newHdfsFile = new Path(hdfsDir+"/"+"ourTestFile1.txt");
out.println("Destination File path:"+hdfsDir+"/"+"ourTestFile1.txt");
fs.copyFromLocalFile(localFile, newHdfsFile);
/*******************************************************************
* *Approach 2
*
* Executing hadoop commands as string using runtime.exec()
* *****************************************************************
*/
String[] cmd = new String[] {"hadoop fs -copyFromLocal /home/asadgenx/filelist.txt /user/asad/myfile.txt"};
Process process = Runtime.getRuntime().exec(cmd);
out.println("File copied!!");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
方法一出错HTTP状态500-Mkdirs无法创建文件:/var/lib/tomcat7/servelets
方法二出错HTTP状态500-无法运行程序"hadoop fs-copyFromLocal/home/asadgenx/filelist.txt/user/asad/myfile.txt":错误=2,没有这样的文件或目录
这里的Hadoop专家能帮我解决这个问题吗!!!
我希望现在回答你的问题还为时不晚。
首先,我将把这个问题的范围扩大到从tomcat servlet访问HDFS文件系统,这正是你想要做的。我遇到了很多陷阱,阅读了很多论坛帖子来了解它,更多的是你如何设置一切。
要遵循方法2,您必须与SecurityManager打交道,而您不希望这样做。
要遵循方法1,请查看以下检查列表:
-
使您的网络应用程序可以访问appropiate jar文件。我更喜欢在每个网络应用程序中放置罐子,而不是通过tomcat提供它们。无论如何,你的网络应用程序应该可以访问以下jar文件列表(我没有命名jar版本,也许其中一些是多余的,我正试图从运行Map Reduce作业的项目中删除列表,然后得到结果):
- hadoop公共
- 番石榴
- 公共日志记录
- commons-cli
- log4j
- 朗公地
- 公用配置
- hadoop身份验证
- slf4j-log4j
- slf4j-api
- hadoop-hdfs
- protobuf-java
- htrace核心
它们位于hadoop分发中的许多目录中
-
请确保您的网络配置正常。测试您的hadoop服务是否已启动并运行,以及您是否可以访问从tomcat服务器到hadoop服务器所需的所有主机和端口配置。如果它们都位于同一服务器中,那就更好了。尝试访问HDFS监视器(http://hadoop-host:50070)tomcat服务器上的网页。
-
调整您将要读取/写入的文件的访问权限:
a。通过您的网络应用程序,您将只能访问位于网络应用程序目录内的文件。
b。从hadoop,您的web应用程序将以用户"tomcat"的身份连接。请确保用户tomcat具有读取或写入Hadoop DFS中预期文件的权限。
- 正如Angus所假设的,您的Configuration对象将为空。您需要在servlet中自己设置所需的配置参数
一旦一切都设置好了,就可以在servlet中运行这样的东西:
//Set the root of the files I will work with in the local file system
String root = getServletContext().getRealPath("/") + "WEB-INF";
//Set the root of the files I will work with in Hadoop DFS
String hroot = "/home/tomcat/output/mrjob";
//Path to the files I will work with
String src = hroot + "/part-00000.avro";
String dest = root + "/classes/avro/result.avro";
//Open the HDFS file system
Configuration hdfsconf = new Configuration();
//Fake Address, replace with yours!
hdfsconf.set("fs.default.name", "hdfs://hadoop-host:54310");
hdfsconf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
hdfsconf.set("fs.file.impl", "org.apache.hadoop.fs.LocalFileSystem");
FileSystem hdfs = FileSystem.get(hdfsconf);
//Copy the result to local
hdfs.copyToLocalFile(new Path(src), new Path(dest));
//Delete result
hdfs.delete(new Path(hroot), true);
//Close the file system handler
hdfs.close();
希望这能有所帮助!