分佈式文件系統及FastDFS

一、前言

今天來談談分佈式文件系統,側重點是文件系統,分佈式稍微帶一下。而後聊下我用的FastDFS的例子。linux

二、從小需求開始

個人博客的編輯器用的是markdown,它內嵌了一個文件上傳功能,不事後端文件管理要本身的寫。
最開始直接用SpringMVC接收上傳文件,直接扔服務器新建的upload文件夾下。但問題很快就出現了,上傳同名文件會衝突,順手加個時間戳好像能夠解決問題,但我總感受重複文件最後只存一次纔是最好的,但靠文件名是無法判斷重複的,加上大小,類型也不夠,查了很多資料,考慮到本身寫沒足夠的精力,最後決定用現成的FastDFS,學習別人是怎麼作的。
由上,咱們有這麼幾個問題: git

  1. 文件存哪?
  2. 怎麼存?
  3. 如何去重?

帶着這幾個問題來看看文件系統的設計。github

三、文件系統

3.1 什麼是文件系統。

若是是windows,按win+E打開資源管理器,資源指是什麼,是文件,文件管理器,也就是文件系統。在Linux,Mac,Android,iOS之上,全部應用都是由文件系統所管理。操做系統中負責管理和存儲文件信息的軟件機構稱爲文件系統。算法

3.2 文件系統的分類

文件系統從架構上能夠分爲兩類:
1.本地文件系統
linux的ext3,ext4 windows的FAT32 NTFS ..
以下是window下格式化硬盤時能夠選擇的文件系統。注意下其中有個參數分配單元大小,稍後討論。
數據庫

2.分佈式文件系統
分佈式文件又能夠分爲兩種, windows

一是通用分佈式文件系統
將windows或linux多臺機器進分佈式架構即是一個通用分佈式文件系統了,由於通用,使用起來很方便,但性能就差點。應用端能夠mount(掛載)使用。典型表明:lustre、MooseFS. 後端

另一個即是專用分佈式文件系統了,基本都是基於GFS的思想,,文件上傳後不能修改。不能mount使用,須要使用專有API對文件進行訪問,也可稱做分佈式文件存儲服務。典型表明:GFS、FastDFS、HDFS、TFS。緩存

3.2 文件的存儲

文件系統最基本的功能即是存儲了,存儲方式分爲兩種:安全

1.獨立文件形式存儲
即以N級目錄+文件的方式存儲文件,win,linux,mac..都是這種方式,這種方式查詢很快,根據路徑天然就能夠找到文件。 服務器

可是,在前面的圖片中談到了一個參數分配單元大小,值是4K。咱們看幾個文件的屬性:


其中的大小是文件的大小,但佔用空間卻比實際大小大,並且正好是4k的倍數,沒錯文件系統中文件大小的單位是固定的,又稱爲文件簇,這個指文件分配的最小空間,這個值設小能夠節省空間但訪問速度會變慢,反之則浪費空間,但能夠加快訪問速度。有人會建議若是硬盤空間足夠可在格式化硬盤時選擇分配單元大小爲64k,從而提升系統性能。

若是都是大文件,浪費的空間能夠不計,但若是都是2k的小文件呢,100w這種小文件實際大小不到2g,但佔用空間近4g,通常空間被浪費掉了。因此有了另外一種存儲方式。

2.塊存儲
若是將100w小文件寫入壓縮包,裏面雖然是100w文件,但在系統中實際上是一個壓縮文件,這樣它所佔用的空間是實際大小了,若是是壓縮存儲還會更小。這種方式咱們稱之爲塊存儲。

這二者各有優劣,塊存儲節省空間,但想訪問其中一個就比較麻煩,文件存儲訪問很快,但海量小文件狀況下空間浪費就大了。

3.兩者的應用場景
分佈式文件系統FastDFS使用的是文件存儲,應用於分佈式訪問,建議用於>4k的文件訪問即是這個道理;

但另一個HDFS使用的是塊存儲,它所應用的場景是分佈式計算,其實須要的是一次性加載數以百萬的文件到MapReduce服務器中運算,若是一個個下載確定不如直接一個壓縮包過來。

3.2 文件的去重

