踩坑无数!NFS服务从入门到放弃再到真香的血泪史

前言

说起NFS,我估计很多搞运维的兄弟都有一肚子话要说。这玩意儿吧,看起来简单,用起来坑多,但是真正搞明白了又觉得挺香的。

前几天有个朋友问我,说他们公司要搭建一个文件共享系统,问我推荐什么方案。我第一反应就是NFS,毕竟这货在Linux环境下用了这么多年,虽然毛病不少,但胜在稳定可靠。结果这哥们儿一脸懵逼地看着我:“NFS是啥?”

好吧,看来有必要写篇文章好好聊聊NFS了。我从2020年开始接触这东西,到现在也算是爱恨交加了。今天就把我这些年踩过的坑和积累的经验分享给大家。

NFS到底是个什么鬼

NFS全称Network File System,网络文件系统。简单来说,就是让你可以像访问本地文件一样访问远程服务器上的文件。听起来很牛逼对吧?实际上原理也不复杂。

NFS的工作原理其实就是客户端和服务端的通信。服务端把某个目录"导出"(export),客户端就可以把这个远程目录"挂载"(mount)到本地的某个挂载点上。挂载完成后,你在客户端操作这个目录,实际上就是在操作服务端的文件。

不过这里有个坑,NFS默认使用的是UDP协议,在网络不稳定的环境下容易出问题。现在一般都推荐用TCP,虽然性能稍微差一点,但稳定性好很多。

搭建NFS服务的那些事儿

服务端配置

在CentOS系统上安装NFS还是比较简单的:

yum install -y nfs-utils rpcbind

安装完成后需要启动相关服务:

systemctl start rpcbind
systemctl start nfs-server
systemctl enable rpcbind
systemctl enable nfs-server

这里要注意一个细节,rpcbind必须先启动,因为NFS依赖RPC服务。我之前就因为这个顺序问题折腾了半天。

接下来就是配置导出目录了,编辑/etc/exports文件:

/data/share 192.168.1.0/24(rw,sync,no_root_squash,no_subtree_check)
/home/backup 192.168.1.100(ro,sync,root_squash)

这个配置文件的语法看起来有点奇怪,但其实很好理解。第一行表示把/data/share目录共享给192.168.1.0/24网段的所有主机,权限是读写,同步写入,不压缩root权限。

说到权限配置,这里面的坑可不少。no_root_squash这个选项要慎用,它允许客户端的root用户在NFS服务器上也有root权限。如果你的网络环境不够安全,这就是个巨大的安全隐患。

配置完成后,重新加载配置:

exportfs -ra

可以用exportfs -v查看当前的导出状态。

客户端挂载

客户端的配置相对简单一些,同样需要安装nfs-utils:

yum install -y nfs-utils

然后就可以挂载了:

mount -t nfs 192.168.1.10:/data/share /mnt/nfs

不过我建议在挂载时指定一些参数:

mount -t nfs -o tcp,rsize=32768,wsize=32768,hard,intr 192.168.1.10:/data/share /mnt/nfs

这些参数的含义:

  • tcp:使用TCP协议
  • rsize/wsize:读写缓冲区大小
  • hard:硬挂载,网络中断时会一直重试
  • intr:允许中断

如果要开机自动挂载,可以在/etc/fstab中添加:

#添加完成一定要记得mount -a,检查下配置是否正确!!!!
192.168.1.10:/data/share /mnt/nfs nfs tcp,rsize=32768,wsize=32768,hard,intr 0 0

性能调优这个老大难问题

NFS的性能一直是个让人头疼的问题。我记得有一次,业务部门抱怨说文件传输太慢了,让我优化一下。当时我就想,这能有多慢?结果一测试,好家伙,传输速度只有几MB/s,这在千兆网络环境下简直不能忍。

网络层面的优化

网络配置对NFS性能影响很大。我发现很多人在配置时都忽略了网络参数的调整。

在服务端,可以增加NFS守护进程的数量:

# 编辑 /etc/sysconfig/nfs
RPCNFSDCOUNT=16

默认情况下,NFS只启动8个守护进程,在高并发场景下明显不够用。我一般会根据CPU核心数来设置,比如16核的服务器就设置16个进程。

