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 <file_to_upload>
# 下载文件
fdfs_download_file /etc/fdfs/client.conf <file_id>
例如,上传文件后得到的字符串可能为: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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#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<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include <sys/types.h>
#include<string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include<ctype.h>
#include<sys/stat.h>
#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;
}

浙公网安备 33010602011771号