详解MongoDB实现存储物理文件和SQUID加速

数据库 其他数据库 MongoDB
今天我们要讲到的是在MongoDB上如何存储物理文件,以及实现SQUID加速等问题。希望对大家了解“芒果”有所帮助。

之前在阅读MongoDB GFS文档时,学习了它如何存储物理文件(包括大文件)的方式。为了加深印象,专门写了一个上传文件存储到Mongodb的示例。当然后因为是存储到文档数据库中,所以就不能用普通方式来访问这些物理文件了,这里又专门写了一个aspx页面专门读取这些文件(比如图片或MP3等),所以下载示例之后会看到两个页面,一个是uploadfile.aspx(上传),一个是getfile.aspx(从mongodb中把文件以流的方式读出来)。当然考虑到访问速度,这里还引入了SQUID来进行文件加速(当前SQUID默认只缓存静态文件,所以这里要对ASPX页面的输出进行一下设置,这些都会在本文中进行介绍)

首先介绍一下开发环境,我使用的是VS2008+SP1 ,mongodb客户端软件用的是samus-mongodb(最新版本即可)

添加对下面名空间的引用

  1. using MongoDB;  
  2. using MongoDB.GridFS; 

下面是上传文件的主要代码:

uploadfile.aspx.cs    

  1. HttpPostedFile myFile = FileUpload.PostedFile;  
  2.      int nFileLen = myFile.ContentLength;  
  3.        
  4.      byte[] myData = new Byte[nFileLen];  
  5.      myFile.InputStream.Read(myData, 0, nFileLen);  
  6.        
  7.      GridFile fs = new GridFile(DB, filesystem);  
  8.  
  9.      Random random = new Random(unchecked((int)DateTime.Now.Ticks));  
  10.  string newfilename = string.Format("{0}{1}{2}", random.Next(1000, 99999), 
  11. random.Next(1000, 99999), System.IO.Path.GetExtension(myFile.FileName));  
  12.      GridFileStream gfs = fs.Create(newfilename);  
  13.      gfs.Write(myData, 0, nFileLen);  
  14.      gfs.Close(); 

这里只是给上传文件起个随机名称,这样如果一切正常,就可以在数据库中找到该文件了,如下图:

    

下面看一下如何访问上传的物理文件getfile.aspx.cs(通过传递filename参数,mongodb中相应字段结构,如上图):

  1. protected void Page_Load(object sender, EventArgs e)  
  2.      {  
  3.          if (!string.IsNullOrEmpty(Request.QueryString["filename"]))  
  4.          {  
  5.              string filename = Request.QueryString["filename"];  
  6.              Init();  
  7.              String filesystem = "gfstream";  
  8.  
  9.              GridFile fs = new GridFile(DB, filesystem);  
  10.              GridFileStream gfs = fs.OpenRead(filename);  
  11.  
  12.              Byte[] buffer = new Byte[gfs.Length];  
  13. HttpContext.Current.Response.AddHeader("Expires", DateTime.Now.AddDays(20).ToString("r"));  
  14.              HttpContext.Current.Response.AddHeader("Cache-Control""public");  
  15.         
  16.              // 需要读的数据长度  
  17.              long dataToRead = gfs.Length;  
  18.              int length;  
  19.              while (dataToRead > 0)  
  20.              {  
  21.                  // 检查客户端是否还处于连接状态  
  22.                  if (HttpContext.Current.Response.IsClientConnected)  
  23.                  {  
  24.                      length = gfs.Read(buffer, 0, 10000);  
  25.           HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);  
  26.                      HttpContext.Current.Response.Flush();  
  27.                      buffer = new Byte[10000];  
  28.                      dataToRead = dataToRead - length;  
  29.                  }  
  30.                  else 
  31.                  {  
  32.                      // 如果不再连接则跳出死循环  
  33.                      dataToRead = -1;  
  34.                  }  
  35.              }  
  36.              gfs.Dispose();  
  37.              HttpContext.Current.Response.End();  
  38.          }  
  39.      } 

下面就是以列表的方式从mongodb中检索文件列表的最终的运行效果:

    

