.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。
相關文章
相關標籤/搜索