分散式文件系統FastDFS設計原理

来源:http://www.cnblogs.com/uiopoiiss/archive/2016/06/02/5552227.html
-Advertisement-
Play Games

FastDFS是一個開源的輕量級分散式文件系統,由跟蹤伺服器(tracker server)、存儲伺服器(storage server)和客戶端(client)三個部分組成,主要解決了海量數據存儲問題,特別適合以中小文件(建議範圍:4KB < file_size <500MB)為載體的線上服務。 S ...


FastDFS是一個開源的輕量級分散式文件系統,由跟蹤伺服器(tracker server)、存儲伺服器(storage server)和客戶端(client)三個部分組成,主要解決了海量數據存儲問題,特別適合以中小文件(建議範圍:4KB < file_size <500MB)為載體的線上服務。

enter image de.ion here

 

Storage server

Storage server(後簡稱storage)以組(捲,group或volume)為單位組織,一個group內包含多台storage機器,數據互為備份,存儲空間以group內容量最小的storage為準,所以建議group內的多個storage儘量配置相同,以免造成存儲空間的浪費。

以group為單位組織存儲能方便的進行應用隔離、負載均衡、副本數定製(group內storage server數量即為該group的副本數),比如將不同應用數據存到不同的group就能隔離應用數據,同時還可根據應用的訪問特性來將應用分配到不同的group來做負載均衡;缺點是group的容量受單機存儲容量的限制,同時當group內有機器壞掉時,數據恢復只能依賴group內地其他機器,使得恢復時間會很長。

group內每個storage的存儲依賴於本地文件系統,storage可配置多個數據存儲目錄,比如有10塊磁碟,分別掛載在/data/disk1-/data/disk10,則可將這10個目錄都配置為storage的數據存儲目錄。

storage接受到寫文件請求時,會根據配置好的規則(後面會介紹),選擇其中一個存儲目錄來存儲文件。為了避免單個目錄下的文件數太多,在storage第一次啟動時,會在每個數據存儲目錄里創建2級子目錄,每級256個,總共65536個文件,新寫的文件會以hash的方式被路由到其中某個子目錄下,然後將文件數據直接作為一個本地文件存儲到該目錄中。

Tracker server

Tracker是FastDFS的協調者,負責管理所有的storage server和group,每個storage在啟動後會連接Tracker,告知自己所屬的group等信息,並保持周期性的心跳,tracker根據storage的心跳信息,建立group==>[storage server list]的映射表。

Tracker需要管理的元信息很少,會全部存儲在記憶體中;另外tracker上的元信息都是由storage彙報的信息生成的,本身不需要持久化任何數據,這樣使得tracker非常容易擴展,直接增加tracker機器即可擴展為tracker cluster來服務,cluster里每個tracker之間是完全對等的,所有的tracker都接受stroage的心跳信息,生成元數據信息來提供讀寫服務。

Upload file

FastDFS向使用者提供基本文件訪問介面,比如upload、download 下載地址   、append、delete等,以客戶端庫的方式提供給用戶使用。

enter image de.ion here

選擇tracker server

當集群中不止一個tracker server時,由於tracker之間是完全對等的關係,客戶端在upload文件時可以任意選擇一個trakcer

選擇存儲的group

tracker接收到upload file的請求時,會為該文件分配一個可以存儲該文件的group,支持如下選擇group的規則: 1. Round robin,所有的group間輪詢 2. Specified group,指定某一個確定的group 3. Load balance,剩餘存儲空間多多group優先

選擇storage server

當選定group後,tracker會在group內選擇一個storage server給客戶端,支持如下選擇storage的規則: 1. Round robin,在group內的所有storage間輪詢 2. First server ordered by ip,按ip排序 3. First server ordered by priority,按優先順序排序(優先順序在storage上配置)

選擇storage path

當分配好storage server後,客戶端將向storage發送寫文件請求,storage將會為文件分配一個數據存儲目錄,支持如下規則: 1. Round robin,多個存儲目錄間輪詢 2. 剩餘存儲空間最多的優先

生成Fileid

選定存儲目錄之後,storage會為文件生一個Fileid,由storage server ip、文件創建時間、文件大小、文件crc32和一個隨機數拼接而成,然後將這個二進位串進行base64編碼,轉換為可列印的字元串。

選擇兩級目錄

當選定存儲目錄之後,storage會為文件分配一個fileid,每個存儲目錄下有兩級256*256的子目錄,storage會按文件fileid進行兩次hash(猜測),路由到其中一個子目錄,然後將文件以fileid為文件名存儲到該子目錄下。

生成文件名

當文件存儲到某個子目錄後,即認為該文件存儲成功,接下來會為該文件生成一個文件名,文件名由group、存儲目錄、兩級子目錄、fileid、文件尾碼名(由客戶端指定,主要用於區分文件類型)拼接而成。

enter image de.ion here

文件同步

寫文件時,客戶端將文件寫至group內一個storage server即認為寫文件成功,storage server寫完文件後,會由後臺線程將文件同步至同group內其他的storage server。

