FastDFS
文章目录
- FastDFS
-
-
- 什么是FastDFS
- 使用FastDFS的好处
- 安装
-
- 安装fastdfs依赖包libfastcommon
- 安装FastDFS
- 配置Tracker
- 配置Storage
- 配置client
- 启动tracker 和 storage
- 测试是否安装成功
- Nginx配合FastDFS
-
- 安装fastdfs-nginx-module
- 安装nginx
- 配置fastdfs-nginx-module模块
- 配置Nginx
- Nginx启动
- 测试是否安装成功
-
- Django使用FastDFS
-
-
-
- 项目fdfs最终文件目录树展示
- 1.创建utils包下,再创建storage.py文件,这个文件用来重写Django的文件存储类
-
- FastDFS实现上传资源排重
-
-
- 安装
- 1.安装hash数据库FastDHT的依赖库
- 2.安装libevent
- 3.FastDHT安装
- 4.配置FastDHT
- 5.启动FastDHT
-
- 扩展:
-
-
什么是FastDFS
简单说下,FastDFS就是由tracker和storager组成的
tracker:客户端先访问tracker,返回可用的storager的IP和port,然后把文件上传到对应的storager,简单来说就是起到分配,追踪的作用,同时还会接收storager的状态
storager:就是存储文件的地方,文件上传后就会返回一个file_id,file_id可以代表文件的位置,(是通过对文件内容进行hash算法决定的,所以对于相同内容可以不用重复存储,不过要配合FastDHT实现文件去重存储,最下面有讲)

