前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分布式文件系统FastDFS

分布式文件系统FastDFS

作者头像
心平气和
发布2020-09-11 11:25:07
6320
发布2020-09-11 11:25:07
举报
文章被收录于专栏:程序员升级之路

FastDFS是一个开源的轻量级分布式文件系统,开发语言为C,适合以小型文件为载体的在线服务,如相册网站、图片服务器等等。

github地址:https://github.com/happyfish100/fastdfs

架构图如下

几个重要的概念:tracker、storage、client

client就是调用方,tracker负责元数据,要上传文件、下载文件先从tracker获取相应的storage,然后client和storage交互,进行实际的文件上传、下载等操作。

FastDFS 没有实现自己的存储,而是使用操作系统的文件系统进行存储的,实际存储是按两级目录来保存文件的。

一、安装

实际安装的是5.11版本,安装目录设置为 /opt

1、安装libfastcommon

fastdfs依赖这个库

代码语言:javascript
复制
cd /opt
wget https://github.com/happyfish100/libfastcommon/archive/master.zip
unzip libfastcommon-master.zip
cd libfastcommon-master
make.sh
/make.sh install

2、安装FastDFS

代码语言:javascript
复制
cd opt
wget https://github.com/happyfish100/fastdfs/archive/master.zip
unzip fastdfs-master.zip
cd fastdfs-master
./make.sh
./make.sh install

3、配置

代码语言:javascript
复制
#配置拷贝
cd /etc/fdfs/
ls
client.conf.sample  storage.conf.sample  tracker.conf.sample
cp client.conf.sample client.conf
cp storage.conf.sample storage.conf
cp tracker.conf.sample tracker.conf

tracker中一些重要的参数如下

base_path

max_connections

connect_timeout

network_timeout

work_threads

sync_log_buff_interval

storage一些重要参数:

connect_timeout

network_timeout

heart_beat_interval

base_path

max_connections

work_threads

tracker_server(可以设置多行)

这里不具体详述每个参数的意义,具体可以参考官方文档。

二、使用

1、php

安装扩展,代码在FastDFS 的php_client目录,按标准的扩展安装即可。

安装完在php.ini加上如下,路径根据自己安装目录调整

代码语言:javascript
复制
fastdfs_client.base_path=/opt/fastdfs
fastdfs_client.tracker_group_count = 1
fastdfs_client.tracker_group0 = /etc/fdfs/client.conf

示例代码如下

代码语言:javascript
复制
<?php
    //上传文件
    function uploadFile(){
        $fdfs = new FastDFS();
        $tracker = $fdfs->tracker_get_connection();
        $storager = $fdfs->tracker_query_storage_store('group1', $tracker);
        $localFileName = '/home/liujh/projects/xman/url.txt';
        $fileRes = $fdfs->storage_upload_by_filename($localFileName, "txt", ["image" => "url"], "group1", $tracker, $storager);
        var_dump($fileRes);
        $fdfs->tracker_close_all_connections();
    }
 
    //获取文件信息
    function getFile(){
        $fileName = 'M00/00/00/rBVq5F1DyCOAURnnAAAPAnkf924742.txt';
        $fdfs = new FastDFS();
        $buf = $fdfs->storage_download_file_to_buff('group1', $fileName);
        var_dump($buf);
    }
    //获取文件元信息
    function getMeta(){
        $fileName = 'M00/00/00/rBVq5F1DyCOAURnnAAAPAnkf924742.txt';
        $fdfs = new FastDFS();
        $buf = $fdfs->storage_get_metadata('group1', $fileName);
        var_dump($buf);
    }
 
    //删除文件
    function delete(){
        $fileName = 'M00/00/00/rBVq5F1DyCOAURnnAAAPAnkf924742.txt';
        $fdfs = new FastDFS();
        $buf = $fdfs->storage_delete_file('group1', $fileName);
        var_dump($buf);
    }
    getFile();

2、Java

先在init方法进行初始化

代码语言:javascript
复制
public class FastDFSClintFactor{
@Value("#{'${connectTimeout}'}")
private String connectTimeout;

@Value("#{'${tracker_server}'}")
private String trackerServers;
  
//初始化
private void init(){
// 链接超时
      if(connectTimeout != null && connectTimeout.length > 0){
        ClientGlobal.setG_connect_timeout(Integer.valueOf(connectTimeout));
      } else {
        ClientGlobal.setG_connect_timeout(ClientGlobal.DEFAULT_CONNECT_TIMEOUT);
      }
      
      
      // 服务器
      if((trackerServers!= null && trackerServers.length > 0!)){
        InetSocketAddress[] addresss = this.getTrackerServerArray(trackerServers);
        ClientGlobal.setG_tracker_group(new TrackerGroup(addresss));
      } else {
        throw new NullPointerException("the value of item \"tracker_server\" is null. ");
      }
   }
   
 }

再创建trackerServer

代码语言:javascript
复制
// 链接服务器
      trackerServer = new TrackerClient().getConnection();

最后是创建client及使用

代码语言:javascript
复制
public StorageClient getStorageClient(){
    return new StorageClient(trackerServer, null);
  }
  
 
   // 文件属性
    List<NameValuePair> nvpList = new ArrayList<NameValuePair>(); 
    nvpList.add(new NameValuePair(FILENAME_KEY, fileSrcName));  
    nvpList.add(new NameValuePair(FILEEXTNAME_KEY, fileExtName));  
    NameValuePair[] metas = nvpList.toArray(new NameValuePair[0]);
    
    // 上传文件
    try {
      StorageClient sc = fastDFSManager.getStorageClient();
      String[] result = sc.upload_file(bytes, fileExtName, metas);
      }catch (Exception e) {
      logger.error("上传文件到FastDFS服务器异常,文件名:" + fileName, e);
      return null;
    }

三、使用踩坑

刚上线时有时候一些文件写入时大小为0,看了代码目前是长连接的实现方式,在MSHUT_DONW中才关闭连接,实际生产环境php-fpm的max_request会配置较大,造成服务端关闭连接但客户端还没关闭,因而许多连接取不到数据,修复方案改为短连接,修改文件fastdfs_client.c,代码如下:

代码语言:javascript
复制
//启用
zend_module_entry fastdfs_client_module_entry = {
STANDARD_MODULE_HEADER,
"fastdfs_client",
fastdfs_client_functions,
PHP_MINIT(fastdfs_client),
PHP_MSHUTDOWN(fastdfs_client),
NULL,//PHP_RINIT(fastdfs_client),
PHP_RSHUTDOWN(fastdfs_client),//PHP_RSHUTDOWN(fastdfs_client),
PHP_MINFO(fastdfs_client),
"1.00",
STANDARD_MODULE_PROPERTIES
};


PHP_RSHUTDOWN_FUNCTION(fastdfs_client)
{
FDFSConfigInfo *pConfigInfo;
FDFSConfigInfo *pConfigEnd;
if (!g_use_connection_pool){
  if (config_list != NULL)
  {
    pConfigEnd = config_list + config_count;
    for (pConfigInfo=config_list; pConfigInfo<pConfigEnd; \
      pConfigInfo++)
    {
      if (pConfigInfo->pTrackerGroup != NULL)
      {
        tracker_close_all_connections_ex( \
            pConfigInfo->pTrackerGroup);
      }
    }
  }
}

return SUCCESS;
}

四、写在最后

从架构图来看,FastDFS是高可用的,但故障发生时会丢失数据吗?答案是会丢,因为storage之间的文件同步是异步的,所以在client上传文件完后,storage已经返回响应给client了,如果这个时候文件还没有同步到其它的storage,则这个文件就丢了。

这里还有个问题,如果storage cluster有2个实例 st1, st2,如果client将文件上传到st1上,这个时间如果文件还没有同步到st2,这个时间client访问到st2了,这个时间就取不到数据了。针对这个问题,可以安装nginx模块

fastdfs-nginx-module来解决,不过这样一来运维成本也增加了,系统的复杂性也增加了。

总的来说,FastDFS是一个勉强能用的分布式文件系统,离真正的高可用、不丢数据、运维方便还有些距离。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员升级之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档