架构&服务端系统架构

使用fastDFS搭建分布式文件存储系统

2019-11-07  本文已影响0人  iDevOps
什么是fastDFS

FastDFS是用c语言编写的一款开源的分布式文件系统,它是由淘宝资深架构师余庆编写并开源。FastDFS专为互联 网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很 容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。 为什么要使用fastDFS呢? 上边介绍的NFS、GFS都是通用的分布式文件系统,通用的分布式文件系统的优点的是开发体验好,但是系统复杂 性高、性能一般,而专用的分布式文件系统虽然开发体验性差,但是系统复杂性低并且性能高。fastDFS非常适合 存储图片等那些小文件,fastDFS不对文件进行分块,所以它就没有分块合并的开销,fastDFS网络通信采用 socket,通信速度很快。

fastDSF工作原理

FastDFS架构包括 Tracker server和Storageserver。客户端请求Tracker server进行文件上传、下载,通过Tracker server调度最终由Storage server完成文件上传和下载。


fastDSF工作原理
文件上传流程
文件上传流程

客户端上传文件后存储服务器将文件ID返回给客户端,此文件ID用于以后访问该文件的索引信息。文件索引信息 包括:组名,虚拟磁盘路径,数据两级目录,文件名。
/group1/M00/00/00/wKgFiF3DfWuANNz4AAAlzCrdDj8028.png

文件下载流程
文件下载流程

tracker根据请求的文件路径即文件ID 来快速定义文件。
1.通过组名tracker能够很快的定位到客户端需要访问的存储服务器组是group1,并选择合适的存储服务器提供客 户端访问。
2.存储服务器根据“文件存储虚拟磁盘路径”和“数据文件两级目录”可以很快定位到文件所在目录,并根据文件名找到 客户端需要访问的文件。

安装Tracker端
yum install gcc-c++  libevent
# 安装成功后会自动将库文件拷贝到/usr/lib64下
tar -zxvf libfastcommonV1.0.7.tar.gz -C /usr/local
cd libfastcommon-1.0.7
make.sh
make.sh install

# 由于 FastDFS 程序引用 usr/lib 目录所以需要将/usr/lib64 下的库文件拷贝至/usr/lib 下
cp /usr/lib64/libfastcommon.so /usr/lib
#安装tracker
tar -zxvf FastDFS_v5.05.tar.gz -C /usr/local
cd FastDFS
make.sh
make.sh install
# 安装成功后将安装目录下的文件拷贝到/etc/fdfs
http.conf
mime.types
cp /etc/fdfs/tracker.conf.sample tracker.conf
vi tracker.conf
base_path=/home/fastdfs
http.server_port=80
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
安装Storage端
cp /etc/fdfs/storage.conf.sample storage.conf
# 修改配置
group_name=group1
base_path=/home/fastdfs
# 如果多个挂载磁盘则定义多个store_path
store_path0=/home/fastdfs/fdfs_storage
store_path2=...
# 配置tracker服务器ip,如果多个则配置多个tracker
tracker_server=192.168.5.134:22122
tracker_server=192.168.5.135:22122
# http端口
http.server_port=80
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
和nginx整合

在 storage server 上安装 nginx 的目的是对外通过 http 访问 storage server 上的文件。使用 nginx 的模块 FastDFS-nginx-module 的作用是通过 http 方式访问 storage 中的文件,当 storage 本机没有要找的文件时向源 storage 主机代理请求文件。

tar -zxvf fastdfs-nginx-module_v1.16.tar.gz
cd fastdfs-nginx-module/src
# 修改配置文件 /usr/local改为/usr
ngx_addon_name=ngx_http_fastdfs_module
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 -L/usr/lib -lfastcommon -lfdfsclient"
CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 -DFDFS_OUTPUT_CHUNK_SIZE='256*1024' -DFDFS_MOD_CONF_FILENAME='\"/etc/fdfs/mod_fastdfs.conf\"'"

# 将fastdfs-nginx-module/src下的mod_fastdfs.conf拷贝到/etc/fdfs/
cp mod_fastdfs.conf /etc/fdfs
# 修改mod_fastdfs.conf 
base_path=/home/fastdfs #保存日志目录
tracker_server=192.168.5.135:22122 #tracker服务器的IP地址以及端口号
storage_server_port=23000 #storage服务器的端口号
url_have_group_name=true #文件 url 中是否有 group 名
store_path0=/home/fastdfs/fdfs_storage  #存储路径
[group1]
group_name=group1
storage_server_port=23000
store_path_count=1
store_path0=/home/fastdfs/fdfs_storage

# 创建nginx/client目录
mkdir -p /var/temp/nginx/client
yum -y install pcre pcre-devel  
yum -y install zlib zlib-devel  
yum -y install openssl openssl-devel
tar -zxvf nginx-1.8.1.tar.gz -C /usr/local
cd /usr/local/nginx-1.8.1
# 编译
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi \
--add-module=/usr/local/fastdfs-nginx-module/src
# make
make
make install
vi //usr/local/nginx/conf/nginx.conf