每個storage寫文件後,同時會寫一份binlog,binlog里不包含文件數據,只包含文件名等元信息,這份binlog用於後臺同步,storage會記錄向group內其他storage同步的進度,以便重啟後能接上次的進度繼續同步;進度以時間戳的方式進行記錄,所以最好能保證集群內所有server的時鐘保持同步。

storage的同步進度會作為元數據的一部分彙報到tracker上,tracke在選擇讀storage的時候會以同步進度作為參考下載地址 。

比如一個group內有A、B、C三個storage server,A向C同步到進度為T1 (T1以前寫的文件都已經同步到B上了),B向C同步到時間戳為T2(T2 > T1),tracker接收到這些同步進度信息時,就會進行整理,將最小的那個做為C的同步時間戳,本例中T1即為C的同步時間戳為T1(即所有T1以前寫的數據都已經同步到C上了);同理,根據上述規則,tracker會為A、B生成一個同步時間戳。

Download file

客戶端upload file成功後,會拿到一個storage生成的文件名,接下來客戶端根據這個文件名即可訪問到該文件。

enter image de.ion here

跟upload file一樣,在download file時客戶端可以選擇任意tracker server。

tracker發送download請求給某個tracker,必須帶上文件名信息,tracke從文件名中解析出文件的group、大小、創建時間等信息,然後為該請求選擇一個storage用來服務讀請求。由於group內的文件同步時在後臺非同步進行的,所以有可能出現在讀到時候,文件還沒有同步到某些storage server上,為了儘量避免訪問到這樣的storage,tracker按照如下規則選擇group內可讀的storage下載地址 。

1. 該文件上傳到的源頭storage - 源頭storage只要存活著,肯定包含這個文件,源頭的地址被編碼在文件名中。 2. 文件創建時間戳==storage被同步到的時間戳 且(當前時間-文件創建時間戳) > 文件同步最大時間(如5分鐘) - 文件創建後,認為經過最大同步時間後,肯定已經同步到其他storage了。 3. 文件創建時間戳 < storage被同步到的時間戳。 - 同步時間戳之前的文件確定已經同步了 4. (當前時間-文件創建時間戳) > 同步延遲閥值(如一天)。 - 經過同步延遲閾值時間,認為文件肯定已經同步了。

小文件合併存儲

小文件合併存儲主要解決如下幾個問題:

1. 本地文件系統inode數量有限,從而存儲的小文件數量也就受到限制。 2. 多級目錄+目錄里很多文件,導致訪問文件的開銷很大(可能導致很多次IO 3. 按小文件存儲,備份與恢復的效率低

FastDFS在V3.0版本里引入小文件合併存儲下載地址 的機制,可將多個小文件存儲到一個大的文件(trunk file),為了支持這個機制,FastDFS生成的文件fileid需要額外增加16個位元組

1. trunk file id 2. 文件在trunk file內部的offset 3. 文件占用的存儲空間大小 (位元組對齊及刪除空間復用,文件占用存儲空間>=文件大小)

每個trunk file由一個id唯一標識,trunk file由group內的trunk server負責創建(trunk server是tracker選出來的),並同步到group內其他的storage,文件存儲合併存儲到trunk file後,根據其offset就能從trunk file讀取到文件。

文件在trunk file內的offset編碼到文件名,決定了其在trunk file內的位置是不能更改的,也就不能通過compact的方式回收trunk file內刪除文件的空間。但當trunk file內有文件刪除時,其刪除的空間是可以被覆用的,比如一個100KB的文件被刪除,接下來存儲一個99KB的文件就可以直接復用這片刪除的存儲空間。

HTTP訪問支持

FastDFS的tracker和storage都內置了http協議的支持,客戶端可以通過http協議來下載文件,tracker在接收到請求時,通過http的redirect機制將請求重定向至文件所在的storage上;除了內置的http協議外,FastDFS還提供了通過apache或nginx擴展模塊下載文件的支持。

enter image de.ion here

其他特性

FastDFS提供了設置/獲取文件擴展屬性的介面(setmeta/getmeta),擴展屬性以key-value對的方式存儲在storage上的同名文件(擁有特殊的首碼或尾碼),比如/group/M00/00/01/some_file為原始文件,則該文件的擴展屬性存儲在/group/M00/00/01/.some_file.meta文件(真實情況不一定是這樣,但機制類似),這樣根據文件名就能定位到存儲擴展屬性的文件。

以上兩個介面作者不建議使用,額外的meta文件會進一步“放大”海量小文件存儲問題,同時由於meta非常小,其存儲空間利用率也不高,比如100bytes的meta文件也需要占用4K(block_size)的存儲空間。

FastDFS還提供appender file的支持,通過upload_appender_file介面存儲,appender file允許在創建後,對該文件進行append操作。實際上,appender file與普通文件的存儲方式是相同的,不同的是,appender file不能被合併存儲到trunk file。

問題討論

從FastDFS的整個設計看,基本上都已簡單為原則。比如以機器為單位備份數據,簡化了tracker的管理工作;storage直接藉助本地文件系統原樣存儲文件,簡化了storage的管理工作;文件寫單份到storage即為成功、然後後臺同步,簡化了寫文件流程。但簡單的方案能解決的問題通常也有限,FastDFS目前尚存在如下問題(歡迎探討)。

數據安全性

  • 寫一份即成功:從源storage寫完文件至同步到組內其他storage的時間視窗內,一旦源storage出現故障,就可能導致用戶數據丟失,而數據的丟失對存儲系統來說通常是不可接受的。
  • 缺乏自動化恢復機制:當storage的某塊磁碟故障時,只能換存磁碟,然後手動恢複數據;由於按機器備份,似乎也不可能有自動化恢復機制,除非有預先準備好的熱備磁碟,缺乏自動化恢復機制會增加系統運維工作。
  • 數據恢復效率低:恢複數據時,只能從group內其他的storage讀取,同時由於小文件的訪問效率本身較低,按文件恢復的效率也會很低,低的恢復效率也就意味著數據處於不安全狀態的時間更長。
  • 缺乏多機房容災支持:目前要做多機房容災,只能額外做工具來將數據同步到備份的集群,無自動化機制。

存儲空間利用率

  • 單機存儲的文件數受限於inode數量
  • 每個文件對應一個storage本地文件系統的文件,平均每個文件會存在block_size/2的存儲空間浪費。
  • 文件合併存儲能有效解決上述兩個問題,但由於合併存儲沒有空間回收機制,刪除文件的空間不保證一定能復用,也存在空間浪費的問題

負載均衡

  • group機制本身可用來做負載均衡,但這隻是一種靜態的負載均衡機制,需要預先知道應用的訪問特性;同時group機制也導致不可能在group之間遷移數據來做動態負載均衡。

備註

  • 以上內容大部分為個人的理解,不能代表FastDFS的真實情況,發現問題請幫忙指出。
  • 本文的配圖均來自互聯網,Chinaunix FastDFS討論區UC技術博客,如涉及版權問題,請聯繫我刪除。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Apache和IIS分別有自己的偽靜態操作方法,那在Servers2003_IIS需要給PHP程式使用偽靜態呢?安裝rewrite插件包。 一、下載rewrite插件包,一般裡面必須有httpd.ini和Rewrite.dll,如圖: 二、一般推薦將偽靜態包放至網站根目錄下,然後在需要偽靜態的網站右 ...
  • 編譯器到底做了什麼實現的虛函數的晚綁定呢?我們來探個究竟。 編譯器對每個包含虛函數的類創建一個表(稱為V TA B L E)。在V TA B L E中,編譯器放置特定類的虛函數地址。在每個帶有虛函數的類 中,編譯器秘密地置一指針,稱為v p o i n t e r(縮寫為V P T R),指向這個對 ...
  • 適用場合: 7.3 工廠模式的適用場合 創建新對象最簡單的辦法是使用new關鍵字和具體類。只有在某些場合下,創建和維護對象工廠所帶來的額外複雜性才是物有所值。本節概括了這些場合。 7.3.1 動態實現 如果需要像前面自行車的例子一樣,創建一些用不同方式實現同一介面的對象,那麼可以使用一個工廠方法或簡 ...
  • http://blog.csdn.net/hil2000/article/details/41261267/ 一.我為什麼要學習go語言 當今已經是移動和雲計算時代,Go出現在了工業向雲計算轉型的時刻,簡單、高效、內 置併發原語和現代的標準庫讓Go語言尤其適合雲端軟體開發(畢竟它就是為此而設計的)。 ...
  • 上一篇 從引用傳遞到設計模式 (上) 的文末,提到非虛擬介面 NVI 的實現,即將虛函數聲明為保護型或私有型,藉由模板函數模式來實現 。 園友 @KillU 看的很仔細,提出了一個問題:虛函數是 private 類型,繼承可以麽? 答案是:可以 5 實現權和調用權 <Effective C++> 中 ...
  • 需求描述: 解決過程: 百度一番無果,google一番有了答案。 解決方案: android6.0(api=23)以後直接打開文件,讓系統去判斷如何處理。詳細解決方案見如下地址: http://www.jianshu.com/p/d896a09b9aca 原因分析: http://stackover ...
  • Installation Requirements: Eclipse 4.5 (Mars) or later. Java VM version 8 or later. Gocode and Go oracle. Instructions: For an Eclipse package without ...
  • 這裡來講解一下Java8 新特性中的函數式介面, 以及和Lambda 表達式的關係。看到過很多不少介紹Java8特性的文章,都會介紹到函數式介面和lambda表達式,但是都是分別介紹,沒有將兩者的關係說明清楚,在這裡,把自己的理解整理如下: 一、函數式介面: 函數式介面其實本質上還是一個介面,但是它 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...