分布式文件系統及FastDFS


1、前言

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

2、從小需求開始

我的博客的編輯器用的是markdown,它內嵌了一個文件上傳功能,不過后端文件管理要自己的寫。
最開始直接用SpringMVC接收上傳文件,直接扔服務器新建的upload文件夾下。但問題很快就出現了,上傳同名文件會沖突,順手加個時間戳好像可以解決問題,但我總感覺重復文件最后只存一次才是最好的,但靠文件名是沒法判斷重復的,加上大小,類型也不夠,查了不少資料,考慮到自己寫沒足夠的精力,最后決定用現成的FastDFS,學習別人是怎么做的。
由上,我們有這么幾個問題:

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

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

3、文件系統

3.1 什么是文件系統。

如果是windows,按win+E打開資源管理器,資源指是什么,是文件,文件管理器,也就是文件系統。在Linux,Mac,Android,iOS之上,所有應用都是由文件系統所管理。操作系統中負責管理和存儲文件信息的軟件機構稱為文件系統。

3.2 文件系統的分類

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

2.分布式文件系統
分布式文件又可以分為兩種,

一是通用分布式文件系統
將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 秒傳的秘密

百度網盤秒傳原理

四、分布式文件系統-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 國際許可協議發布,轉載必須保留署名及鏈接。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM