分散式檔案系統之 FastDFS
阿新 • • 發佈:2020-12-24
### [FastDFS 百度百科](https://baike.baidu.com/item/fastdfs/5609710?fr=aladdin)
> `FastDFS` 是一個開源的輕量級分散式檔案系統,它對檔案進行管理,功能包括:檔案儲存、檔案同步、檔案訪問(檔案上傳、檔案下載)等,解決了大容量儲存和負載均衡的問題。特別適合以檔案為載體的線上服務,如相簿網站、視訊網站等等。
>`FastDFS` 為網際網路量身定製,充分考慮了冗餘備份、負載均衡、線性擴容等機制,並注重高可用、高效能等指標,使用 `FastDFS` 很容易搭建一套高效能的檔案伺服器叢集提供檔案上傳、下載等服務。
### FastDFS 簡介
`FastDFS` 服務端有兩個角色:**跟蹤器**(`tracker`)和**儲存節點**(`storage`)。跟蹤器主要做排程工作,在訪問上起負載均衡的作用;儲存節點儲存檔案,完成檔案管理的所有功能。
`FastDFS` 同時對檔案的 `metadata` 進行管理。所謂檔案的 `metadata` 就是檔案的相關屬性,以鍵值對方式表示,如:width=1024,其中的 `key` 為 width,`value` 為 1024。檔案 `metadata` 是檔案屬性列表,可以包含多個鍵值對。
跟蹤器和儲存節點都可以由一臺或多臺伺服器構成。跟蹤器和儲存節點中的伺服器均可以隨時增加或下線而不會影響線上服務。其中跟蹤器中的所有伺服器都是對等的,可以根據伺服器的壓力情況隨時增加或減少。
為了支援大容量,儲存節點(伺服器)採用了 **分卷**(或分組)的組織方式。儲存系統由一個或多個卷組成,卷與卷之間的檔案是相互獨立的,所有卷的檔案容量累加就是整個儲存系統中的檔案容量。一個卷可以由一臺或多臺儲存伺服器組成,一個卷下的儲存伺服器中的檔案都是相同的,卷中的多臺儲存伺服器起到了冗餘備份和負載均衡的作用。
在卷中增加伺服器時,同步已有的檔案由系統自動完成,同步完成後,系統自動將新增伺服器切換到線上提供服務。
當儲存空間不足或即將耗盡時,可以動態添加捲。只需要增加一臺或多臺伺服器,並將它們配置為一個新的卷,這樣就擴大了儲存系統的容量。
`FastDFS` 中的檔案標識分為兩個部分:**卷名** 和 **檔名**,二者缺一不可。
### 檔案互動過程
#### 上傳互動過程
1. client 詢問 `tracker` 上傳到的 `storage`,不需要附加引數;
2. `tracker` 返回一臺可用的 `storage`;
3. client 直接和 `storage` 通訊完成檔案上傳。
#### 下載互動過程
1. client 詢問 `tracker` 下載檔案的 `storage`,引數為檔案標識(卷名和檔名);
2. `tracker` 返回一臺可用的 `storage`;
3. client 直接和 `storage` 通訊完成檔案下載。
### FastDFS 為什麼要結合 Nginx
我們在使用 `FastDFS` 部署一個分散式檔案系統的時候,通過 `FastDFS` 的客戶端 API 來進行檔案的上傳、下載、刪除等操作。同時通過 `FastDFS` 的 HTTP 伺服器來提供 HTTP 服務。但是 `FastDFS` 的 HTTP 服務較為簡單,無法提供負載均衡等高效能的服務,我們使用 `FastDFS` 的 `Nginx` 模組來彌補這一缺陷。
`FastDFS` 通過 `tracker` 伺服器,將檔案放在 `Storage` 伺服器儲存,但是同組之間的伺服器需要複製檔案,有延遲的問題。假設 `tracker` 伺服器將檔案上傳到了 192.168.1.100,檔案 ID 已經返回客戶端,這時後臺會將這個檔案複製到 192.168.1.100,如果複製沒有完成,客戶端就用這個 ID 在 192.168.1.100 取檔案,肯定會出現錯誤。而 `fastdfs-nginx-module` 可以重定向連線到源伺服器取檔案,避免客戶端由於複製延遲的問題出現錯誤。
### 基於 Docker 安裝 FastDFS
所需全部環境配置檔案已上傳至百度網盤。
> 提取連結:https://pan.baidu.com/s/1ptM7psDH9IJuH4P7Cd0L9A
> 提取碼:qdxe
在 Linux 伺服器上建立 `/usr/local/docker/fastdfs` 目錄和 `/usr/local/docker/fastdfs/environment` 目錄
**目錄說明:**
- `/usr/local/docker/fastdfs`:用於存放 `docker-compose.yml` 檔案和 `FastDFS` 的資料卷。
- `/usr/local/docker/fastdfs/environment`:用於存放 `Dockerfile` 檔案和剛剛提取的環境檔案。
**注意**:因為 Shell 建立後是無法直接使用的,所以將 `entrypoint.sh` 檔案拷貝到伺服器目錄裡以後,需要賦予執行的許可權,執行以下命令:
```sh
$ chmod +x entrypoint.sh
```
#### 各環境配置檔案說明
##### tracker.conf
`FastDFS` 跟蹤器配置,容器中路徑為:`/etc/fdfs`,修改為:
```conf
base_path=/fastdfs/tracker
```
##### storage.conf
`FastDFS` 儲存配置,容器中路徑為:`/etc/fdfs`,修改為:
```conf
base_path=/fastdfs/storage
store_path0=/fastdfs/storage
tracker_server=192.168.1.100:22122
http.server_port=8888
```
##### client.conf
`FastDFS` 客戶端配置,容器中路徑為:`/etc/fdfs`,修改為:
```conf
base_path=/fastdfs/tracker
tracker_server=192.168.1.100:22122
```
##### config
`fastdfs-nginx-module` 配置檔案,容器中路徑為:`/usr/local/src/fastdfs-nginx-module/src`,修改為:
```text
# 修改前
CORE_INCS="$CORE_INCS /usr/local/include/fastdfs /usr/local/include/fastcommon/"
CORE_LIBS="$CORE_LIBS -L/usr/local/lib -lfastcommon -lfdfsclient"
# 修改後
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
CORE_LIBS="$CORE_LIBS -L/usr/lib -lfastcommon -lfdfsclient"
```
##### mod_fastdfs.conf
`fastdfs-nginx-module` 配置檔案,容器中路徑為:`/usr/local/src/fastdfs-nginx-module/src`,修改為:
```text
connect_timeout=10
tracker_server=192.168.1.100:22122
url_have_group_name = true
store_path0=/fastdfs/storage
```
##### nginx.conf
`Nginx` 配置檔案,容器中路徑為:`/usr/local/src/nginx-1.13.6/conf`,修改為:
```text
user root;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8888;
server_name localhost;
location ~/group([0-9])/M00 {
ngx_fastdfs_module;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
```
#### 建立 docker-compose.yml
```yaml
version: '3.1'
services:
fastdfs:
build: environment
restart: always
container_name: fastdfs
volumes:
- ./storage:/fastdfs/storage
network_mode: host
```
#### 建立 Dockerfile
```dockerfile
FROM ubuntu:xenial
MAINTAINER [email protected]
# 更新資料來源
WORKDIR /etc/apt
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse' > sources.list
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse' >> sources.list
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse' >> sources.list
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> sources.list
RUN apt-get update
# 安裝依賴
RUN apt-get install make gcc libpcre3-dev zlib1g-dev --assume-yes
# 複製工具包
ADD fastdfs-5.11.tar.gz /usr/local/src
ADD fastdfs-nginx-module_v1.16.tar.gz /usr/local/src
ADD libfastcommon.tar.gz /usr/local/src
ADD nginx-1.13.6.tar.gz /usr/local/src
# 安裝 libfastcommon
WORKDIR /usr/local/src/libfastcommon
RUN ./make.sh && ./make.sh install
# 安裝 FastDFS
WORKDIR /usr/local/src/fastdfs-5.11
RUN ./make.sh && ./make.sh install
# 配置 FastDFS 跟蹤器
ADD tracker.conf /etc/fdfs
RUN mkdir -p /fastdfs/tracker
# 配置 FastDFS 儲存
ADD storage.conf /etc/fdfs
RUN mkdir -p /fastdfs/storage
# 配置 FastDFS 客戶端
ADD client.conf /etc/fdfs
# 配置 fastdfs-nginx-module
ADD config /usr/local/src/fastdfs-nginx-module/src
# FastDFS 與 Nginx 整合
WORKDIR /usr/local/src/nginx-1.13.6
RUN ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src
RUN make && make install
ADD mod_fastdfs.conf /etc/fdfs
WORKDIR /usr/local/src/fastdfs-5.11/conf
RUN cp http.conf mime.types /etc/fdfs/
# 配置 Nginx
ADD nginx.conf /usr/local/nginx/conf
COPY entrypoint.sh /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
WORKDIR /
EXPOSE 8888
CMD ["/bin/bash"]
```
#### 啟動容器
```sh
$ docker-compose up -d
```
#### 測試上傳
```sh
# 互動式進入容器
$ docker exec -it fastdfs /bin/bash
# 上傳測試檔案
$ /usr/bin/fdfs_upload_file /etc/fdfs/client.conf /usr/local/src/fastdfs-5.11/INSTALL
# 伺服器反饋的上傳後地址
group1/M00/00/00/wKhLi1oHVMCAT2vrAAAeSwu9TgM3976771
```
#### 上傳後文件地址
```text
http://192.168.75.128:8888/group1/M00/00/00/wKhLi1oHVMCAT2vrAAAeSwu9TgM3976771
```
- 文章作者:彭超
- 本文首發於個人部落格:[https://antoniopeng.com](https://antoniopeng.com)
- 版權宣告:本部落格所有文章除特別宣告外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 [彭超的部落格](https://antoniopeng