.Net平台下,分布式文件存储的实现

遇到的问题 

对于Web程序,使用一台服务器的时候,客户端上传的文件通常也都是存储在这台服务器上。但在集群环境中就行不通了,若是每一个服务器都存储本身接受到的文件,就乱套了,数据库中明明有这个附件的记录,却找不到这个文件。因而,文件须要进行统一集中管理,并向集群中的服务器提供统一的路径。html

基于NFS的分布式文件存储实现

Network File System 简称NFS,用人话说叫共享文件夹,能够实现分布式存储文件。只须要在文件服务器上共享文件夹,并指定相应帐号的权限,并给Web服务器设置能够访问共享文件夹的帐号和密码,web服务器就能够像操做本地文件同样操做文件服务器上的文件了。NFS下的文件访问路径有固定的格式,称为UNC(Universal Naming Convention),以“\\”开头。web

要以UNC的方式访问NFS下的文件,须要用到windows提供的两个API:WNetAddConnection2 和 WNetCancelConnection2。WNetAddConnection2可使用指定的帐号和密码建立一个UNC的链接,而后程序能够直接访问该UNC下文件。数据库

首先建立类FileServerConnection,用于管理链接,具体代码以下:windows

public class FileServerConnection
{
    private string uncName;
    private string username;
    private string password;

    /// <summary>
    /// 构造器
    /// </summary>
    /// <param name="uncName">完整的UNC路径</param>
    /// <param name="username">访问共享链接的用户名</param>
    /// <param name="password">访问共享链接的密码</param>
    public FileServerConnection(string uncName, string username, string password)
    {
        this.uncName = uncName;
        this.username = username;
        this.password = password;
    }

    /// <summary>
    /// 链接文件服务器
    /// </summary>
    public void Connect()
    {
        var netResource = new NetResource
                    {
                        Scope = ResourceScope.GlobalNetwork,
                        ResourceType = ResourceType.Disk,
                        DisplayType = ResourceDisplayType.Share,
                        RemoteName = this.uncName.TrimEnd('\\')
                    };

        var result = WNetAddConnection2(netResource, password, username, 0);
        if (result != 0)
            throw new Win32Exception(result);
    }

    /// <summary>
    /// 释放链接
    /// </summary>
    public void Disconnect()
    {
        WNetCancelConnection2(this.uncName, 0, true);
    }

    [DllImport("mpr.dll")]
    private static extern int WNetAddConnection2(NetResource netResource,
                                                    string password,
                                                    string username,
                                                    int flags);

    private static extern int WNetCancelConnection2(string name, int flags, bool force);
}

FileServerConnection中所用到的几个结构体代码以下:安全

[StructLayout(LayoutKind.Sequential)]
public class NetResource
{
    public ResourceScope Scope;
    public ResourceType ResourceType;
    public ResourceDisplayType DisplayType;
    public int Usage;
    public string LocalName;
    public string RemoteName;
    public string Comment;
    public string Provider;
}

public enum ResourceScope
{
    Connected = 1,
    GlobalNetwork,
    Remembered,
    Recent,
    Context
} ;

public enum ResourceType
{
    Any = 0,
    Disk = 1,
    Print = 2,
    Reserved = 8,
}

public enum ResourceDisplayType
{
    Generic = 0x0,
    Domain = 0x01,
    Server = 0x02,
    Share = 0x03,
    File = 0x04,
    Group = 0x05,
    Network = 0x06,
    Root = 0x07,
    Shareadmin = 0x08,
    Directory = 0x09,
    Tree = 0x0a,
    Ndscontainer = 0x0b
}

而后在Web程序启动的时候,只须要建立一个FileServerConnection的实例,而后调用它的Connect方法。为了防止重复建立链接引起异常,能够Connect以前先DisConnect。具体调用代码以下: 服务器

fsConnection= new FileServerConnection (storeRootPath, username, password);
fsConnection.Disconnect();
fsConnection.Connect();

基于DFS分布式存储方案

一台文件存储服务器+一块大磁盘,已经可以应付大多数状况了。若是想要更大的存储容量、更大的吞吐量、更安全可靠的文件部署方案,可使用windows server上的DFS。DFS本质上仍是基于文件夹共享(NFS)的,可是能够经过它来组织多太文件服务器提供统一的访问路径,从而支持大容量和大吞吐量。并且,能够配置把同一份文件存储在不一样的服务器上,一台挂掉以后,文件仍然不会丢失;DFS还能够和活动目录集成,即便根服务器挂掉,仍然不影响服务器使用,从而 保证文件存储的可靠性。Windows Server下DFS的安装和使用参考: http://technet.microsoft.com/zh-cn/library/cc731089.aspx#BKMK_UI 和  http://www.cnblogs.com/cabin/archive/2010/10/07/1845020.html
若是不想使用Windows自带的DFS,还有第三方的DFS可供选择,好比 FastDFS。
相关文章
相关标签/搜索