Skip to main content
标签ad报错:该广告ID(9)不存在。
  主页 > Linux

fastdfs存储原理

2023-06-11 浏览:
标签ad报错:该广告ID(7)不存在。

本文主要介绍fastdfs客户端的上传下载原理以及以及服务端的网络io模型;主要介绍storage,不涉及tracker;storage和tracker使用的网络io模型是一样的。

1.协议格式

FastDFS采用二进制TCP通信协议。一个数据包由 包头(header)和包体(body)组成。client、tacker、storage之间通信的消息格式,都是这样的。

包头只有10个字节,格式如下:

@ pkg_len:8字节整数,body长度,不包含header,只是body的长度

@ cmd:1字节整数,命令码; 比如上传,下载等;不同的命令,对应的body内容不同

@ status:1字节整数,状态码,0表示成功,非0失败(UNIX错误码)

// tracker\tracker_proto.h TrackerHeadertypedef struct{    char pkg_len[FDFS_PROTO_PKG_LEN_SIZE];  //body length, not including header    char cmd;    //command code    char status; //status code for response} TrackerHeader;

以STORAGE_PROTO_CMD_UPLOAD_FILE,上传普通文件为例,数据包定义如下:

img

2.客户端上传原理

fastdfs提供命令进行上传文件操作:

fdfs_upload_file <config_file> <local_filename> [storage_ip:port] [store_path_index]

客户端上传文件流程如下:

img

stat获取文件的状态、大小等

上传文件,肯定是要判断是否是一个常规文件;并且需要获取文件的大小的。通过linux系统提供的stat函数就可以得到,跟使用stat命令是一样的。

img

img

storage_do_upload_file

img

发送静态资源文件的时候,需要先将文件读入内存,再将内存中的数据send到相应的网络fd。通过使用sendfile完成文件的发送,不再需要两步操作。

sendfile使用mmap,实现零拷贝;

零拷贝,使用的是mmap方式,本质是DMA的方式,不需要CPU参与。普通copy,从磁盘copy数据到内存,需要CPU的move指令。

在进程中有一块区域叫内存分配区,当调用mmap的时候,会把文件映射到对应的区域,操作文件就跟操作内存一样。

img

fastdfs提供的客户端fdfs_upload_file是通过文件的方式上传,其实fastdfs也可以支持内存方式上传;我们在云盘项目中,就自己参考fastdfs的协议,实现了内存方式上传,减少了保存本地磁盘文件的过程。

发送完文件后,等待服务端返回响应;包含group_name, remote_file_name。

img

3.断点续传

fastdfs支持断点续传

先使用命令操作

echo hello > test1.txtecho world > test2.txtecho cong > test3.txt# 先使用fdfs_upload_appender上传 test1.txtfdfs_upload_appender /etc/fdfs/client.conf test1.txt得到:group1/M00/00/00/CqgWMGIgcUiEPsHJAAAAADY6MCA314.txt ,在fdfs_append_file的时候需要# 接着续传 test2.txtfdfs_append_file /etc/fdfs/client.conf group1/M00/00/00/CqgWMGIgcUiEPsHJAAAAADY6MCA314.txt test2.txt# 接着续传 test3.txtfdfs_append_file /etc/fdfs/client.conf group1/M00/00/00/CqgWMGIgcUiEPsHJAAAAADY6MCA314.txt test3.txt# 在服务器相应的目录下查找对应的文件,用cat读取文件内容。root@4af22fda6f4b:/home/fastdfs/storage/data/00/00# cat CqgWMGIgcUiEPsHJAAAAADY6MCA314.txthelloworldcong

断点续传文件分为两个阶段:

  1. fdfs_upload_appender 上传第一部分文件,STORAGE_PROTO_CMD_UPLOAD_APPENDER_FILE命令;
  2. fdfs_append_file 上传其他部分的文件,以STORAGE_PROTO_CMD_APPEND_FILE命令。

需要注意:

  • 注意断点续传的顺序性;
  • 支持断点续传,但fastdfs并不支持多线程分片上传同一个文件。

4.客户端下载原理

fastdfs下载协议如下:

img

客户端下载流程如下:

img

下载的时候也支持三种接收方式:

  • FDFS_DOWNLOAD_TO_FILE:storage_do_download_file1_ex
  • FDFS_DOWNLOAD_TO_BUFF:storage_download_file1
  • FDFS_DOWNLOAD_TO_CALLBACK:storage_download_file_ex

fastdfs支持多线程下载, 因为协议支持file_offset和download_bytes; 可以指定每一个线程现在的起始位置和大小。

img

如果服务端是对单个连接进行限速,那么客户端使用多线程下载可以提升下载速度;如果服务端是对用户名或者ip进行限速,客户端多线程下载效果也不明显。

5.网络io模型

fastdfs网络io使用的是多reactor的模型;分为accept线程,work线程,dio线程;这样设计的优点:

  • 将网络io和磁盘io解耦;
  • 扩充磁盘的时候,方便定义文件读写线程数量

accept线程接收网络连接,并将连接分配给work线程处理;通过pipe将连接发送给work线程;

work线程处理io请求;每个work线程都有一个epoll;如果需要进行磁盘io操作,则将任务push到队列中,交给dio线程处理;

dio线程进行磁盘io操作,从队列里面取任务;并通过pipe向work线程发送消息。

网络io简单处理流程如下图:

img

fastdfs具体的io处理如下:

img

线程进行磁盘io操作,从队列里面取任务;并通过pipe向work线程发送消息。

网络io简单处理流程如下图:

[外链图片转存中…(img-25s6udTD-1647335339614)]

fastdfs具体的io处理如下:

[外链图片转存中…(img-HST0uKy0-1647335339615)]

img

————————————————
版权声明:本文为CSDN博主「congchp」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/congchp/article/details/123507184