FastDFS 启动与使用详解:分布式文件系统的快速入门

FastDFS 启动与使用详解:分布式文件系统的快速入门

FastDFS 是一款开源的分布式文件系统,它主要解决了大文件的存储与负载均衡问题,非常适合用于海量文件的存储需求。本文将详细介绍如何启动和使用 FastDFS,包括启动追踪器、存储节点、客户端,以及如何进行文件上传下载与状态检测。

1. FastDFS 组件介绍

FastDFS 系统由三个核心组件组成:

Tracker Server(追踪器服务器):管理和调度客户端请求,负责任务分发和负载均衡。

Storage Server(存储服务器):负责文件的存储、同步和访问。

Client(客户端):通过追踪器和存储服务器进行文件的上传、下载等操作。

2. 启动 FastDFS 组件

2.1 启动 Tracker Server(追踪器服务器)

Tracker Server 是 FastDFS 系统的调度中心,必须首先启动。以下命令用于启动、关闭和重启追踪器服务器:

# 启动 Tracker Server

fdfs_trackerd /etc/fdfs/tracker.conf

# 关闭 Tracker Server

fdfs_trackerd /etc/fdfs/tracker.conf stop

# 重启 Tracker Server

fdfs_trackerd /etc/fdfs/tracker.conf restart

可以使用以下命令检查 Tracker Server 是否正常运行:

ps aux | grep fdfs_*

2.2 启动 Storage Server(存储服务器)

存储服务器是文件存储的核心组件,需在追踪器服务器启动后启动。以下是相关命令:

# 启动 Storage Server

fdfs_storaged /etc/fdfs/storage.conf

# 关闭 Storage Server

fdfs_storaged /etc/fdfs/storage.conf stop

# 重启 Storage Server

fdfs_storaged /etc/fdfs/storage.conf restart

2.3 启动 Client(客户端)

客户端用于与 FastDFS 系统进行交互,主要执行文件的上传和下载操作。以下是基本的上传和下载命令:

# 上传文件

fdfs_upload_file /etc/fdfs/client.conf

# 下载文件

fdfs_download_file /etc/fdfs/client.conf

例如,上传文件后得到的字符串可能为:group1/M00/00/00/wKj3h1vC-PuAJ09iAAAHT1YnUNE31352.c,该字符串即为 file_id,用于后续的下载操作。

3. FastDFS 状态检测

为了确保系统的稳定性,定期监控 FastDFS 的状态是非常重要的。可以使用以下命令来监测系统的状态:

fdfs_monitor /etc/fdfs/client.conf

监测命令会显示 Storage Server 的状态信息,常见的状态包括:

INIT:初始化,尚未找到同步源服务器。

WAIT_SYNC:等待同步,已找到同步源服务器。

SYNCING:同步中。

DELETED:已删除,服务器已从集群中移除。

OFFLINE:离线状态。

ONLINE:在线状态,但尚不能提供服务。

ACTIVE:在线状态,已准备好提供服务。

了解这些状态可以帮助你快速诊断和处理系统问题。

4. File ID 详解

FastDFS 在上传文件后,会生成一个 file_id,该 file_id 包含了文件所在的组、虚拟目录和文件名等信息。

Group1:文件所属的存储组。如果系统中存在多个组,file_id 中的组名会动态变化。

M00:虚拟目录,与存储节点的实际路径相映射。

00/00:文件在存储节点中的实际路径,这部分路径是可变的。

wKhS_VlrEfOAdIZyAAAJTOwCGr43848.md:文件名部分,采用 Base64 编码,包含源存储服务器 IP 地址、文件创建时间、文件大小、CRC32 校验码和随机数。

5. 文件上传与下载的代码实现

5.1 使用多进程方式实现

通过多进程和 exec 系列函数,可以在代码中实现文件的上传与下载。以下是简单的实现思路:

使用 pipe 函数创建管道,父进程和子进程之间通过管道通信。

在子进程中调用 execlp 函数执行 fdfs_upload_file 命令,并通过管道将结果传递给父进程。

父进程从管道中读取上传结果,并将其写入数据库或进行其他操作。

5.2 使用 FastDFS API 实现

另一种方法是直接使用 FastDFS 提供的 API 进行文件的上传和下载。通过编写 fdfs_upload_file.c 文件,调用 FastDFS 的接口,实现更灵活的文件操作。

/**

* 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.

**/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "fdfs_client.h"

// #include "logger.h"

//加上const 明显就知道了这是一个传入的文件 fileID 是一个传出n参数

int upload_file(const char *confFile,const char *myFile,char *fileID)

{

char group_name[FDFS_GROUP_NAME_MAX_LEN + 1];

ConnectionInfo *pTrackerServer;

int result;

int store_path_index;

ConnectionInfo storageServer;

if ((result=fdfs_client_init(confFile)) != 0)

{

return result;

}

pTrackerServer = tracker_get_connection();

if (pTrackerServer == NULL)

{

fdfs_client_destroy();

return errno != 0 ? errno : ECONNREFUSED;

}

*group_name = '\0';

if ((result=tracker_query_storage_store(pTrackerServer, \

&storageServer, group_name, &store_path_index)) != 0)

{

fdfs_client_destroy();

fprintf(stderr, "tracker_query_storage fail, " \

"error no: %d, error info: %s\n", \

result, STRERROR(result));

return result;

}

result = storage_upload_by_filename1(pTrackerServer, \

&storageServer, store_path_index, \

myFile, NULL, \

NULL, 0, group_name, fileID);

if (result == 0)

{

printf("%s\n", fileID);

}

else

{

fprintf(stderr, "upload file fail, " \

"error no: %d, error info: %s\n", \

result, STRERROR(result));

}

tracker_disconnect_server_ex(pTrackerServer, true);

fdfs_client_destroy();

return result;

}

//size fileID 对长度的描述

int upload_file1(const char *confFlie,const char *uploadFile,char *fileID,int size)

{

//创建管道

int fd[2];

int ret=pipe(fd);

if(ret==-1){

perror("pipe error");

exit(0);

}

//创建子进程

pid_t pid=fork();

//子进程

if(pid==0){

//将new 重定向号old 将标准输出重定向到管道写的一段

dup2(fd[1],STDOUT_FILENO);

//关闭u读的a一顿

close(fd[0]);

execlp("fdfs_upload_file","xxx",confFlie,uploadFile,NULL);

perror("execlp error");

}

else{

//父进程 读ao管道 关闭写端

close(fd[1]);

char buf[1024];

read(fd[0],fileID,size);

//回收pid

wait(NULL);

}

return 0;

}

main.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "fdfs_upload_file.h"

int main(int argc,const char *argv[])

{

char fileID[1024]={0};

upload_file("/etc/fdfs/client.conf","main.c",fileID);

printf("fileId:%s\n",fileID);

printf("=================================\n");

upload_file1("/etc/fdfs/client.conf","main.c",fileID,sizeof(fileID));

printf("fileID: %s\n",fileID);

return 0;

}

相关文章