JSP访问Hadoop 图片存储服务

2022-06-29 18:37:55 浏览数 (1)

使用Hadoop的hdfs来存放图片文件.以下是整个架构思路:

使用hadoop作为分布式文件系统,hadoop是一个实现了HDFS文件系统和MapReduce的开源项目,我们这里只是使用了它的hdfs.首先从web页面上上传的文件直接调用hadoop接口将图片文件存入hadoop系统中,hadoop可以设定备份数,这样在hadoop系统中某个datanode死掉并不会造成图片不可能,系统会从其他datanode上拿到数据。

以下我们编写的一个hadoop的java的访问封装类:

import java.io.File; import java.io.IOException; import java.io.InputStream;

import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileUtil; import org.apache.hadoop.fs.Path; import org.apache.log4j.Logger;

public class HadoopFileUtil {  static Logger logger = Logger.getLogger(HadoopFileUtil.class);  /**   * @param args   */  public static void main(String[] args) {   String src=args[0];   String dst=args[1];   String tag=args[2]; HadoopFileUtil util=new HadoopFileUtil();   if(tag!=null&&tag.equals("1")){     System.out.println(util.createFile(src, dst));   }   else{     util.deleteFile(dst);   }

 }

 /**   * 拷贝一个本地文件到hadoop里面   * @param localFile 本地文件和路径名   * @param hadoopFile hadoop文件和路径名   * @return   */  public  boolean createFile(String localFile,String hadoopFile){   try {   Configuration conf=new Configuration();   FileSystem src=FileSystem.getLocal(conf);   FileSystem dst= FileSystem.get(conf);   Path srcpath = new Path(localFile);   Path dstpath = new Path(hadoopFile);   FileUtil.copy(src, srcpath, dst, dstpath,false,conf);   } catch (Exception e) {   e.printStackTrace();   return false;   } 

  return true;  }  /**将一个流作为输入,生成一个hadoop里面的文件   * @param inStream 输入流   * @param hadoopFile hadoop路径及文件名字   * @return   */  public boolean createFileByInputStream(InputStream inStream,String hadoopFile){   try {   Configuration conf=new Configuration();   FileSystem dst= FileSystem.get(conf);   Path dstpath = new Path(hadoopFile);   FSDataOutputStream oStream=dst.create(dstpath);   byte[] buffer = new byte[400];   int length = 0;   while((length = inStream.read(buffer))>0){     oStream.write(buffer,0,length);   }   oStream.flush();   oStream.close();   inStream.close();   } catch (Exception e) {   e.printStackTrace();   return false;   }    return true;  }  /**   * 删除hadoop里面的一个文件   * @param hadoopFile   * @return   */  public  boolean deleteFile(String hadoopFile){   try {   Configuration conf=new Configuration();   FileSystem dst= FileSystem.get(conf);   FileUtil.fullyDelete(dst,new Path(hadoopFile));   } catch (Exception e) {   e.printStackTrace();   return false;   }   return true;  }  /**   * 从hadoop中读取一个文件流   * @param hadoopFile   * @return   */  public FSDataInputStream getInputStream(String hadoopFile){   FSDataInputStream iStream=null;   try {   Configuration conf=new Configuration();   FileSystem dst= FileSystem.get(conf);   Path p=new Path(hadoopFile);   iStream=dst.open(p);   } catch (Exception e) {   e.printStackTrace();   logger.error("getInputStream error:", e);   }   return iStream;  }

} 通过调用这个类可以将图片存入hadoop 系统.

当需要访问某个图片时,先访问jsp服务器(如:tomcat)的一个servlet,这个servlet从hadoop里面读出图片,并

返回给浏览器.以下是我们的servlet: import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter;

import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;

import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.io.IOUtils; import org.apache.log4j.Logger;

import com.tixa.dfs.hadoop.util.HadoopFileUtil;

public class HadoopServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {  static Logger logger = Logger.getLogger(HadoopServlet.class);  public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{

  PrintWriter out=res.getWriter();   res.setContentType("image/jpeg");   java.util.Date date = new java.util.Date();    res.setDateHeader("Expires",date.getTime() 1000*60*60*24);    String path=req.getPathInfo();   path=path.substring(1,path.length());   HadoopFileUtil hUtil=new HadoopFileUtil();   FSDataInputStream inputStream=hUtil.getInputStream(path);   OutputStream os = res.getOutputStream();   byte[] buffer = new byte[400];   int length = 0;   while((length = inputStream.read(buffer))>0){     os.write(buffer,0,length);   }   os.flush();   os.close();   inputStream.close();  } }

另外,为了避免对hadoop的频繁读取,可以再jsp服务器前放一个squid进行对图片的缓存。

这就是我们图片服务器的架构.

0 人点赞