文件上传原理和负载均衡方法

一、文件上传原理1.1、选择tracker server1.2、选择存储的group及其负载均衡算法1.3、选择storage server及其负载均衡算法1.4、选择storage path及其负载均衡算法1.5、生成Fileid1.5.1、选择两级目录1.5.2、生成文件名

二、下载文件逻辑总结

一、文件上传原理

1.1、选择tracker server

高可用,通过冗余的方式提供服务。当集群中不止一个tracker服务时,由于tracker之间是对等的关系,客户端在上传文件时可以任意选择一个tracker。

1.2、选择存储的group及其负载均衡算法

当tracker接收到上传文件的请求时,会为该文件分配一个可以存储该文件的group,支持如下选择group的规则: (1)Round robin,所有的group间轮询。 (2)Specified group,指定某一个确定的group。 (3) Load balance,选择最大剩余空 间的组上传文件 。

1.3、选择storage server及其负载均衡算法

当选定group后,tracker会在group内选择一个storage server给客户端,支持如下选择storage的规则:

Round robin,在group内的所有storage间轮询。First server ordered by ip,按IP排序,也会轮询。First server ordered by priority,按优先级排序(优先级在storage上配置);可以理解为权重的方式,权重高的优先选择。比如,storage 1 为100M的带宽和storage 2为500M带宽,上传文件时优先使用500M带宽的storage。

1.4、选择storage path及其负载均衡算法

当分配好storage server后,客户端将向storage发送写文件请求,storage将会为文件分配一个数据存储目录,支持如下规则: (1) Round robin,多个存储目录间轮询。 (2)剩余存储空间最多的优先。

可以配置多个磁盘路径。注意,同一个group中的storage的配置必须是一样的;这里的一样不是路径一样,而是path的数量要一致。多个路径对应多个磁盘,才能发挥多个磁盘并发读写能力。

# store path (disk or mount point) count, default value is 1store_path_count = 1

#存储路径(磁盘或挂载点)计数,默认值为1

store_path_count=1

# store_path#, based on 0, to configure the store paths to store filesif store_path0 not exists, it' s value is base_path (NOTrecommended)#the paths must be exist.

#store_path#,基于0,要配置存储路径来存储filesif store_path 0不存在,它的值是base_path(NOT推荐的)#这些路径必须存在。

#

#

#工IMPORTANTNOTE:#

#工IMPORTANTNOTE:

#the store paths' order is very important, don 't mess up ! !!

#store路径的排序很重要,不要搞砸了!

#

# the base_path should be independent (different) of the store paths

# 基路径应该独立于存储路径(不同)

store_path0 = /home/fastdfs/storage_group1_23000

#store_path1 = / home/yuqing/fastdfs2

fastdfs适合小文件存储,大文件存储建议使用ceph。如果使用fastdfs存储大文件,那么是一个磁盘分摊写压力;而ceph的集群可以使用多台服务分摊写压力,写的速度会非常快。

1.5、生成Fileid

选定存储目录之后,storage会为文件生一个Fileid,由 storage server ip、文件创建时间、文件大小、文件crc32、一个随机数拼接而成,然后将这个二进制串进行base64编码,转换为可打印的字符串。

4 bytes 4 bytes 8 bytes 4 bytes 2 bytes

+--------+--------+----------------+--------+-----+

| IP | time | file_size | crc32 |校验值|

1.5.1、选择两级目录

当选定存储目录之后,storage会为文件分配一个fileid,每个存储目录下有两级256*256的子目录,storage会路由到其中一个子目录,然后将文件以fileid为文件名存储到该子目录下。

1.5.2、生成文件名

当文件存储到某个子目录后,即认为该文件存储成功,接下来会为该文件生成一个文件名,文件名由:group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。 文件名规则:

storage_id,(ip的数值型)源storage server ID或IP地址。timestamp,文件创建时间戳。file_size,若原始值为32位则前面加入一个随机值填充,最终为64位。crc32,文件内容的检验码。随机数 ,引入随机数的目的是防止生成重名文件。

eBuDxWCb2qmAQ89yAAAAKeR1iIo162

| 4bytes | 4bytes | 8bytes |4bytes | 2bytes |

| ip | timestamp | file_size |crc32 | 校验值 |

二、下载文件逻辑

客户端upload file成功后,会拿到一个storage生成的文件名,接下来客户端根据这个文件名即可访问到该文件。 跟upload file一样,在download file时客户端可以选择任意tracker server。 client发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。

由于group内的文件同步时在后台异步进行的,所以有可能出现在读到时候,文件还没有同步到某些storage server上,为了尽量避免访问到这样的storage,tracker按照如下规则选择group内可读的storage:

该文件上传到的源头storage, 源头storage只要存活着,肯定包含这个文件,源头的地址被编码在文件名中。文件创建时间戳一定是storage被同步到的时间戳 且(当前时间-文件创建时间戳) > 文件同步最大时间(如5分钟) ,文件创建后,认为经过最大同步时间后,肯定已经同步到其他storage了。文件创建时间戳 < storage被同步到的时间戳。 同步时间戳之前的文件确定已经同步了。(当前时间-文件创建时间戳) > 同步延迟阀值(如一天)。 经过同步延迟阈值时间,认为文件肯定已经同步了。

思考:fastdfs上传完文件后立即读取文件问题。因为fastdfs是弱一致性,可能其他storage还没有同步文件,这时应该怎么判断从哪个storage中读取文件?

