文章目录
一.分布式文件系统简介:
- 传统的文件系统是把数据存储在主机上,而传统的文件系统格式有ntfs / fat32 / ext3 / ext4,当主机空间不足时,通过挂载外盘来扩容。
- 而分布式文件系统是把数据存储在很多的主机节点上上,通过程序来形成一个完整的文件系统。
- 分布式文件需要网络来数据传输,通过云服务上的管理程序来进行存储数据节点的获取和存储以及用户的访问和上传。
- 布式文件系统有GFS、HDFS、Lustre、FastDFS、GlusterFS、GPFS、Ceph、淘宝TFS和腾讯TFS等,本文将对FastDFS进行介绍
二.FastDFS简介
FastDFS 是一款开源的轻量级分布式文件系统,由淘宝的架构师余庆创作,为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,注重高可用、高性能等指标。
- 纯C实现,支持Linux、FreeBSD等类UNIX系统;
- 类Google FS,不是通用的文件系统,只能通过专有的API访问,目前提供了 C、Java和PHP API
- 类似于文件系统的key/value pair存储系统
- 倾向于存储中小型文件(4KB~500MB)
- 支持相同内容的文件只保存一份,节约磁盘空间
- 下载文件支持HTTP协议
三.FastDFS组成
Tracker Server
跟踪服务器,主要做调度工作,在访问时起负载均衡的作用。在内存中记录 集群中group和storage服务器的状态信息,是连接客户端和Storage服务端的枢纽。因为相关信息全部在内存中,Tracker服务器的性能非常高,一个较大的集群(比如上百个group)中有3台就足够了。
Storage Server
存储服务器,文件内容和文件属性都保存到存储服务器上。
client
客户端,作为业务请求的发起方,通过专有接口,使用TCP/IP 协议与跟踪器服务器或存储节点进行数据交互。FastDFS 向使用者提供基本文件访问接口,比如upload 、 download 、 append 、 delete等,以客户端库的方式提供给用户使用。
上传流程
客户端首先请求Tracker服务器进行查询存储节点,得到存储节点的ip+port,将文件上传到对应的存储节点,存储节点服务器会返回客户端文件ID.
下载流程
文件ID
例如:
group1/M00/00/00/rBEAAWCHwpKAG_IaAAE2xZYv3yo399.tar.gz
group1
文件上传到了存储节点的哪一个组M00 - 虚拟目录
和存储节点的配置项有映射
如:store_path0=/home/yuqing/fastdfs/data00/00
配置好后在data下会生成文件路径,00/00就是真实的文件路径rBEAAWCHwpKAG_IaAAE2xZYv3yo399.md
文件名包含的信息包含如下5个字段,每个字段4字节,采用Base64编码- 源storage server Ip 地址
- 文件创建时间戳
- 文件大小
- 文件CRC32效验码
- 随机数
四.FastDFS配置
配置文件位置:/etc/fdfs
1.tracker.conf
#绑定ip,不写会自动绑定本机ip bind_addr= #监听端口号 port=22122 #追踪器文件路径 base_path=/home/
2.stroage 配置文件
# 组名
group_name=group1
#绑定ip,不写会自动绑定本机ip
bind_arr=
#监听端口号
port=23008
#存储节点写log日志的路径
base_path=/home/yuging/fastdfs
#存储节点提供的存储文件的路径个数
store_path_count=2
#具体的存储路径(要修改)
store_pathg=/home/yuqing/fastdfsstore_path1=/home/yuqing/fastdfs1
#追踪器的地址信息(要修改)
tracker_server=192.168.247.135:22122
3.client配置文件
客户端写日志的文件
base_path=/home/yuqing/
#tracker服务器地址
tracker_server=ip+port
五.FastDFS使用
tracker 服务-守护进程
启动:fdfa fdfs_trackerd 追踪器的配置文件(/etc/fdfs/tracker.conf) 关闭:fdfs_trackerd 追踪器的配置文件(/etc/fdfs/tracker.conf) stop 重启:fdfs_trackerd 追踪器的配置文件(/etc/fdfs/tracker.conf)restart
storage服务-守护进程
启动 fdfs_storaged 存储节点的配置文件(/etc/fdfs/storage.conf) 关闭:fdfs_storaged 存储节点的配置文件(/etc/fdfs/storage.conf) stop 重启:fdfs_storaged 存储节点的配置文件(/etc/fdfs/storage.conf) restart
启动客户端
上传:fdfs_upload_file 客户端的配置文件(/etc/fdfs/client.conf) 上传文件 得到的结果字符串:file_id 下载:fdfs_download_file 客户端的配置文件(/etc/fdfs/client.conf) file_id
六.代码实现
代码实现有两种方法
通过execl调用客户端程序进行上传下载
int upload_file2(const char* conFile,const char*uploadFile,char* fileId,int n){ //创建匿名管道 int fd[2]; int ret=pipe(fd); if(ret==-1){ perror("pipe eerror"); exit(0); } //创建子进程 pid_t pid=fork(); if(fork()==0) { dup2(fd[1],STDOUT_FILENO); close(fd[0]); execlp("fdfs_upload_file","fdfs_upload_file",conFile,uploadFile,NULL); perror("execlp error"); }else{ //父进程 close(fd[1]); read(fd[0],fileId,n); } }
使用API
需要链接对应的头文件和库文件
#include "fdfs_client.h" int upload_file1(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; }