尽管MONGODB的并发性能很不错,但每次都去mongodb取的话也是有性能损耗的,特别是对于不经常变化的物理文件,所以这里使用了SQUID来进行文件缓存。当前SQUID默认只支持静态文件,对于本示例中的ASPX页面输出的流信息来缓存还要进行一下设置。    

首先,如果在squid.conf文件中有如下行,需要用#进行注释(它会禁止缓存所有带?的链接地址):

  1. hierarchy_stoplist cgi-bin ? \.php \.html  
  2. acl QUERY urlpath_regex cgi-bin \? \.php \.html     
  3. cache deny QUERY 

这样,再修改一下相应的.aspx,并在Header中添加如下信息,即:    

  1. HttpContext.Current.Response.AddHeader("Expires", DateTime.Now.AddDays(20).ToString("r"));  
  2. HttpContext.Current.Response.AddHeader("Cache-Control", "public"); 

这样SQUID就会忠实在根据该头信息来CACHED相应文件了。

当然也可以用如下方式来让指定那些文件aspx文件才会被SQUID CACHED:   

  1. acl CACHABLE_PAGES urlpath_regex \getfile.aspx  
  2.    #允许cache上面的aspx页面  
  3.    no_cache allow CACHABLE_PAGES 

而下面一个acl匹配所有的动态页面并禁止缓存所有aspx页面

  1. #acl NONE_CACHABLE_PAGES urlpath_regex \? \.aspx     
  2.     #禁止cache其它的aspx页面  
  3.     #no_cache deny NONE_CACHABLE_PAGES 

下面几行设置页面cache的时长,第一行cache一天,第二行cache两分钟

  1. refresh_pattern ^http://10.0.4.114:1100/mongodbsample/getfile.aspx 1440 0% 1440 ignore-reload  
  2. refresh_pattern ^http://10.0.4.114:1100/mongodbsample/getfile.aspx 2 0% 2 ignore-reload 

如要SQUID配置正确的话,只要访问SQUID所请求代理的站点(本文中为http://10.0.4.85:8989/mongodbspame/uploadfile.aspx),这里它就会到http://10.0.4.114:1100/mongodbspame/uploadfile.aspx去获取页面信息,同时对该页面中的链接getfile.aspx文件均会进行缓存,如下图:

    

好了,今天的内容就先到这里了,示例源码及SQUID配置文件下载链接:/Files/daizhj/mongodbsample.rar

原文标题:使用Mongodb存储上传物理文件并进行SQUID加速(基于aspx页面)

链接:http://www.cnblogs.com/daizhj/archive/2010/08/19/1803454.html

【编辑推荐】

  1. MongoDB CEO谈NoSQL的大数据量处理能力
  2. 抛弃关系数据库 PHP程序员应了解MongoDB的五件事
  3. MongoDB,无模式文档型数据库简介
  4. 关系数据库的末日是否已经来临
  5. 扔掉沉没成本 尝试关系数据库替代品OODBMS 
     
责任编辑:彭凡 来源: 博客园
相关推荐

2013-07-24 18:06:07

存储存储虚拟化

2018-07-17 14:50:47

存储虚拟化技术

2013-11-11 10:22:14

存储虚拟化

2010-09-09 08:42:28

MongoDB

2023-04-14 15:37:02

DataLeap存储优化MySQL

2010-05-10 14:16:50

Oracle树结构

2009-06-19 17:39:52

ibmdwLotus

2009-07-31 17:01:00

ibmdwAmazon

2018-08-17 10:05:25

存储系统转型

2018-06-14 08:44:03

2023-12-01 16:30:12

2011-08-03 13:28:08

Oracle数据库数据库控制文件

2017-04-26 08:51:36

MongoDB集群实战

2022-02-17 08:02:45

对象存储RGW

2010-05-05 14:14:56

iMC数据中心管理平台

2017-09-15 16:00:48

Lucene存储读取技术

2010-11-15 11:58:02

Oracle物理结构

2019-08-06 09:11:49

数据库数据结构操作系统

2010-04-21 16:55:06

Oracle物理存储结

2017-07-13 09:48:17

点赞
收藏

51CTO技术栈公众号