通常咱們使用的操做系統中,只會限制重複文件名,並不會肯定兩個文件的數據是否同樣。
但當文件開始多起來,好比百度網盤,如今一個藍光電影能有十幾g,若是網友每人傳一份,百來我的就能佔1t,雖然硬盤不值錢,但億萬級的文件堆起來也開銷很多,若是能去重,那隻用維持一份數據就行了。

文件去重,也是須要找到一個惟一標識來定位文件。hash是一個比較好的選擇。
Hash 即散列,當數據足夠散,一個點只有一份數據,不出現hash衝突,這不就是惟一了。
hash值能夠用本身定義計算,但更一般的作法是用MD5,SHA1這樣成熟的hash算法。
MD5之類不只僅是用來加密,也早就大量用於文件防僞,固然hash的碰撞仍然存在,通過精心設計,徹底能夠僞造出MD5相同,但數據不一樣文件,從而帶來安全問題,畢竟這個文件若是是手機銀行呢。

3.4 秒傳的祕密

百度網盤秒傳原理

4、分佈式文件系統-FastDFS

文件存儲問題解決了,下面就是分佈式的東西的。
關於分佈式的架構思路請參考下個人另一篇文章,這裏就不累述了。

如下是FastDFS架構圖

Tracker:負載均衡服務器。
Storage:存儲服務器。
這裏簡單的介紹下它的一些流程。

4.1 上傳下載流程

  • 上傳
  1. client詢問tracker上傳到的storage;
  2. tracker返回一臺可用的storage;
  3. client直接和storage通訊完成文件上傳,storage返回文件ID。
  • 下載
  1. client詢問tracker能夠下載指定文件的storage,參數爲文件ID(組名和文件名);
  2. tracker返回一臺可用的storage;
  3. client直接和storage通訊完成文件下載。

上傳文件時,文件ID由storage server生成並返回給client
文件ID包含了組名和文件名,storage server能夠直接根據該文件名定位到文件
一個文件ID示例:

4.2 同步機制

採用binlog文件記錄文件上傳、刪除等操做,根據binlog進行文件同步;

storage生成的文件名中,包含源頭storage IP地址和文件建立時間戳;
源頭storage定時向tracker報告同步狀況,包括向目標服務器同步到的文件時間戳;
tracker收到storage的同步報告後,找出該組內每臺storage被同步到的時間戳(取最小值),
做爲storage屬性保存到內存中;

client詢問tracker有哪些storage能夠下載指定文件時,tracker返回知足以下四個條件之一的storage:
1 (當前時間 -文件建立時間戳) > 同步延遲閥值(如一天);
2 文件建立時間戳 < Storage被同步到的時間戳;
3 文件建立時間戳==Storage被同步到的時間戳 且(當前時間 -文件建立時間戳) > 文件同步最大時間(如5分鐘);
4 該文件上傳到的源頭storage。

因爲文件不要求強一致性,因此同步方案要求不高,徹底不必使用paxos之類的一致性算法,這是與分佈式緩存,數據庫等差異較大的地方

4.3 FastDFS去重機制

去重機制也就是hash了,一個是本身實現的hash,另一個是MD5。
Hash: 4*32位hash code
MD5:

需安裝FastDHT(分佈式哈希系統 ):使用 Berkeley DB 作數據存儲,使用 libevent 作網絡IO處理,提供 Java 版的客戶端接口包。適合用來存儲用戶在線、會話等小數據量信息。
經過hash->文件路徑來標識文件,後面上傳的文件,若是已經存在相同內容的文件,則採用符號鏈接的方式,指向原始文件。

缺陷:咱們看到的是FastDFS採用服務端去重的機制,相比網盤的秒傳機制效率低。因此個人網站目前沒有使用這一機制,更考慮作個網盤相似的插件,本地去重,這個排後吧。之後能夠玩玩。

五 擴展參考

做者:初龍

原文連接:https://chulung.com/article/distributed-file-system-and-fastdfs

本文由MetaCLBlog於2017-07-17 09:06:11自動同步至cnblogs

本文基於 知識共享-署名-非商業性使用-禁止演繹 4.0 國際許可協議發佈,轉載必須保留署名及連接。

相關文章
相關標籤/搜索