使用FastDFS的好处
- 海量存储,存储容量扩展方便(只需直接添加Storage)
- 可结合nginx提高网站访问图片的效率
- 相同的文件只会出现一份
安装
提示:安装前要有gcc环境(一般都自带)
安装fastdfs依赖包libfastcommon
1.获取,解压安装包
wget https://github.com/happyfish100/libfastcommon/archive/V1.0.38.tar.gz
解压安装包:tar -zxvf V1.0.38.tar.gz
- 编译安装
进入目录:cd libfastcommon-1.0.38
执行编译:./make.sh
安装:sudo ./make.sh install
如果有问题,可能要安装 gcc
安装FastDFS
1.获取,解压安装包
wget https://github.com/happyfish100/fastdfs/archive/V5.11.tar.gz
解压安装包:tar -zxvf V5.11.tar.gz
2.编译安装
进入目录:cd fastdfs-5.11
执行编译:./make.sh
安装:./make.sh install
配置Tracker
1.配置文件
sudo cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
2.在/home/python/目录中创建存放tracker的目录
mkdir –p /home/python/fastdfs/tracker
3.编辑/etc/fdfs/tracker.conf配置文件
sudo vim /etc/fdfs/tracker.conf
修改:
# tracker存储data和log的跟路径,必须提前创建好
base_path=/home/python/fastdfs/tracker
# http端口,需要和nginx相同
http.server_port=8888
配置Storage
1.配置文件
sudo cp /etc/fdfs/tracker.conf.sample /etc/fdfs/storage.conf
2.在/home/python/目录中创建存放tracker的目录
mkdir –p /home/python/fastdfs/storage
3.编辑/etc/fdfs/storage.conf配置文件
sudo vim /etc/fdfs/storage.conf
修改:
# tracker存储data和log的跟路径,必须提前创建好
base_path=/home/python/fastdfs/storage
# 存储路径个数,需要和store_path个数匹配
store_path_count=1
#如果为空,则使用base_path
store_path0=/home/python/fastdfs/storage
#配置该storage监听的tracker的ip和port
tracker_server=自己的IP:22122
# http端口,需要和nginx相同
http.server_port=8888
配置client
1.client配置文件
sudo cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf
2.编辑/etc/fdfs/client.conf配置文件
sudo vim /etc/fdfs/client.conf
修改内容:
base_path=/home/python/fastdfs/tracker
tracker_server=自己ubuntu虚拟机的ip地址:22122
启动tracker 和 storage
# tracker启动
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start
# storage启动
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf start
# 监控进程 (选)
/usr/bin/fdfs_monitor /etc/fdfs/client.conf
测试是否安装成功
1.上传文件测试:
fdfs_upload_file /etc/fdfs/client.conf 要上传的图片文件
返回类似group1/M00/00/00/rBIK6VcaP0aARXXvAAHrUgHEviQ394.jpg的文件id则说明文件上传成功
Nginx配合FastDFS
安装fastdfs-nginx-module
# 下载fastdfs-nginx-module安装包
wget https://github.com/happyfish100/fastdfs-nginx-module/archive/V1.20.tar.gz
解压fastdfs-nginx-module:
tar -xvf V1.20.tar.gz
安装nginx
1.安装PCRE(2选1)
查看是否安装
rpm -qa pcre
直接命令安装
apt-get update
apt-get install libpcre3 libpcre3-dev openssl libssl-dev libperl-dev
下载安装包安装
cd /usr/local/src/
# 获取安装包
wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
# 解压
tar zxvf pcre-8.35.tar.gz
# 进入目录
cd pcre-8.35
# 编译安装
./configure
make && make install
- 安装nginx
# 获取安装包
wget http://nginx.org/download/nginx-1.6.2.tar.gz
# 安装前配置,加载fastdfs-nginx-module模块
sudo ./configure --prefix=/usr/local/nginx/ --add-module=fastdfs-nginx-module-master解压后的目录的绝对路径/src
# 编译
make
# 安装
make install
如果已经安装了nginx,直接安装fastdfs-nginx-module模块
mv fastdfs-nginx-module /usr/local/webserver/nginx/
# nginx安装包目录下执行
./configure --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --add-module=fastdfs-nginx-module的绝对路径/src
# 编译
make
# 如果make错误
# 修改 fastdfs-nginx-module/src/config
ngx_addon_name=ngx_http_fastdfs_module
if test -n "${ngx_module_link}"; then
ngx_module_type=HTTP
ngx_module_name=$ngx_addon_name
ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
ngx_module_libs="-lfastcommon -lfdfsclient"
ngx_module_srcs="$ngx_addon_dir/ngx_http_fastdfs_module.c"
ngx_module_deps=
CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 -DFDFS_OUTPUT_CHUNK_SIZE='256*1024' -DFDFS_MOD_CONF_FILENAME='\"/etc/fdfs/mod_fastdfs.conf\"'"
. auto/module
else
HTTP_MODULES="$HTTP_MODULES ngx_http_fastdfs_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_fastdfs_module.c"
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
CORE_LIBS="$CORE_LIBS -lfastcommon -lfdfsclient"
CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 -DFDFS_OUTPUT_CHUNK_SIZE='256*1024' -DFDFS_MOD_CONF_FILENAME='\"/etc/fdfs/mod_fastdfs.conf\"'"
fi
配置fastdfs-nginx-module模块
1.配置mod-fastdfs.conf,并拷贝到/etc/fdfs文件目录下
cd fastdfs-nginx-module-1.20/src/
cp mod_fastdfs.conf /etc/fdfs
2.进入/etc/fdfs修改mod-fastdfs.conf:
vim /etc/fdfs/mod_fastdfs.conf
修改:
connect_timeout=10
base_path=/home/python/fastdfs
tracker_server=10.122.149.211:22122 #tracker的ip地址
url_have_group_name=true #url是否包含group名称
storage_server_port=23000 #需要和storage配置的相同
store_path_count=1 #存储路径个数,需要和store_path个数匹配
store_path0=/home/python/fastdfs/storage #storage的位置
配置Nginx
vim /usr/local/nginx/conf/nginx.conf
在http部分中添加配置信息如下:
server {
listen 8888;
server_name localhost;
location ~/group[0-9]/ {
ngx_fastdfs_module;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
意思是当访问IP:8888/group[0-9]/…,nginx就会调用ngx_fastdfs_module模块,通过file_id,即:group…/…/ ,找到文件并返回
最后需要拷贝之前安装FastDFS解压目录中的http.conf和mime.types:
cd /usr/local/src/fastdfs-5.11/conf
cp mime.types http.conf /etc/fdfs/
Nginx启动
sudo /usr/local/nginx/sbin/nginx
如果nginx的报错ERROR - file: …/storage/trunk_mgr/trunk_shared.c, line: 177, “Permission denied” can’t be accessed
在nginx.conf前面加上user root
![]()
搭建FastDFS+FastDHT完成去重存储(含Django使用)FastDFSDjango使用FastDFS
测试是否安装成功
1.启动tracker、storage、nginx服务
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf start
sudo /usr/local/nginx/sbin/nginx
也可以用systemctl启动
systemctl start fdfs_trackerd.service
systemctl start fdfs_storaged.service
systemctl start nginx.service
2.上传文件
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf <local_filename>文件路径
返回:
类似group1/M00/00/00/rBIK6VcaP0aARXXvAAHrUgHEviQ394.jpg
3.在浏览器中访问
格式:nginx配置的IP:8888/返回的文件id
127.0.0.1:8888/group1/M00/00/00/rBIK6VcaP0aARXXvAAHrUgHEviQ394.jpg
4.删除文件
/usr/bin/fdfs_delete_file /etc/fdfs/client.conf <file_id>
/usr/bin/fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/rBIK6VcaP0aARXXvAAHrUgHEviQ394.jpg
再次访问就没有了,返回404页面
Django使用FastDFS
项目fdfs最终文件目录树展示
utils
└── fdfs
----- ├── client.conf
----- ├── init.py
----- └── storage.py
1.创建utils包下,再创建storage.py文件,这个文件用来重写Django的文件存储类
storage.py下,FDFSStorage类继承django自带的文件存储类,重写_open,_save, exists,url方法。
- open:打开文件方法
- save :admin中保存文件时调用的方法,保存文件时,加上上传文件到FastDFS操作。
- exists:判断这个文件名是否存在,原来是防止覆盖的,用了fastFDS不会存在这个问题
- url:在调用url方法,返回数据表中文件的file_id,这里加上nginx的ip,就等于直接访问图片了
from django.core.files.storage import Storage
from django.conf import settings
from fdfs_client.client import Fdfs_client,get_tracker_conf
# 重写Django内置的文件存储类
class FDFSStorage(Storage):
'''fast dfs文件存储类'''
def __init__(self, client_conf=None, base_url=None):
'''初始化'''
if client_conf is None:
# client_conf = settings.FDFS_CLIENT_CONF
client_conf = get_tracker_conf(settings.FDFS_CLIENT_CONF)
self.client_conf = client_conf
if base_url is None:
base_url = settings.FDFS_URL
self.base_url = base_url
def _open(self, name, mode='rb'):
'''打开文件时使用'''
pass
def _save(self, name, content):
'''保存文件时使用'''
# name:你选择上传文件的名字 test.jpg
# content:包含你上传文件内容的File对象
# 创建一个Fdfs_client对象
client = Fdfs_client(self.client_conf)
# 取后缀
str = name.split(".")
file_ext_name = str[-1]
# 上传文件到fast dfs系统中
res = client.upload_by_buffer(content.read(), file_ext_name)
# 返回一个字典
# dict
# {
# 'Group name': group_name,
# 'Remote file_id': remote_file_id,
# 'Status': 'Upload successed.',
# 'Local file name': '',
# 'Uploaded size': upload_size,
# 'Storage IP': storage_ip
# }
if res.get('Status') != 'Upload successed.':
# 上传失败
raise Exception('上传文件到fast dfs失败')
# 获取返回的文件ID
filename = res.get('Remote file_id')
print(filename)
return filename.decode()
# 1.jpg
def exists(self, name):
'''Django判断文件名是否可用'''
return False
def url(self, name):
'''返回访问文件的url路径'''
return self.base_url + name
2.把的之前下载FastDFS文件夹下配置的client.py文件复制到fdfs目录下
修改:
- tracker_server = trackerip:22122
- base_path = /home/python/fastdfs/ 这个放到fastdfs文件夹下
cp /etc/fdfs/client.conf 项目文件夹/utils/
3.配置项目文件夹setting.py
# 设置Django的文件存储类
DEFAULT_FILE_STORAGE='utils.fdfs.storage.FDFSStorage'
# 设置fdfs使用的client.conf文件路径
FDFS_CLIENT_CONF='./utils/fdfs/client.conf'
# 设置fdfs存储服务器上nginx的IP和端口号
FDFS_URL='http://192.168.40.131:8888/'
FastDFS实现上传资源排重
FastDFS本身支持文件的排重处理机制,就是同样的文件只存储一份。但需要FastDHT作为文件hash的索引存储。
排重原理上面已经讲了,这里再细致一下:
FastDFS的storager每次均计算上传文件的hash值,然后从FastDHT服务器上进行查找比对,如果没有返回,说明不存在相同内容的文件,则写入hash,并将文件内容保存,返回file_id。
如果有返回,则建立一个新的文件链接,对已有文件进行软链接,不保存文件,返回该file_id。
安装
注意:
我安装环境是Ubuntu 16.04 ,可能有些目录或者命令的改变,下面也会有说
1.安装hash数据库FastDHT的依赖库
官网:http://www.oracle.com/technology/software/products/berkeley-db/index.html
github官网下载: https://github.com/berkeleydb/libdb/
# berkeleydb 4.7.25以上
tar zxf libdb-master
cd libdb-master/build-unix
# 选择安装目录
sudo mkdir /usr/local/berkeleydb5.3.21
../dist/configure --prefix=/usr/local/berkeleydb5.3.21
# 编译安装
make && make install
2.安装libevent
sudo apt-get update
apt-get install libevent libvent-devel
3.FastDHT安装
github官网下载: https://github.com/happyfish100/fastdht/
tar xzf fastdht-master.zip
cd fastdht-master
# 关联刚刚下载的依赖库(如果是pip下载的不需要)
# ubuntu16.04 中没有chkconfig命令,systemctl代替chkconfig
# 没有这个目录/etc/rc.d/init.d,改为 /etc/init.d/
vim make.sh
修改:
27 CFLAGS='-Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I/usr/local/berkeleydb5.3.21/include/ -L/usr/local/berkeleydb5.3.21/lib/'
....
137 cp -f init.d/fdhtd /etc/init.d/
138 /bin/systemctl load fdhtd
# 编译安装
./make.sh && ./make.sh install
可能会出现一个错误,docs安装不成功,如果是这个可以不管,应该是些文档
4.配置FastDHT
注意:第三步安装完后/etc/fdht/文件夹下有3个conf文件,如果没有就到上面安装包的conf文件中复制到/etc/fdht/目录下
fdhtd.conf
fdht_servers.conf
fdht_client.conf
1. 创建文件夹/fastdht
mkdir home/python/fastdfs/fastdht
2. 修改fdhtd.conf文件
vim /etc/fdht/fdhtd.conf
base_path=home/python/fastdfs/fastdht(第一步创建的文件夹)
3. 修改fdht_servers.conf文件
# 一般配置2台,防止单点
group_count = 1
group0 = fastdht所在主机ip1:11411
group0 = fastdht所在主机ip2:11411
4. 修改fdht_client.conf文件
vim /etc/fdht/fdht_client.conf
keep_alive=1
base_path= home/python/fastdfs/fastdht(第一步创建的文件夹)
5.复制一份/etc/fdht/fdht_servers.conf到/etc/fdfs/
cp /etc/fdht/fdht_servers.conf /etc/fdfs/
6.修改之前的etc/fdfs/storage.conf文件
# 检测文件是否重复
check_file_duplicate=1
# 命名空间FastDFS
key_namespace=FastDFS
# 长连接配置
keep_alive=1
# 导入之前/etc/fdht/fdht_servers.conf
#include /etc/fdfs/fdht_servers.conf
配置文件:
5.启动FastDHT
1、启动命令:
sudo fdhtd /etc/fdht/fdhtd.conf
2、重启storager
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
或者:
systemctl start fdfs_storaged.service
3、测试是否成功
# 用下面命令上传同一个文件2次
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf <file>
# 进入storager目录下
cd fastdfs/storage/data/00/00
# 使用ls -al命令
wKgog16Jt22AJj8PAAAgnQSk244394.jpg -> /home/liang/work/Django/fastdfs/storage/data/00/00/wKgog16Jt26AfQG2AAAgnaeGwNQ726.jpg
有个箭头指向一个文件,代表软链接成功
如果还有问题,也可以自己看看安装包里的INSTALL文件
可以设置开机自启:
# 把启动命令加到这个配置文件下
vim /etc/rc.local
....
/usr/local/bin/fdhtd /etc/fdht/fdhtd.conf
#加上执行权限
chmod +x /etc/rc.local
扩展:
FastDFS合并存储原理分析: 就是几个小文件存储成一个大文件
https://blog.csdn.net/hfty290/article/details/42026215