HDFS 在Web程序的相册功能开发中的应用 1、背景: 互联网的应用每时每刻都在产生数据,这些数据长期的积累了长期,使得这些数据文件总量非常庞大,存储这些数据需要投入巨大的硬件资源,但是如果能在已有空闲磁盘集群下可以利用起来,可以不再需要大规模采集服务器存储数据或购买容量庞大的磁盘,减 少了硬件成本。在这里就可以使用到分布式存储这种方案来解决这个问题。 HDFS就是一个开源在apache 上的分布式文件系统框架,它提供了命令行模式和api 模式来操作,HDFS 文件系统部署在多台节点上后,我们可以上传任意的文件到HDFS 中,无需关心文件究竟存储在哪个节点上。只要通过api 访问文件即可(流操作)。 下面我们用一个实际的产品来解决,在HDFS 中默认的块大小为64M,也就是说一个文件在大小不超过64M 的情况下不会被切割,整个文件会被完整的上传到某个节点中,通常我们在互联网门户中图片存储是个非常常见的应用,大量用户的图片自然占用了大量的存储空间,使用分布式文件系统正好满足相册的技术机构。每个图片一般经过压缩后最大几M,每个图片在使用HDFS 的也就是一个对应一个Block。下面我们考虑如下一个问题: web应用关心的是个对外的接口,这个接口只需要指定HDFS 的管理地址,但web 应用中每个请求访问一个图片,是否需要web 程序通过HDFS 将数据从不同节点上拉过来然后再传向客户端,这样是不是影响效率?如果存放数据的节点直接向浏览器发送数据是不是更好? 带着上面的问题我们就从架构开始设计一套系统。 我们可以在每台数据节点上都部署上apache 服务器,并发布同样的web 程序。当一个请求发现在某个节点上时,我们只需要直接将url重定向到节点所在的机器域名并请求同样的uri,就可以使得当前这个节点的apache 服务器同浏览器建立连接,并直接发送数据。 目前比较流行的web 架构是J2EE,在这里我们就采用J2EE的架构来搭建一个原型。 2、整体结构
我们拥有100 台机器,每台机器都部署了DataNode 节点和Apache Web 服务器,对外提供一个固定的域名服务器,客户通过浏览器直接访问的是该服务器,在该server 中发布程序接受来自浏览器的请求,通过调用HDFS 的接口,来判断请求的文件所存放的节点是否为当前节点,如果不是则根据得到的节点地址去重定向请求到存储该文件的节点的Apache 服务器上。 由于HDFS 中默认切割块为64M,通常图片文件大小不过几M,文件的存放就在一个Block 中,如果Block 数组大于1,因为浏览器不支持分段获取数据,那么我们需要直接从远程将数据拉到对外服务器中合并成完整的流,然后推送到浏览器中。
String filedisplay = (String) request.getParameter("filePath"; Path path = new Path(filedisplay); Configuration conf = new Configuration(); FileSystem fs = path.getFileSystem(conf); long length = file.getLen(); BlockLocation[] blkLocations = fs.getFileBlockLocations(file, 0,length);
如上面代码所示这里拿到到的BlockLocation包含了该块的信息:
private String[] hosts; //hostnames of datanodes private String[] names; //hostnameortNumber of datanodes private String[] topologyPaths; // full path name in networktopology private long offset; //offset of the of the block in the f ile private long length;
通过此可以拿到DataNode节点信息,让后将请求重定向到DataNode 所在的机器的Apache服务器中就行。 3 、处理结构图
4、Java程序实现
String filedisplay = (String)request.getParameter("filePath"; Path path = new Path(filedisplay); Configuration conf = new Configuration(); FileSystem fs = path.getFileSystem(conf); InputStream ins = fs.open(path); OutputStream outp = null; try { outp = response.getOutputStream(); byte[] b = new byte[1024]; int i = 0; while ((i = ins.read(b)) > 0) { outp.write(b, 0, i); } outp.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (ins != null) { ins.close(); ins = null; } if (outp != null) { outp.close(); outp = null; } } 通过以上步骤,jsp中将请求的URI进行匹配,即可获取文件的流并下载。
5、使用总结: Hdfs在和传统JavaEE Web应用的时候,主要发挥查询大数据文件的功能,而且这个文件一般是静态文件,不经常做变更(Hadoop文件块写入是不会变化的。 ,. HDFS 在Web程序的相册功能开发中的应用 |
HDFS 在Web程序的相册功能开发中的应用
最新推荐文章于 2023-09-14 14:05:31 发布