ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

FastDFS分布式文件系统搭建实战:从单机到生产高可用

FastDFS分布式文件系统搭建实战:从单机到生产高可用 看到5分钟搭建FastDFS这个标题我先泼一盆冷水单机版从下载源码到服务起来5到10分钟确实够用。但FastDFS这个名字里的分布式三个字才是真正让你多花时间的部分。我第一次在生产环境部署它的时候光排查一个下载失败的问题就折腾了大半个晚上。这篇博客就是把我从零搭建到生产可用的完整过程以及过程中踩过的坑一起写出来按步骤操作你能快速跑通更重要的是搞清楚每一步背后的原理避免上线之后才被各种隐藏问题打脸。这篇文章适合谁看如果你的项目需要存储大量图片、音视频、办公文件这类中小型文件且不想直接上云、想在自建服务器上用一套轻量级方案那FastDFS是个很好的选择。如果你是运维或者后端开发需要在一个小时内把一个可用的分布式文件系统搭起来并对接到业务里这篇同样适用。我会从它为什么值得选、架构怎么分工、单机怎么搭、怎么测通、上生产要补什么、以及常见的坑这几个维度把整个链路讲透。1. 为什么是FastDFS轻量分布式文件存储的定位分析1.1 FastDFS能解决什么实际问题先聊一个最常见的业务痛点一个电商后台系统商品图片、用户头像、售后凭证加在一起每天产生上万个小文件。如果直接存在应用服务器的本地磁盘问题很快就会出现——磁盘不够用、应用扩容时文件没法跟着迁移、多台应用服务器之间文件不一致更麻烦的是用户上传的图片要通过HTTP访问时你总不能把内网磁盘路径直接暴露出去。FastDFS就是冲着这个场景来的。它是一个用C语言写的开源轻量级分布式文件系统专注做文件存储、同步和访问不负责复杂的POSIX文件语义也不搞数据块级别的计算。它擅长的恰恰是电商、内容社区、企业网盘这类海量中小文件、高并发写入和读取、文件基本只读不改的业务。我当初调研选型的时候对比过HDFS和FastDFS。HDFS是针对大文件批量处理的动辄几十MB甚至GB级别的文件分块存储光一个NameNode就要专门伺候放在图片存储场景纯属杀鸡用牛刀。FastDFS的文件最小粒度就是单个文件不切块直接通过路径定位设计目标就是在普通PC服务器上支撑高并发的小文件读写性能和部署成本都友好得多。1.2 同类方案对比FastDFS、SeaWeedFS、MinIO怎么选现在常见的小文件存储方案除了FastDFS还有SeaWeedFS和MinIO。我做了一张对比表方便你根据自己的场景判断方案架构复杂度性能表现生态/接口适合场景FastDFS中等TrackerStorage两角色需自建HTTP服务高纯内存索引文件位置单机可支撑数万并发读自有协议需配nginx模块支持HTTP电商图片、音视频文件、小规模私有云盘SeaWeedFS中等MasterVolume架构高设计理念与FastDFS类似兼容S3 API部分版本对S3接口有需求的自建存储MinIO简单单二进制分布式模式较高但元数据较重原生S3 API想用标准S3生态、对接对象存储应用选FastDFS的核心原因有三个。一是它非常轻编译完核心服务就两个tracker和storage不会引入一堆依赖组件二是元数据不落数据库文件名即路径查询和访问都快三是社区里针对FastDFS的nginx整合方案很成熟上传下载链路很容易打通。如果你的团队对S3协议有明确要求那MinIO可能更合适但如果只是给业务系统提供一个高可用的文件存储底座FastDFS在成本和效率之间平衡得最好。2. FastDFS工作原理拆解Tracker与Storage的协调机制2.1 两个角色的定位和边界FastDFS的架构其实很简单整个集群里只有两类节点。一类叫Tracker Server中文常叫跟踪服务器它不存实际文件数据只负责调度和维护集群状态另一类叫Storage Server存储服务器真正干体力活存文件的地方。你可以把Tracker想象成一个前台接待员。所有客户端上传文件时先找它问哪个仓库有空位它查一眼手里的台账告诉你去B仓库的3号货架放。前台不搬货但所有货物在哪个仓库、仓库还空多少位置它心里都有数。客户端下载文件时也找它它告诉你这个文件在C仓库2号货架你自己去取。Storage Server是存放数据的地方。一个Storage节点会归属于一个Group组同一个Group里的多个Storage会互相同步数据形成冗余备份。比如Group1里有两台Storage往其中一台写入一个文件后它会自动同步到另一台这样一台挂掉文件还能从同组的另一台读取。不同Group之间不互相备份它们的作用要么是水平扩容要么是隔离不同业务线或不同品质的文件比如原图和压缩图放不同组。2.2 一次上传和下载请求的完整往返理解了角色定位走一遍完整流程你就彻底通了。假设现在有业务服务器想上传一张图片客户端可以是Java、Go或C程序向Tracker发起上传请求。Tracker检查各Storage的心跳信息找到一台符合条件的Storage通常选同组内空闲率高的节点返回该节点的IP和端口。客户端拿着这个地址直接把文件内容发到对应Storage。Storage将文件写入磁盘同时返回一个文件标识符格式类似group1/M00/00/00/wKgBkFp1yhSAR6Z8AAAHWfHKbJk032.jpg。客户端保存这个标识符后续所有访问都基于它。下载的流程正好反过来客户端带着文件标识符比如group1/M00/00/00/wKgBkFp1yhSAR6Z8AAAHWfHKbJk032.jpg找Tracker说我要取这个文件。Tracker根据文件所在组和当前组内Storage的状态返回一个合适的Storage地址。客户端去该Storage上读取文件内容。整个机制的精妙之处在于文件的位置信息全部由Tracker动态决定业务层不需要维护任何文件与物理路径的映射关系。而且Tracker彼此之间也通过心跳同步信息可以部署多台Tracker做负载均衡和高可用客户端只需要配置多个Tracker地址即可。2.3 心跳机制与状态评估这里有个很多人会忽略的知识点Storage必须周期性向Tracker发送心跳默认每30秒一次。心跳包携带的信息包括该Storage所属组、剩余的可用空间、当前承载的文件总数等。Tracker正是基于这些信息判断哪个节点适合承接新写入。如果你遇到某个Storage文件总被路由过去但磁盘都快满了的情况大概率是没配置好reserved_storage_space这个参数。它表示预留的存储空间大小比如保留10GB或总空间的10%低于这个阈值后Tracker就不会再向这个节点分配新文件。我在生产环境里习惯把reserved_storage_space设置为磁盘总容量的15%防止磁盘写满导致文件系统崩溃。3. 零依赖单机搭建5分钟快速跑通全流程3.1 环境准备与依赖安装先说明一下这里说的零依赖是指不需要额外安装数据库之类的重量级组件但基础的编译环境还是要的。我使用的环境是CentOS 7.9x86_64架构你如果用Ubuntu或Debian包管理命令稍作替换即可。首先装编译工具和基础依赖yum install -y git gcc gcc-c make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl-devel里面的pcre和zlib后面编译nginx整合模块时会用到建议一次装齐省得后面反复折腾。然后用git拉取源码。FastDFS的官方仓库有两个libfastcommon公共基础库和fastdfs主程序。两者版本必须配套我实测最好都直接拉最新release分支避免老的master分支出现兼容问题。cd /usr/local/src git clone https://github.com/happyfish100/libfastcommon.git git clone https://github.com/happyfish100/fastdfs.git3.2 编译安装libfastcommon和FastDFS主体先编译libfastcommonFastDFS的很多底层数据结构、网络通信、日志模块都在这里面。编译过程很大概率会遇到错误错误信息多半是缺某个系统头文件或工具按提示补齐依赖即可cd libfastcommon ./make.sh sudo ./make.sh install这个库的安装脚本会把动态库和头文件放到/usr/lib64或/usr/lib目录下。装完后执行一句ldconfig命令更新动态链接库缓存。这一步非常关键我遇到过好多次新装的libfastcommon.so.6没被系统找到导致后面启动tracker报error while loading shared libraries错误原因就是没刷缓存或安装路径不在默认搜索路径里。如果你遇到类似错误可以执行sudo ldconfig接下来编译FastDFS主程序cd /usr/local/src/fastdfs ./make.sh sudo ./make.sh install安装完成后几个关键文件的位置如下可执行文件/usr/bin/fdfs_trackerd、/usr/bin/fdfs_storaged、/usr/bin/fdfs_upload_file、/usr/bin/fdfs_test默认配置模板目录/etc/fdfs/启动脚本/etc/init.d/fdfs_trackerd、/etc/init.d/fdfs_storaged在/etc/fdfs目录下能看到几个.conf.sample结尾的模板文件把它们复制成正式配置文件cd /etc/fdfs cp tracker.conf.sample tracker.conf cp storage.conf.sample storage.conf cp client.conf.sample client.conf3.3 配置Tracker一份靠谱的tracker.conf打开tracker.conf你需要关心的配置项就几处。空格前不允许有多余字符格式严格要求keyvalue注释用#。# 数据目录必须是已存在的目录 base_path/data/fastdfs/tracker # Tracker的HTTP服务端口用于监控页面新版默认8080 http.server_port8080建议目录单独规划不要把base_path放在根分区用独立数据盘更安全mkdir -p /data/fastdfs/tracker其他配置保持默认即可。默认端口是22122这个端口是客户端与Tracker的通信端口也是Storage向Tracker上报心跳的端口后面防火墙和云安全组都要放行。如果你有多台Tracker组成集群client.conf里把多个tracker_server分别列出来就行不需要额外的集群配置Tracker之间通过storage心跳自动感知彼此。3.4 配置Storage最容易出错的一步storage.conf是整套配置中坑最多的地方。关键项如下# 所属组名同一组内的多台Storage互为备份 group_namegroup1 # Storage的数据和日志目录 base_path/data/fastdfs/storage # 存储路径数量以及第一个存储路径 store_path_count1 store_path0/data/fastdfs/storage/data # 向Tracker注册的地址 tracker_server127.0.0.1:22122 # 预留空间改为磁盘容量的15%左右 reserved_storage_space15%有一个细节必须重点强调store_path0这个路径不是让你手动创建一个普通目录放那里就完了FastDFS会自动在这个目录下生成两级目录结构比如/data/fastdfs/storage/data下会创建00到FF共256个一级目录每个一级目录下再创建256个二级目录。这就是为什么你在上传后返回的路径里能看到M00/00/00/xxxxx其中M00是FastDFS对store_path的虚拟表示后面的00/00就是根据文件名哈希算出的子目录层级。创建这些目录mkdir -p /data/fastdfs/storage/data还有个容易被忽略的参数http.server_port默认8888。如果你打算让Storage自己直接对外提供HTTP下载服务那这个端口就得对外开放。不过我后面会建议用nginx来接管HTTP这个参数的意义就不大了。3.5 启动服务并验证进程启动顺序有讲究必须先启动Tracker再启动Storage因为Storage启动时需要向Tracker完成注册和心跳上报。启动方式推荐用官方脚本sudo /etc/init.d/fdfs_trackerd start sudo /etc/init.d/fdfs_storaged start首次启动后/data/fastdfs/目录下会出现对应的log目录。确认服务是否正常的命令ps -ef | grep fdfs ss -tlnp | grep -E 22122|23000看到tracker监听22122端口storage监听23000端口默认storage对外的数据传输端口基本就成功了一半。然后再看日志有没有报错tail -f /data/fastdfs/storage/logs/storaged.log如果看到类似tracker server: 127.0.0.1:22122, group_name: group1的注册成功信息说明Storage已经和Tracker建立连接了。此时你用fdfs_monitor命令能看到集群概览/usr/bin/fdfs_monitor /etc/fdfs/client.conf在输出中找到storage server count 1和ACTIVE字样整个单机集群就绪了。如果你在输出中看到OFFLINE先别急着排查防火墙大概率是Storage配置里的tracker_server地址写错或者Tracker的base_path路径有问题。4. 上传下载实测文件在整个链路里到底经历了什么4.1 配置client.confFastDFS自带的客户端工具也要一份配置主要是告诉工具去哪个Tracker注册。编辑client.conf# 日志目录 base_path/data/fastdfs/client # Tracker地址 tracker_server127.0.0.1:22122然后创建base_path目录mkdir -p /data/fastdfs/client4.2 用fdfs_upload_file上传文件准备好一个测试文件比如一张图片test.jpg执行上传命令/usr/bin/fdfs_upload_file /etc/fdfs/client.conf test.jpg如果一切正常命令行会返回一个文件ID类似group1/M00/00/00/wKgBkFp1yhSAR6Z8AAAHWfHKbJk032.jpg这就是FastDFS返回的文件唯一标识它由四部分组成组名、虚拟路径M00、目录哈希子路径、文件名。文件名包含了IP地址的base64编码和时间戳等信息所以基本不会冲突。你可以在storage目录下验证文件是否真的写入了ls -lh /data/fastdfs/storage/data/00/00/wKgBkFp1yhSAR6Z8AAAHWfHKbJk032.jpg注意看到没有M00并没有对应物理磁盘上的 M00目录它只是store_path0的虚拟映射符号。FastDFS通过这种映射关系屏蔽了物理路径的差异让文件ID保持稳定即使后来调整了存储路径旧的访问也不受影响。4.3 通过HTTP下载验证访问链路FastDFS的Storage本身集成了一个简单的HTTP服务。我在storage.conf里看到http.server_port8888这个服务默认是开启的。尝试直接用浏览器或curl下载刚上传的文件curl -v http://127.0.0.1:8888/group1/M00/00/00/wKgBkFp1yhSAR6Z8AAAHWfHKbJk032.jpg -o /tmp/downloaded.jpg如果返回200且文件内容一致说明fastdfs原始HTTP链路是通的。这个内置HTTP服务在小型测试环境够用但是它存在明显的短板不支持文件同步延迟期间的错误重定向即客户端可能访问到一个尚未同步到文件的Storage节点导致404。所以在真实生产环境里标配做法是使用我下一章要讲的nginx模块所有HTTP走nginx由模块内部根据文件位置自动代理由同组其他机器同步数据过来业务侧完全感知不到。还有一个很多人会踩的坑curl -v得到的响应头里可能会有一个Content-Length: 0或诡异的状态码原因是storage.conf里http.disabled默认是false但如果你把http.server_port配置到了已经被占用的端口下载就会异常。排查方法很简单先确认端口监听正常再确认storage日志里没有binding错误。5. 从能跑到可用生产环境的配置补全与扩展规划单机验证通过后距离生产可用还有一段路要补。这里我按自己实际部署的经验把所有必要的配置项和扩展思路拆开讲。5.1 用nginx统一HTTP访问入口为什么不用Storage自带的HTTP服务直接对外除了上面提到的同步重定向缺陷之外还有两个现实原因一是内置HTTP服务的性能跟nginx根本不在一个级别二是如果以后你在Storage前面挂CDN或者WAFnginx作为统一的入口更好做域名、缓存、限流的控制。FastDFS官方提供了一个配套模块fastdfs-nginx-module作用非常巧妙。它让nginx充当一个智能代理当请求的文件在本地Storage上不存在时比如文件刚上传到同组的另一台机器还没同步过来模块会计算出文件应在的Storage地址向这台Storage发起内部请求取数据返回给客户端本地有就直接serve。编译nginx时把这个模块加进去nginx版本建议用1.21或1.22稳定版。一个兼容性极佳的配置示例cd /usr/local/src wget https://nginx.org/download/nginx-1.22.1.tar.gz tar zxvf nginx-1.22.1.tar.gz cd nginx-1.22.1 ./configure --prefix/usr/local/nginx --add-module/usr/local/src/fastdfs-nginx-module/src make sudo make install编译好后把模块自带的配置文件放到/etc/fdfs下cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/mod_fastdfs.conf里需要改这几个关键项# 连接Tracker tracker_server127.0.0.1:22122 # 本机Storage的存储路径必须和storage.conf的store_path0一致 store_path0/data/fastdfs/storage/data # URL中需要带上group name url_have_group_nametrue然后在nginx配置里加一个server块我贴一段实际能跑的配置server { listen 80; server_name file.example.com; location /group1/M00 { alias /data/fastdfs/storage/data; ngx_fastdfs_module; } location /group2/M00 { alias /data/fastdfs/storage/data; ngx_fastdfs_module; } }这里有两个一定要记住的坑。第一个是alias路径必须和store_path0完全一致一旦不一致nginx会一直报404。第二个是ngx_fastdfs_module指令必须写在location里不能单独写在server层否则模块找不到正确的配置上下文。重启nginx后下载URL就变成http://file.example.com/group1/M00/00/00/wKgBkFp1yhSAR6Z8AAAHWfHKbJk032.jpg我建议把nginx和Storage部署在同一台机器上这样模块的内部代理请求走本机回环延迟极低如果机器不在同一台模块也能工作但每张图都会多一次内网转发性能有损耗。5.2 多Storage、多Group的扩展规划FastDFS的横向扩展有两种维度。第一种是往同一个Group里加Storage节点这样该组的存储容量基本不变但并发能力和数据安全性提升——同一份文件有了多副本读写吞吐和容灾能力都跟着上来。第二种是加新的Group比如增加Group2、Group3每新增一个Group就相当于容量翻倍组之间互相独立适合不同业务共用一套集群时做逻辑隔离。我上一家公司的基础架构就是这么规划的用户头像放在Group1商品图片放在Group2运营上传的素材放Group3。每个Group内两台Storage互相备份全部机器前面统一挂nginx做入口。因为文件ID里天然带着group名业务侧直接根据路径前缀路由到不同业务模块非常清晰。新增一台Storage节点时流程和单机搭建时的storage配置一样只需要把tracker_server指向集群里的Tracker并设置不同的group_name或加入已有group然后启动服务等它完成同步即可。Tracker会自动感知新节点并开始分配文件。5.3 防盗链与安全加固文件服务一旦开放公网访问盗链是绕不开的话题。FastDFS自带基于时间戳的token防盗链机制原理是客户端在生成下载URL时计算一个tokenFastDFS校验token和时间戳的合法性。这个过程中密钥只存在于服务端和业务服务器浏览器里的URL即使被复制出去过一段时间token过期后也无法再访问。开启防盗链需要在storage.conf里改三个参数http.anti_steal.check_tokentrue http.anti_steal.token_check_fail_content # 校验失败时返回的内容可留空返回403 http.secret_keyFastDFS1234567890token生成算法在官方文档里有明确说明md5(文件ID 时间戳 密钥)。以Java为例签名逻辑大致是String fileId group1/M00/00/00/wKgBkFp1yhSAR6Z8AAAHWfHKbJk032.jpg; long ts System.currentTimeMillis() / 1000; String token MD5(fileId ts FastDFS1234567890); String url http://file.example.com/ fileId ?token token ts ts;要注意生成签名的文件ID部分必须和URL里的路径部分完全一致大小写敏感多一个斜杠都不行。激活token校验后之前那种不带token直接访问图片的URL立即失效。防火墙层面至少放行三个端口Tracker的22122、Storage的数据端口23000多storage就放行这个范围的端口、nginx的80或443。另外如果启用了Storage自带的HTTP服务8888端口也要一并放行或直接禁用内置HTTP服务。6. 部署实施中的常见故障与排障实录这一节是我最想写的部分因为网上教程大多只讲到上传成功就结束了真实环境里的问题千奇百怪。我把几个典型的故障完整复盘一下大家以后遇到类似问题能少走弯路。6.1 Storage始终OFFLINE从日志反推配置错误有一次我在新环境部署fdfs_monitor输出里storage状态始终是OFFLINE。我当时第一反应是防火墙拦截了23000端口但检查防火墙规则后发现端口并没有被拦。排查链路是这样的先看storage.log里面一直重复connect to tracker server 10.0.0.5:22122 fail说明storage根本连不上tracker。telnet测试tracker的22122端口竟然是通的。仔细对比配置发现storage.conf里的tracker_server写成了10.0.0.5:22122但tracker.conf里的bind_addr绑定在了127.0.0.1上也就是说tracker只监听了本机回环地址外部IP的请求全部被拒。解决办法是让tracker监听所有网卡把tracker.conf里的bind_addr留空或者显式配置成0.0.0.0。这个问题的教训是不要把tracker的bind_addr配置成127.0.0.1除非你确定所有storage都在同一台机器上。生产环境我建议bind_addr留空让tracker自己绑定所有可用网卡。类似的还有多网卡服务器上的storage节点如果机器上存在多个IPstorage向tracker注册时会随机选一个IP上报可能导致tracker返回的下载地址客户端无法访问。解决办法是在storage.conf中明确设置bind_addr为自己的业务网卡IP同时client.conf里也要保持一致。6.2 上传成功但HTTP下载404nginx模块配置的连锁错误另一个非常典型的故障是用fdfs_upload_file上传文件返回了正常的文件ID但通过nginx访问时却返回404。这个坑我前前后后排查了将近一个小时。逐步定位过程直接访问Storage内置HTTP服务8888端口文件能正常打开说明文件本身没问题问题出在nginx环节。查看nginx错误日志发现报错信息是*1 the file (path:/data/fastdfs/storage/data/00/00/wKgBkFp1yhSAR6Z8AAAHWfHKbJk032.jpg) not found。去storage目录里查这个文件文件确实存在。那为什么nginx找不到后来发现nginx配置里用了root而不是alias。在location匹配到/group1/M00时如果用rootnginx会在root目录后面再拼接完整的URI路径也就是/data/fastdfs/storage/data/group1/M00/00/00/...但我实际配置的root路径是/data/fastdfs/storage/data拼接后的路径当然不存在。改成alias /data/fastdfs/storage/data问题解决。这个案例告诉我们nginx的root和alias在普通静态站点中差别不大但在fastdfs模块这种需要精确映射的路径下alias是唯一可靠的选择。另外url_have_group_nametrue这个配置也直接影响匹配行为如果你把它设成falseURL里就不带group1前缀location匹配规则又要相应调整。6.3 libfastcommon版本导致的诡异崩溃团队里另一个环境遇到的情况是FastDFS服务和nginx模块分别编译安装后storage偶尔异常退出查看core dump文件指向libfastcommon里的内存写操作。当时第一反应是磁盘坏了但最终定位到问题是libfastcommon版本和FastDFS主程序版本不一致。由于FastDFS的master分支迭代频繁旧版本主程序配新版本libfastcommon或反过来时数据结构的内存布局可能不兼容。最稳妥的做法是从同一个release tag下分别编译两者。我在环境上把libfastcommon和fastdfs的release版本对齐到同一时间点的tag比如V6.0.6配套重新编译后异常消失。建议大家在下载源码时直接用release分支不要盲目追master尤其不要混用不同时间点的代码。6.4 启动Storage时tracker连接超时还有一种隐蔽的情况Storage启动时提示connect to tracker server fail, errno: 110, error info: Connection timed out。检查网络端口没问题tracker也正常。最后发现是Storage和Tracker之间的防火墙规则只放行了TCP 22122但Tracker回应Storage的UDP包被丢弃了。虽然FastDFS的心跳和文件同步主要是TCP但它内部某些状态收集也用了UDP通信。把防火墙规则改成放行对应网段的全部双向流量后问题消失。6.5 文件同步延迟问题与group内节点一致性最后聊一个容易被忽视但生产必踩的坑当你往Group1的Storage_A上传完文件立即通过Storage_B的nginx下载有概率出现404或数据不一致。原因是FastDFS的文件同步是异步的storage之间的同步有延迟通常几秒到几十秒不等取决于文件大小和网络状况。解决思路主要有两个方向。方向一靠fastdfs-nginx-module的代理逻辑兜底。你访问Storage_B时如果本地没有这个文件模块会自动去同组其他节点拉取所以只要模块配置正确这个404就不会出现。这也是我强烈建议生产环境一定要用nginx模块而不是裸的Storage HTTP的原因。方向二业务层做小优化。上传完成后文件ID先写进数据库或缓存但不要让用户立刻通过B节点访问给同步留出几秒缓冲窗口。对于大数据量的历史文件迁移场景也可以主动调用FastDFS的fdfs_file_sync命令强制同步。最后说点实在的这次完整部署下来我最大的体会是FastDFS真正困难的地方不在于编译安装而在于理解它的两个角色分工和文件路由逻辑。你只要想通Tracker负责调度、Storage负责存储、文件ID包含位置信息这三个核心点后面无论是排查问题还是规划扩容思路都会清晰很多。如果你只是在测试环境里跑通后面对接业务时还建议把上传接口封装成独立服务统一处理文件ID生成、token签名、nginx地址拼接这些逻辑别在业务代码里散落一堆拼接URL的操作。集群上线前也务必做一次灾备演练手动kill掉一个Storage节点确认同组的另一个节点能正常接管读写同时观察Tracker会不会自动把文件分配策略调整到健康节点。做完这些你手里的FastDFS才算真正可用。
返回列表