server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        location /group1/M00 {
        root /home/fastdfs/fdfs_storage/data;
        ngx_fastdfs_module;
    }
}
/usr/local/nginx/sbin/nginx
[root@fds-client conf]# /usr/bin/fdfs_test /etc/fdfs/client.conf upload /home/test/test.png 
This is FastDFS client test program v5.05

Copyright (C) 2008, Happy Fish / YuQing

FastDFS may be copied only under the terms of the GNU General
Public License V3, which may be found in the FastDFS source kit.
Please visit the FastDFS Home Page http://www.csource.org/ 
for more detail.

[2019-11-07 10:11:55] DEBUG - base_path=/home/fastdfs, connect_timeout=30, network_timeout=60, tracker_server_count=1, anti_steal_token=0, anti_steal_secret_key length=0, use_connection_pool=0, g_connection_pool_max_idle_time=3600s, use_storage_id=0, storage server id count: 0

tracker_query_storage_store_list_without_group: 
    server 1. group_name=, ip_addr=192.168.5.136, port=23000

group_name=group1, ip_addr=192.168.5.136, port=23000
storage_upload_by_filename
group_name=group1, remote_filename=M00/00/00/wKgFiF3DfWuANNz4AAAlzCrdDj8028.png
source ip address: 192.168.5.136
file timestamp=2019-11-07 10:11:55
file size=9676
file crc32=719130175
example file url: http://192.168.5.136/group1/M00/00/00/wKgFiF3DfWuANNz4AAAlzCrdDj8028.png
storage_upload_slave_by_filename
group_name=group1, remote_filename=M00/00/00/wKgFiF3DfWuANNz4AAAlzCrdDj8028_big.png
source ip address: 192.168.5.136
file timestamp=2019-11-07 10:11:55
file size=9676
file crc32=719130175
example file url: http://192.168.5.136/group1/M00/00/00/wKgFiF3DfWuANNz4AAAlzCrdDj8028_big.png
使用Java程序对文件上传下载
<dependency>
    <groupId>net.oschina.zcx7878</groupId>
    <artifactId>fastdfs-client-java</artifactId>
    <version>1.27.0.0</version>
</dependency>
# resoureces/config/fastdfs-client.properties

fastdfs.connect_timeout_in_seconds = 5 #http连接超时时间 
fastdfs.network_timeout_in_seconds = 30 #tracker与storage网络通信超时时间 
fastdfs.charset = UTF‐8 #字符编码 
fastdfs.tracker_servers = 192.168.5.135:22122 #tracker服务器地址,多个地址中间用英文逗号分隔
@Test
void testUpload() throws  Exception{
    ClientGlobal.initByProperties("config/fastdfs-client.properties");
    System.out.println("network_timeout: "+ ClientGlobal.g_network_timeout);
    System.out.println("charset: "+ ClientGlobal.g_charset);

    //创建tracker客户端
    TrackerClient tc = new TrackerClient();
    //连接tracker server
    TrackerServer ts = tc.getConnection();
    if(ts == null){
        System.out.println("connect null");
        return;
    }

    //获取一个storage server
    StorageServer ss = tc.getStoreStorage(ts);
    if(ss == null){
        System.out.println("ss null");
        return;
    }

    //创建一个storage 客户端
    StorageClient1 storageClient1 = new StorageClient1(ts, ss);
    NameValuePair[] meta_list = null;
    String item = "E:\\logo.png";
    String fileid = storageClient1.upload_file1(item, "png", meta_list);
    System.out.println("Upload local file " + item + " ok, fileid=" + fileid);
}
输出:
network_timeout: 30000
charset: utf-8
Upload local file E:\logo.png ok, fileid=group1/M00/00/00/wKgFiF3Dj9GAMryVAAAexdAvMYY862.png
@Test
public void testFind() throws Exception{
    ClientGlobal.initByProperties("config/fastdfs-client.properties");
    TrackerClient trackerClient = new TrackerClient();
    TrackerServer trackerServer = trackerClient.getConnection();
    StorageServer storageServer = null;
    StorageClient storageClient = new StorageClient(trackerServer, storageServer);
    FileInfo fileInfo = storageClient.query_file_info("group1", "M00/00/00/wKgFiF3Dj9GAMryVAAAexdAvMYY862.png");
    System.out.println(fileInfo);
}
输出:
source_ip_addr = 192.168.5.136, file_size = 7877, create_timestamp = 2019-11-07 11:30:25, crc32 = -802213498
@Test
public void testDownload() throws Exception{
    ClientGlobal.initByProperties("config/fastdfs-client.properties");
    TrackerClient trackerClient = new TrackerClient();
    TrackerServer trackerServer = trackerClient.getConnection();
    StorageServer storageServer = null;

    StorageClient1 storageClient1 = new StorageClient1(trackerServer, storageServer);
    byte[] bytes = storageClient1.download_file1("group1/M00/00/00/wKgFiF3Dj9GAMryVAAAexdAvMYY862.png");
    File file = new File("e:/1.png");
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    fileOutputStream.write(bytes);
    fileOutputStream.close();
}

本文所需软件包百度网盘地址
链接:https://pan.baidu.com/s/1Rp7av-rLbXmM6vojvbkmrg
提取码:1maj

上一篇下一篇

猜你喜欢

热点阅读