- 画出云盘项目架构图,并解析每个模块的作用
FastDFS服务有三个角色: 跟踪服务器(tracker server),存储服务器(storage server)和客户端(client)。特别适合于中小文件(文件大小:4KB-500MB)海量数据存储问题,例如图片分享和视频分享网站。
Tracker是fastdfs的协调者,负责管理所有的storage server 和group,每个storage 在启动后会连接tracker,告知自己所属的group等信息,并保持周期性心跳,tracker根据storage 的心跳信息,建立 group==》【storage server list】的映射表。
Tracker需要管理的元信息很少,会全部存储在内存中,里面的信息都是由storage汇报的信息生成的,本身是不需要持久化任何数据,这就使得tracker非常容易扩展,直接增加tracker机器即可扩展为tracker cluster(集群)来服务,cluster 里每个tracker之间是完全对等,所有的tracker 都接受storage 的心跳信息,生成元数据来提供读写服务。
Storage server(后面简称为storage)以组(卷,group或volume)为单位组织,一个group内包含多台storage机器,数据互为备份,存储空间以group内容量最小的storage为准,故配置多个storage尽量硬件资源相同,以免造成浪费。
以group为单位租住的存储能方便进行隔离,负载均衡,副本数定制(group内storage 的数量为该group的副本数),比如将不同引用数据存到不同的group就能隔离应用数据,同时还能根据应用的访问特性来将应用分配到不同的group来做负载均衡;缺点就是group的容量受单机存储容量的限制,同时当group内有机器坏掉时,数据恢复只能依赖group内的其他机器,使得恢复时间会很长。
group内每个storage的存储依赖于本地文件系统,storage可配置多个数据目录,比如有10快磁盘,分别挂载在/data/disk1-/data/disk10, 则可将这10个目录配置为storage的数据存储目录;
storage接受到写文件请求时,会根据配置好的规则,选择其中一个存储目录来存储文件。为了避免单个目录下的文件太多,在storage第一次启动时,会在每个数据存储目录中创建2级子目录,每级256个,总共65536个文件,新写的文件会以hash的方式被路由到其中某个子目录下,然后将文件数据直接作为一个本地文件存储到该目录中。
Client: FastDFS向使用者提供基本文件接口,比如monitor、upload、download、append、delete等,以客户端库的方式提供给用户使用。
2. 云盘多大的上传量,高峰时期能到多少
这个是根服务器的性能有关,写如磁盘的速度,文件的大小等等。测试的时候可以先测试单机,上传1k的文件和上传500M的文件肯定是不同的。
3. Storage是如何分组的?
Storage是支持水平扩展的,只需要一组一组的扩充就行了。同一个group中不同机器是备份的数据,可以做到读写分离。
4. 同一个group里的storage如何做同步
是通过binlog 的方式去做的。
5. 不同的group里的storage能否做到同步
不同的group的数据是不一样的,同一个group中所有storage的数据是一样。
6. 存储的storage服务器宕机了,其他的storage如何同步?
-
如何防止盗链
Fastdfs会有的token机制,redis 这个会生成token,然后爱设置有效时间。 -
FastDFS如何应对单点故障
如果storage的某个磁盘坏了,会换一个新的磁盘,配置好之后,会自动进行备份其他storage的数据。 -
能否支持断点续传?如何实现?
会有一个append 的操作,后面在讲。通过upload_appeder_file这个接口实现断点续传。 -
能否支持小文件合并
如果有很多小文件,一个小文件占用一个node的话,会导致文件传输效率会很低的,后面再讲。很多文件存储会支持小文件合并。 -
如何实现负载均衡?
读写分离,可以进行一个轮询,一个storage在读或者在写的时候,下一次应该尽量用另外的storage -
Fastdfs和ceph,hadoop有什么区别,为什么选择用这个作为分布式存储?
https://www.cnblogs.com/yswenli/p/7234579.html#/c/subject/p/7234579.html
-
上传文件内容一样的话,是秒传的,服务器会不会重复存储。
这个根据程序中写的,如果是根据文件内容生成的md5,则不同文件名但内容一样的话,生成的md5是一样的,服务器会将该文件内容引用量加1,删除的时候会减1;如果是根据文件名加上文件内容生成的md5,就需要两者都相同才能生成相同的md5,之后传输就是秒传,过程和上面的一样。 -
Fastdfs单机就是单集群的,在不同地区可以进行数据备份嘛?
是不能的,目前还做不到,只是跟上面的一样,同一个group是一样的数据,不同地区的话,不在一个group数据是不一样的。 -
用密码验证和用token验证有什么区别?
密码:一直存在,会在(mysql)数据库(持久化)里面;读密码时候会读mysql。
用密码登陆的时候,就会返回token。
token: 是临时的,比如24小时过期。一般存在redis中,redis可以设置过期时间。 -
此项目中redis用在了哪些功能上?
存储token;比如上传文件,下载文件就只需要使用token,就不需要使用密码了。
下载排行耪和快速获取文件名 -
项目中是根据文件内容生成的md5值?那么文件名不一样,内容一样的话,是怎么存储的?
在redis 中是根据md5值加上文件名生成的key值
在mysql中是md5值是一样的,文件名不一样,所以生成的url 是一样的,数量改变成了2个。
目前这个项目中的md5一样的,只保存一份。文件名在一个表(保证名字),存储的在另一个表(只保证文件内容,不保证名字),生成的url在存储的表中,所以只用存储一份就行了,不用重复存储。 -
生成token 的流程
在login_cgi.c中,连接redis(后续保存在redis中),产生随机数,根据des加密,然后用base64进行加密(这里是因为在互联网中发送127字节容易截断,所以用base64进行加密,加密后比原先的长1/3),最后用md5加密生成token,这样做的目的是为了保证token 的唯一性。
当不可见字符在网络上传输的时候,比如从计算机A到计算机B,往往需要经过多个路由设备,由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的,为了解决上面的问题,我们可以对这些数据进行编码。把传输的内容变成可见字符,也就是ASCII码可见字符。所以要让记事本这样的文本处理软件能处理二进制数据,如使用json保存二进制信息,需要先把数据做个base64编码,统统变成可见字符,在保存。 -
此项目有什么缺点?
很多人同时传大文件,存储空间和性能会影响到并发,
所以一般用fastdfs 的是一些图片和小视频,写这个框架的作者也说这个框架只适合中小文件,500MB以内的文件
上传文件的流程是先保存到本地,然后保存在fastdfs里面,因为里面用的是调用的是fdfs_client应用程序,需要指定存储路径和文件
如果项目中是读多写少,可以通过增加storage 机器的数量来满足,一个group挂载多个机器,提高整个系统的并发量。 -
fastdfs为什么没有存源文件名
Fastdfs是根据file_id + 其他表中存储的file_name拼接成的完整的下载url,这两个表是根据md5关联的。源码就是不存储文件名的。 -
fastdfs 在传输文件时候零拷贝是怎么实现的(特性)
一般读文件是先读到内存然后发到网络里面去;
直接通过sendfile ,零拷贝的方式发送过去,顶层直接访问socket发送数据。dma。
-
fastdfs在发送大文件,如果中途没发送完就失败了,这个怎么解决?
发送比较大的文件,适合用追加的方式发送,不然中途失败会很可惜。Append
Fastdfs中的网络模型开始是用libevent,然后作者自己设计一个网络模型,与之类似。 -
fastdfs文件同步
23.1 两个storage如何相互备份,会不会出现备份死循环问题
不会的,因为fastdfs采用的是binlog的异步复制方式,有对应的格式,其中有个字段大小写代表不同含义(分别代表源和副本)
23.2 已经存在两个storage了,然后加入第三个storage,那谁同步给第三个storage
新加入一个机器,这时候两个storage都会向tracker请求向新的机器同步
Tracker会选择其中一个作为同步源,选中哪一个就会返回哪一个的ip
选中ip机器就作为天选之子,开始同步;
另外的机器因为返回源ip不是自己就会等待新的storage C 状态为Active时,在去同步备份数据;
这里有两种规则: 1. 常规: 只推送大写源操作; 2. 新加入: 推送大写源操作 + 小写备份操作。这里新加入机器属于第2中操作。
23.3 binlog 的格式是怎么设计的,如果binlog文件太大该怎么处理
下面是binlog 的格式
上面可以看到,binlog文件有三列: 时间戳、操作类型、文件ID(不带group名称)
其中文件操作类型采用单个字母编码,其中源头操作用大写字母表示,被同步的操作作为对应的小写字母。文件操作字母含义如下:
注:源表示客户端直接操作的那个storage即为源,其他的storage 都为副本
23.4 已有A、B、C三个storage, 我现在上传一个文件到A,然后发起请求,会不会出现从B下载,但此时B没有同步文件,导致下载失败?
不会的,file_id有时间戳,下载的时候回去匹配各个storage的同步时间戳,如果B还没有做同步,则时间戳是小于file_id 的时间戳,这样就不会选择B
-
accept、worker、dio 线程数量什么时候最高效率。
有待商榷 -
为什么需要小文件存储?
如果没有小文件存储方案,20MB的文件可能占几百MB。
问题来源: 1. 文件节点占用; 2. 文件大小,空间对齐的问题,比如至少占用4K字节 -
开启了小文件存储,你的阈值是多少?
在配置tracker文件中,源码中默认值是16MB,但是作者是写的是1MB,具体多少,这个需要根据自己项目中的实际情况。面试可以直接说16MB。许多小文件合并成一个大文件的大小是64MB。
小文件(<16MB)存储是没有独立的文件名的,(>16MB)文件存储是拥有独立的hash文件名
在源码中的默认值和实际值不一样的情况下,需要看代码中的实际值。
==
在配置项目中也会有根据内存池相似的操作,检测到有连续空虚的空间会不会合并。 -
fastdfs只允许唯一文件上传的原理
通常做法是 1. 在客户端进行校验md5 2. 结合mysql + redis 。
上面是需要在storage中的配置文件中设置,相当于索引信息,如果不设置,两份相同文件就会存储两份;如果开启,第二个相同文件上传的时候就会在数据库中检查是否有相同的md5值,数据库中有此md5,就不会进行存储,只用引用计数加1。 -
该项目的并发是多少?回答需要根据实际情况去回答
图中的性能主要的考虑storage,
影响因素:
带宽 1000Mb = 100 MB 不能直接除以8,传输的包还需要把包头啥的算进去。
磁盘读写性能 : 需要1秒写入多少, 写入的次数。
机械硬盘 200MB
固态硬盘 500MB
Read并发: group固定
Storage越多,并发量越高 例如4 个storage
传输文件 : 文件越大,理论并发量就越小
5K 100M/5K = 20480 * 4
50K = 2048 * 4
500K = 208 * 4
10M
然后小文件存储多的时候,也需要考虑fastdfs 存储做的处理时间,实际值可能会更小。
最大连接数是1024 可设置。 每个连接的task 缓存是256K
1024 * 256 = 256M,。
文件越大,占用连接的事件就越长
这里的1024,指的是连接客户端的数量,如果有1024这样的连接客户端在传输文件被占用后,后面在连接不上了,需要等待这1024的客户端传输完成后释放资源在去连接
例如单纯测试硬盘的速度:用1M文件测试可能200MB/s, 用4K去测试可能就10-20MB/s.
做到网盘控制速度: 服务器需要根据时间去控制,读取文件出来,过了5ms在输出,过了20ms在输出,这样将带宽更好的分给其他人。
在fastdfs中有test的相关代码,也是按照上面这样的思路去测试的。
提高并发写的能力:(上传文件)
需要扩展group的数量,而不是storage的数量。
增加带宽
使用读写性能高的磁盘
提高写的能力(下载文件)
增加storage
增加group
增加带宽
使用读写性能高的磁盘