另外,网络缓冲区的大小也很关键:

# 在 /etc/sysctl.conf 中添加
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216

存储层面的考虑

NFS的性能很大程度上取决于底层存储。如果你的服务器用的是机械硬盘,那性能肯定好不到哪里去。我之前在一个项目中,把NFS服务器的存储从SATA硬盘换成SSD,性能提升了好几倍。

文件系统的选择也很重要。ext4虽然稳定,但在大文件和高并发场景下性能一般。如果条件允许,我更推荐使用XFS文件系统,特别是在处理大文件时。

挂载参数的调整

客户端的挂载参数对性能影响也不小。我一般会这样配置:

mount -t nfs -o tcp,rsize=65536,wsize=65536,hard,intr,timeo=14,intr 192.168.1.10:/data/share /mnt/nfs

rsize和wsize设置得大一些可以减少网络往返次数,但也不能设置得太大,否则可能会出现网络包分片的问题。

安全配置不能马虎

NFS的安全性一直是个争议话题。说实话,NFS在设计之初就没有太多考虑安全问题,所以在使用时需要格外小心。

网络层面的安全

最基本的安全措施就是限制访问网段。在/etc/exports中,一定要明确指定允许访问的IP地址或网段,千万不要使用通配符。

我见过有人这样配置:

/data/share *(rw,sync,no_root_squash)

这简直就是在裸奔!任何能访问到你服务器的主机都可以挂载你的NFS共享,而且还有root权限。

正确的做法应该是:

/data/share 192.168.1.100(rw,sync,root_squash)
/data/share 192.168.1.101(rw,sync,root_squash)

防火墙配置

NFS使用的端口比较多,除了固定的111端口(rpcbind)和2049端口(nfs)外,还有一些随机端口。为了方便防火墙配置,可以固定这些端口。

/etc/sysconfig/nfs中添加:

RQUOTAD_PORT=875
LOCKD_TCPPORT=32803
LOCKD_UDPPORT=32769
MOUNTD_PORT=892
STATD_PORT=662

然后在防火墙中开放这些端口:

firewall-cmd --permanent --add-port=111/tcp
firewall-cmd --permanent --add-port=2049/tcp
firewall-cmd --permanent --add-port=875/tcp
firewall-cmd --permanent --add-port=32803/tcp
firewall-cmd --permanent --add-port=32769/udp
firewall-cmd --permanent --add-port=892/tcp
firewall-cmd --permanent --add-port=662/tcp
firewall-cmd --reload

用户权限管理

NFS的用户权限管理是个比较复杂的话题。默认情况下,NFS会根据UID和GID来判断用户权限,这就要求客户端和服务端的用户ID必须一致。

在实际使用中,我一般会创建专门的NFS用户:

# 在服务端和客户端都创建相同的用户
useradd -u 1001 nfsuser

然后把共享目录的所有者设置为这个用户:

chown -R nfsuser:nfsuser /data/share

故障排查的血泪经验

搞NFS这么多年,遇到的奇葩问题不计其数。有些问题看起来很简单,但排查起来却让人抓狂。

挂载失败的常见原因

最常见的问题就是挂载失败。每次遇到这种问题,我都会按照这个顺序排查:

  1. 检查网络连通性
ping 192.168.1.10
telnet 192.168.1.10 2049
  1. 检查服务状态
systemctl status rpcbind
systemctl status nfs-server
  1. 检查导出状态
exportfs -v
showmount -e 192.168.1.10

有一次我遇到一个很奇怪的问题,showmount可以看到导出的目录,但就是挂载不上。折腾了半天才发现是SELinux的问题。

setsebool -P nfs_export_all_rw 1
setsebool -P nfs_export_all_ro 1

性能问题的排查

性能问题相对比较难排查,因为影响因素太多了。我一般会从这几个方面入手:

网络层面,用iperf测试网络带宽:

# 服务端
iperf -s# 客户端
iperf -c 192.168.1.10

存储层面,用dd测试磁盘性能:

dd if=/dev/zero of=/data/share/testfile bs=1M count=1024