可以根据时间来读取,因为fileid里有携带时间戳,可以根据时间进行匹配来进入storage ;如果某个storage没有同步

总结

上传文件逻辑:

#mermaid-svg-bqLIfRZF311YLZVE {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-bqLIfRZF311YLZVE .error-icon{fill:#552222;}#mermaid-svg-bqLIfRZF311YLZVE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bqLIfRZF311YLZVE .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-bqLIfRZF311YLZVE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bqLIfRZF311YLZVE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bqLIfRZF311YLZVE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bqLIfRZF311YLZVE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bqLIfRZF311YLZVE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bqLIfRZF311YLZVE .marker.cross{stroke:#333333;}#mermaid-svg-bqLIfRZF311YLZVE svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bqLIfRZF311YLZVE .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-bqLIfRZF311YLZVE text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-bqLIfRZF311YLZVE .actor-line{stroke:grey;}#mermaid-svg-bqLIfRZF311YLZVE .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-bqLIfRZF311YLZVE .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-bqLIfRZF311YLZVE #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-bqLIfRZF311YLZVE .sequenceNumber{fill:white;}#mermaid-svg-bqLIfRZF311YLZVE #sequencenumber{fill:#333;}#mermaid-svg-bqLIfRZF311YLZVE #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-bqLIfRZF311YLZVE .messageText{fill:#333;stroke:#333;}#mermaid-svg-bqLIfRZF311YLZVE .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-bqLIfRZF311YLZVE .labelText,#mermaid-svg-bqLIfRZF311YLZVE .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-bqLIfRZF311YLZVE .loopText,#mermaid-svg-bqLIfRZF311YLZVE .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-bqLIfRZF311YLZVE .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-bqLIfRZF311YLZVE .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-bqLIfRZF311YLZVE .noteText,#mermaid-svg-bqLIfRZF311YLZVE .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-bqLIfRZF311YLZVE .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-bqLIfRZF311YLZVE .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-bqLIfRZF311YLZVE .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-bqLIfRZF311YLZVE .actorPopupMenu{position:absolute;}#mermaid-svg-bqLIfRZF311YLZVE .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-bqLIfRZF311YLZVE .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-bqLIfRZF311YLZVE .actor-man circle,#mermaid-svg-bqLIfRZF311YLZVE line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-bqLIfRZF311YLZVE :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

Storage Server

Tracker Server

Client

1.定时向Tracker上传状态信息

2.上传链接请求

3.查询可用sorage

4.返回信息(storage的ip和端口)

5.上传文件(文件内容和meta data)

6.生成file id

7.将上传内容写入磁盘

8.返回file id(路径信息和文件名)

9.储存文件信息

Storage Server

Tracker Server

Client

下载文件逻辑:

#mermaid-svg-ZNkWFS6J5ArRnf9n {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ZNkWFS6J5ArRnf9n .error-icon{fill:#552222;}#mermaid-svg-ZNkWFS6J5ArRnf9n .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZNkWFS6J5ArRnf9n .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-ZNkWFS6J5ArRnf9n .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZNkWFS6J5ArRnf9n .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZNkWFS6J5ArRnf9n .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZNkWFS6J5ArRnf9n .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZNkWFS6J5ArRnf9n .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZNkWFS6J5ArRnf9n .marker.cross{stroke:#333333;}#mermaid-svg-ZNkWFS6J5ArRnf9n svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZNkWFS6J5ArRnf9n .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ZNkWFS6J5ArRnf9n text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-ZNkWFS6J5ArRnf9n .actor-line{stroke:grey;}#mermaid-svg-ZNkWFS6J5ArRnf9n .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-ZNkWFS6J5ArRnf9n .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-ZNkWFS6J5ArRnf9n #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-ZNkWFS6J5ArRnf9n .sequenceNumber{fill:white;}#mermaid-svg-ZNkWFS6J5ArRnf9n #sequencenumber{fill:#333;}#mermaid-svg-ZNkWFS6J5ArRnf9n #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-ZNkWFS6J5ArRnf9n .messageText{fill:#333;stroke:#333;}#mermaid-svg-ZNkWFS6J5ArRnf9n .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ZNkWFS6J5ArRnf9n .labelText,#mermaid-svg-ZNkWFS6J5ArRnf9n .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-ZNkWFS6J5ArRnf9n .loopText,#mermaid-svg-ZNkWFS6J5ArRnf9n .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-ZNkWFS6J5ArRnf9n .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-ZNkWFS6J5ArRnf9n .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-ZNkWFS6J5ArRnf9n .noteText,#mermaid-svg-ZNkWFS6J5ArRnf9n .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-ZNkWFS6J5ArRnf9n .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ZNkWFS6J5ArRnf9n .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ZNkWFS6J5ArRnf9n .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ZNkWFS6J5ArRnf9n .actorPopupMenu{position:absolute;}#mermaid-svg-ZNkWFS6J5ArRnf9n .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-ZNkWFS6J5ArRnf9n .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ZNkWFS6J5ArRnf9n .actor-man circle,#mermaid-svg-ZNkWFS6J5ArRnf9n line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-ZNkWFS6J5ArRnf9n :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

Storage Server

Tracker Server

Client

1.定时向Tracker上传状态信息

2.下载链接请求

3.查询可用sorage(检测可用状态)

4.返回信息(storage的ip和端口)

5.file id(组名、路径名)

6.查找文件

7.返回文件内容

Storage Server

Tracker Server

Client

相关链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。