NFS层面,用nfsstat查看统计信息:

nfsstat -c  # 客户端统
nfsstat -s  # 服务端统计

有一次我就是通过nfsstat发现了问题,客户端的retrans(重传)次数特别高,说明网络有问题。后来发现是交换机的某个端口有故障。

文件锁的诡异问题

NFS的文件锁机制真的是让人又爱又恨。理论上很美好,实际使用中问题一大堆。

我印象最深的一次是,有个应用程序在NFS上创建了文件锁,结果服务器突然断电了。重启后,这个锁就一直释放不掉,导致应用程序无法正常工作。

当时试了各种方法,最后只能这样解决:

# 停止相关服务
systemctl stop nfs-server
systemctl stop rpc-statd# 清理锁文件
rm -rf /var/lib/nfs/sm/*
rm -rf /var/lib/nfs/sm.bak/*# 重启服务
systemctl start rpc-statd
systemctl start nfs-server

不过这种方法比较暴力,会影响所有客户端。在生产环境中要慎用!!!!!!!!!!!

实际应用场景的经验分享

这么多年下来,我在不同的场景中都用过NFS,每种场景都有自己的特点和坑点。

Web服务器集群的文件共享

最常见的应用就是Web服务器集群了。多台Web服务器需要共享静态文件,比如图片、CSS、JS等。

在这种场景下,我一般会这样配置:

# 服务端导出配置
/var/www/html/static 192.168.1.0/24(ro,sync,root_squash,no_subtree_check)

注意这里用的是只读权限,因为静态文件一般不需要在Web服务器上修改。如果需要上传文件,我会单独配置一个可写的目录。

客户端挂载时,我会使用这样的参数:

mount -t nfs -o tcp,ro,rsize=32768,wsize=32768,hard,intr,noatime 192.168.1.10:/var/www/html/static /var/www/html/static

noatime参数很重要,它可以避免每次读取文件时更新访问时间,能显著提升性能。

数据库备份的存储

另一个常见场景就是数据库备份。我们有多台数据库服务器,需要把备份文件统一存储到一个地方。

这种场景下,安全性比性能更重要:

# 服务端配置
/data/backup 192.168.1.100(rw,sync,root_squash,no_subtree_check)
/data/backup 192.168.1.101(rw,sync,root_squash,no_subtree_check)

客户端挂载时,我会设置比较保守的参数:

mount -t nfs -o tcp,rw,rsize=8192,wsize=8192,hard,intr,timeo=30 192.168.1.10:/data/backup /backup

缓冲区设置得小一些,超时时间长一些,确保数据的完整性。

开发环境的代码共享

在开发环境中,经常需要多个开发者共享代码。这时候NFS就很方便了,大家都可以直接在自己的机器上编辑代码。

不过这种场景下要注意权限问题。我一般会创建一个开发组:

groupadd -g 2000 developers

然后把所有开发者都加到这个组里,共享目录的权限设置为组可写:

chgrp -R developers /data/code
chmod -R g+w /data/code

NFS的替代方案思考

虽然我用NFS用了这么多年,但不得不承认,它确实有不少局限性。在某些场景下,其他方案可能更合适。

SSHFS的优势

SSHFS基于SSH协议,安全性比NFS好很多。配置也特别简单:

sshfs user@192.168.1.10:/data/share /mnt/sshfs

我在一些对安全性要求比较高的项目中会选择SSHFS。虽然性能比NFS差一些,但胜在安全可靠。

分布式文件系统的崛起

现在越来越多的公司开始使用分布式文件系统,比如GlusterFS、CephFS等。这些系统在可用性和扩展性方面比NFS强很多。

我之前参与过一个项目,就是把原来的NFS系统迁移到GlusterFS。虽然迁移过程比较复杂,但迁移完成后,系统的可用性确实提升了不少。

对象存储的兴起

在云计算时代,对象存储也是个不错的选择。比如AWS的S3、阿里云的OSS等。虽然访问方式和传统文件系统不太一样,但在某些场景下更适合。

一些实用的小技巧

这些年积累了不少NFS使用的小技巧,分享给大家:

自动挂载的配置

手动挂载NFS比较麻烦,可以配置自动挂载。安装autofs:

yum install -y autofs

编辑/etc/auto.master

/mnt/auto /etc/auto.nfs --timeout=60

创建/etc/auto.nfs

share -tcp,rw 192.168.1.10:/data/share

这样,当你访问/mnt/auto/share时,系统会自动挂载NFS。

监控脚本的编写

NFS服务的稳定性监控很重要,我写了个简单的监控脚本:

#!/bin/bash
NFS_SERVER="192.168.1.10"
NFS_PATH="/data/share"
MOUNT_POINT="/mnt/nfs"if ! mountpoint -q $MOUNT_POINT; thenecho "NFS not mounted, trying to mount..."mount -t nfs $NFS_SERVER:$NFS_PATH $MOUNT_POINT
fiif ! timeout 5 ls $MOUNT_POINT > /dev/null 2>&1; thenecho "NFS access failed, remounting..."umount -f $MOUNT_POINTmount -t nfs $NFS_SERVER:$NFS_PATH $MOUNT_POINT
fi

把这个脚本加到crontab里,每分钟执行一次,可以自动处理一些常见的NFS问题。

性能测试的方法

想要知道NFS的性能如何,可以用这个简单的测试:

# 写入测试
time dd if=/dev/zero of=/mnt/nfs/testfile bs=1M count=1024# 读取测试
echo 3 > /proc/sys/vm/drop_caches  # 清理缓存
time dd if=/mnt/nfs/testfile of=/dev/null bs=1M

这个测试虽然简单,但能大致反映NFS的性能水平。

踩过的坑和经验教训

说了这么多技术细节,最后想分享一些我踩过的坑,希望大家能避免。

不要忽视网络质量

有一次,业务部门反映NFS访问特别慢,我检查了服务器配置、存储性能,都没问题。最后发现是网络设备有问题,丢包率达到了5%。在这种网络环境下,NFS的性能肯定好不了。

所以在部署NFS之前,一定要先测试网络质量。

备份配置文件的重要性

还有一次,我在调整NFS配置时,不小心把/etc/exports文件搞坏了。结果所有客户端都挂载不上了,业务直接中断。

幸好我有备份配置文件的习惯,很快就恢复了。从那以后,我每次修改配置前都会先备份:

cp /etc/exports /etc/exports.bak.$(date +%Y%m%d)

权限问题要提前规划

NFS的权限管理比较复杂,如果不提前规划好,后期会很麻烦。我建议在部署之前就把用户权限体系设计好,包括用户ID的分配、组的设置等。

监控和告警不能少

NFS服务虽然相对稳定,但也会出现各种问题。一定要做好监控和告警,及时发现问题。

我一般会监控这些指标:

  • NFS服务的运行状态
  • 挂载点的可用性
  • 网络连通性
  • 磁盘空间使用率

总结

写了这么多,感觉还有很多东西没有涉及到。NFS这个东西,说简单也简单,说复杂也复杂。关键是要在实践中不断积累经验。

我的建议是:

  1. 在内网环境下使用,不要暴露到公网
  2. 做好安全配置,不要图省事给过大权限
  3. 根据实际场景调整性能参数
  4. 做好监控和备份,及时发现和解决问题
  5. 在高可用要求的场景下考虑其他方案

NFS虽然有这样那样的问题,但在合适的场景下,它依然是个不错的选择。特别是在中小型企业的内网环境中,NFS的简单易用还是很有优势的。

当然,技术在不断发展,新的文件共享方案也在不断涌现。我们要保持学习的心态,根据实际需求选择最合适的方案。

希望这篇文章能帮到正在使用或者准备使用NFS的朋友们。如果你们在使用过程中遇到什么问题,或者有更好的经验分享,欢迎在评论区交流讨论!

记得关注微信公众号@运维躬行录,我会持续分享更多实用的运维经验和技术干货。如果这篇文章对你有帮助,别忘了点赞转发,让更多的朋友看到!
公众号:运维躬行录
个人博客:躬行笔记

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90768.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90768.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

矩阵谱分解的证明及计算示例

1. 矩阵谱分解的条件矩阵的谱分解&#xff08;也称为特征分解&#xff09;是将一个矩阵分解为一系列由其特征向量和特征值构成的矩阵乘积的过程。进行谱分解的前提条件包括&#xff1a;<1.> 矩阵是可对角化的&#xff08;Diagonalizable&#xff09;&#xff0c;即矩阵存…

Leetcode 07 java

169. 多数元素 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。 多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&a…

CS231n-2017 Lecture6训练神经网络(一)笔记

本节主要讲的是模型训练时的算法设计数据预处理&#xff1a;关于数据预处理&#xff0c;我们有常用的3个符号&#xff0c;数据矩阵X&#xff0c;假设其尺寸是&#xff0c;N是数据样本的数量&#xff0c;D是数据的维度均值减法(Mean subtraction)&#xff1a;是预处理最常用的形…

C++ 中实现 `Task::WhenAll` 和 `Task::WhenAny` 的两种方案

&#x1f4da; C 中实现 Task::WhenAll 和 Task::WhenAny 的两种方案 引用&#xff1a; 拈朵微笑的花 想一番人世變換 到頭來輸贏又何妨日與夜互消長 富與貴難久長 今早的容顏老於昨晚C 标准库异步编程示例&#xff08;一&#xff09;C TAP&#xff08;基于任务的异步编程…

【学习】Codeforces Global Round 15 C. Maximize the Intersections

题意&#xff1a;给出一个圆&#xff0c;顺时针排布1~2*n&#xff0c;已知连了k条边&#xff0c;问这个圆最好情况下有多少个线的交点&#xff0c;要求线与线之间不能有重复的连接点&#xff0c;也就是每个点只能被一条线连接 思路&#xff1a; 1.考虑没有线的时候&#xff0…

图论:Dijkstra算法

昨天介绍了最小生成树的两个算法&#xff0c;最小生成树的两个算法旨在求解无向有权图中的最小代价联通图的问题&#xff0c;那么对于有向有权图&#xff0c;从起点到终点的最小花费代价问题就可以用 Dijkstra 算法来解决而且Dijkstra算法可以求出来从起始点开始到所有节点的最…

WPFC#超市管理系统(2)顾客管理、供应商管理、用户管理

超市管理系统3. 顾客管理3.1 顾客新增3.2 DataGrid样式3.3 顾客删除3.4 顾客修改4. 供应商管理4.1 供应商管理主界面4.2 新增供应商4.3 修改供应商5. 用户管理5.1 用户管理主界面5.2 新增用户5.3 修改用户总结3. 顾客管理 在CustomerView.xaml使用命令绑定方式添加页面加载Loa…

Windows本地部署DeepSeek

1、Ollama1、下载Ollama安装包https://ollama.com/download&#xff08;如果下载很慢 可以直接找我拿安装包&#xff09;2、使用命令行安装打开cmd 将下载的安装包OllamaSetup.exe 放到想要安装的目录下。&#xff08;如果直接双击&#xff0c;会装到C盘&#xff09;例如想装到…

基于Python的新闻爬虫:实时追踪行业动态

引言 在信息时代&#xff0c;行业动态瞬息万变。金融从业者需要实时了解政策变化&#xff0c;科技公司需要跟踪技术趋势&#xff0c;市场营销人员需要掌握竞品动向。传统的人工信息收集方式效率低下&#xff0c;难以满足实时性需求。Python爬虫技术为解决这一问题提供了高效方…

阿里视频直播解决方案VS(MediaMTX + WebRTC) 流媒体解决方案

背景&#xff1a; 公司采购了新的摄像头&#xff0c;通过rtsp或者rtmp推流到云平台&#xff0c;云平台内部进行转码处理&#xff0c;客户端使用HLS或HTTP-FLV播放&#xff0c;移动App可能使用HLS或私有SDK&#xff0c;超低延时则采用WebRTC。 技术选型&#xff1a; RTSP&…

day33:零基础学嵌入式之网络——TCP并发服务器

一、服务器1.服务器分类单循环服务器&#xff1a;只能处理一个客户端任务的服务器并发服务器&#xff1a;可同时处理多个客户端任务的服务器二、TCP并发服务器的构建1.如何构建&#xff1f;&#xff08;1&#xff09;多进程&#xff08;每一次创建都非常耗时耗空间&#xff0c;…

VR全景制作的流程?VR全景制作可以用在哪些领域?

VR全景制作的流程&#xff1f;VR全景制作可以用在哪些领域&#xff1f;VR全景制作&#xff1a;流程、应用与未来虚拟现实&#xff08;VR&#xff09;全景制作正迅速改变我们的感官体验&#xff0c;使我们能够身临其境地探索虚拟世界&#xff0c;享受沉浸式的奇妙感受。那么&…

用LangChain重构客服系统:腾讯云向量数据库+GPT-4o实战

人们眼中的天才之所以卓越非凡&#xff0c;并非天资超人一等而是付出了持续不断的努力。1万小时的锤炼是任何人从平凡变成超凡的必要条件。———— 马尔科姆格拉德威尔 目录 一、传统客服系统痛点与重构价值 1.1 传统方案瓶颈分析 1.2 新方案技术突破点 二、系统架构设计&…

主要分布在腹侧海马体(vHPC)CA1区域(vCA1)的混合调谐细胞(mixed-tuning cells)对NLP中的深层语义分析的积极影响和启示

腹侧海马体CA1区&#xff08;vCA1&#xff09;的混合调谐细胞&#xff08;mixed-tuning cells&#xff09;通过整合情感、社会关系、空间概念等多模态信息&#xff0c;形成动态的情景化语义表征&#xff0c;为自然语言处理&#xff08;NLP&#xff09;的深层语义分析提供了重要…

ESP32的ADF详解:6. Audio Processing的API

一、Downmix 1. 核心功能 将基础音频流和新加入音频流混合为单一输出流&#xff0c;支持动态增益控制和状态转换。输出声道数与基础音频一致&#xff0c;新加入音频自动转换声道匹配。2. 关键特性声道处理 输出声道数 基础音频声道数新加入音频自动转换声道&#xff08;如立体…

Qt(基本组件和基本窗口类)

一、基本组件1. Designer设计师为什么要上来先将这个东西呢&#xff0c;这个是QT外置的设计界面的工具&#xff0c;没啥用&#xff0c;所以了解一下。我们用的多的是QT内置的界面设计&#xff0c;只需要我们双击我们创建的项目的.ui文件就可以进入这个界面&#xff0c;你对界面…

docker与k8s的容器数据卷

Docker容器数据卷 特性 docker镜像由多个只读层叠加而成&#xff0c;启动容器时&#xff0c;Docker会加载只读镜像层并在镜像栈顶部添加一个读写层。如果运行中的容器修改了现有的一个已经存在的文件&#xff0c;那么该文件将会从读写层下面的只读层复制到读写层&#xff0c;该…

自然语言处理技术应用领域深度解析:从理论到实践的全面探索

1. 引言:自然语言处理的技术革命与应用前景 自然语言处理(Natural Language Processing,NLP)作为人工智能领域的核心分支,正在以前所未有的速度改变着我们的数字化生活。从最初的规则基础系统到如今基于深度学习的大语言模型,NLP技术经历了从理论探索到实际应用的深刻变…

OpenGLRender开发记录(二): 阴影(shadowMap,PCF,PCSS)

目录已实现功能阴影shadowMapPCFPCSS实现shadowMapPCFPCSS阴影GitHub主页&#xff1a;https://github.com/sdpyy1 OpenGLRender:https://github.com/sdpyy1/CppLearn/tree/main/OpenGL 已实现功能 除了上次实现IBL之外&#xff0c;项目目前新增了imGUI的渲染&#xff0c;更方便…

Linux:日志乱码

1、Linux日志乱码可能是XShell客户端编码没设置为UTF-8引起的&#xff0c;按照以下步骤&#xff0c;设置终端格式&#xff1a;中文版&#xff1a;打开Xshell会话属性&#xff08;文件→属性→终端→编码&#xff09;&#xff0c;选择与服务器一致的编码格式&#xff08;如UTF-8…