Web 架构中的共享存储:NFS 部署与用户压缩
《NFS 存储服务从入门到实战》
🎯 目标
- 理解存储在网站架构中的作用
- 掌握 NFS 的原理与核心配置
- 能独立部署 NFS 服务并实现安全挂载
- 理解用户压缩机制与权限映射
- 实现多服务器共享存储场景
- 了解存储与备份的关系及后续演进方向
一、什么是存储?为什么需要它?
1. 存储的定义
存储 是指专门用于集中存放用户上传数据(如图片、视频、文件等)的服务或设备,在 Web 集群架构中通常位于“后排”,为前端 Web 服务器提供统一的数据访问接口。
2. 为什么使用存储?
场景 | 不使用存储 | 使用存储 |
---|---|---|
用户上传头像 | 头像保存在某台 Web 服务器上 | 所有 Web 服务器通过挂载访问同一份数据 |
下次访问 | 可能被负载均衡到另一台无该文件的服务器 → 文件丢失 | 无论访问哪台服务器,都能读取到头像 |
🔍 结论:
在集群环境中,必须使用共享存储,否则会导致用户数据无法一致访问。
3. 存储在网络架构中的位置
[用户] ↓
[负载均衡器] ↓
[Web01] ——→ 共享存储(NFS/OSS/MinIO)
[Web02]
[Web03]
✅ 存储处于“后排”,Web 层通过网络挂载或 API 访问。
二、存储的分类
类型 | 说明 | 示例 |
---|---|---|
硬件存储 | 专用存储设备,硬盘多、性能高 | SAN、NAS 设备 |
开源软件存储 | 利用普通服务器搭建的共享存储系统 | NFS(Linux)、Samba(Windows)、GlusterFS、Ceph、FastDFS、MinIO |
云产品存储 | 公有云提供的对象存储服务 | 阿里云 OSS、腾讯云 COS、华为云 OBS、七牛云 Kodo |
💡 选择建议:
- 小型项目 → NFS
- 中大型集群 → 分布式存储(MinIO/GlusterFS)
- 上云环境 → 对象存储(OSS/COS)
三、NFS 原理详解 ⭐⭐⭐⭐⭐
1. 什么是 NFS?
NFS(Network File System):网络文件系统,允许客户端像访问本地目录一样访问远程服务器上的文件。
适用于局域网内 Linux 服务器之间的文件共享。
2. NFS 的两个核心服务
服务 | 作用 |
---|---|
nfs | 提供文件共享功能 |
rpcbind (原 portmap ) | RPC 远程过程调用的端口映射服务(CentOS 6+ 使用 rpcbind ) |
⚠️ 启动顺序:先启动
rpcbind
,再启动nfs
,否则注册失败!
3. 工作流程图解(简化版)
[Client] ←RPC协议→ [rpcbind] ←→ [NFS Daemon] ←→ [/share_data/ 目录]
- 客户端发起请求 → rpcbind 查询 NFS 使用的端口 → 建立连接 → 操作共享目录
四、极速上手:NFS 部署实战
1. 环境准备
角色 | 主机名 | IP 地址 | 功能 |
---|---|---|---|
NFS 服务端 | nfs01 | 192.168.130.61 | 提供共享目录 /share_data |
NFS 客户端 | web01 | 192.168.130.62 | 挂载 /share_data 到 /mnt |
NFS 客户端 | web02 | 192.168.130.65 | 同上 |
📌 网段:
192.168.130.0/24
2. 服务端部署步骤
(1)安装软件包
yum install -y nfs-utils rpcbind
(2)启动服务(注意顺序)
# 先启动 rpcbind
systemctl enable --now rpcbind
systemctl status rpcbind# 再启动 nfs
systemctl enable --now nfs
(3)检查服务状态
# 查看 RPC 注册的服务
rpcinfo -p# 查看本机共享目录
showmount -e localhost
(4)配置共享目录 /etc/exports
echo "/share_data 192.168.130.0/24(rw,sync,all_squash)" >> /etc/exports
✅ 格式说明:
<共享目录> <客户端IP或网段>(权限选项)
(5)创建共享目录并授权
mkdir /share_data
chown nfsnobody:nfsnobody /share_data
(6)重新加载配置
exportfs -r
# 或 systemctl reload nfs
⚠️ 推荐使用
exportfs -r
,避免客户端夯住。
(7)本地测试挂载
mount -t nfs 192.168.130.61:/share_data /mnt
touch /mnt/test.txt && echo "OK" > /mnt/test.txt
umount /mnt
3. 客户端挂载
(1)安装工具
yum install -y nfs-utils
❗ 注意:无需启动
nfs
服务,只需工具支持挂载。
(2)临时挂载
mount -t nfs 192.168.130.61:/share_data /mnt
(3)永久挂载
写入 /etc/fstab
# 编辑 /etc/fstab
echo "192.168.130.61:/share_data /mnt nfs defaults,_netdev 0 0" >> /etc/fstab
⚠️ 必须加
_netdev
,确保网络就绪后再挂载。
(4)验证挂载
df -Th | grep nfs
touch /mnt/client_test.txt
五、核心配置文件详解
1. /etc/exports
:主配置文件
字段 | 说明 |
---|---|
第一部分 | 共享目录路径(如 /share_data ) |
第二部分 | 客户端地址 + 括号内的权限选项 |
支持的客户端地址格式:
格式 | 示例 | 说明 |
---|---|---|
网段 | 192.168.130.0/24 | 最常用 |
单个 IP | 192.168.130.62 | 精确控制 |
域名 | nfs.freed.com | 需 DNS 解析支持 |
2. 常见权限选项 ⭐⭐⭐⭐⭐
参数 | 说明 |
---|---|
rw | 读写权限(生产常用) |
ro | 只读权限 |
sync | 同步写入磁盘(推荐,数据更安全) |
async | 异步写入内存(性能高,但断电可能丢数据) |
🧠 同步 vs 异步类比:
- 同步:老师挨个问每个学生是否要上厕所 → 实时处理
- 异步:画个圈,想去的人站进去,定时带一批走 → 高效但延迟
3. 用户压缩(User Squash)机制 ⭐⭐⭐⭐⭐
NFS 默认会对客户端用户进行“压缩”处理,防止 root 权限滥用。
参数 | 说明 |
---|---|
root_squash | 客户端 root 用户映射为 nfsnobody (默认开启) |
no_root_squash | root 用户保持 root 权限(危险!慎用) |
all_squash | 所有用户都压缩为匿名用户 |
anonuid=UID , anongid=GID | 指定匿名用户的 UID/GID |
4. 用户压缩实战案例:统一使用 www
用户
需求描述
- 所有客户端上传文件,服务端统一归属为
www
用户 - UID/GID = 1999
- 共享目录:
/nfsdata
- 客户端挂载点:
/upload-pic
实施步骤
(1)所有机器创建 www
用户
useradd -u 1999 -s /sbin/nologin -M www
(2)服务端配置 /etc/exports
echo "/nfsdata 192.168.130.0/24(rw,sync,all_squash,anonuid=1999,anongid=1999)" >> /etc/exports
(3)创建目录并授权
mkdir /nfsdata
chown www:www /nfsdata
exportfs -r
(4)客户端挂载测试
mkdir /upload-pic
mount -t nfs 192.168.130.61:/nfsdata /upload-pic
touch /upload-pic/test.txt
ll /upload-pic/
# 应显示 owner=www
六、NFS 优化与安全建议
1. 安全挂载选项(客户端设置)
mount -o noexec,nosuid,nodev -t nfs 192.168.130.61:/share_data /video
选项 | 作用 |
---|---|
noexec | 禁止执行程序 |
nosuid | 禁止 SUID 权限提升 |
nodev | 禁止设备文件 |
✅ 适合存放静态资源(如图片、视频),防止恶意脚本执行。
2. 性能优化建议
- 使用 SSD 提升 I/O 性能
- 网络千兆以上,减少延迟
- 避免大文件频繁读写
- 客户端增加缓存(如
actimeo=60
)
3. 单点故障应对方案
方案 | 说明 |
---|---|
备用 NFS 节点 | 手动切换 IP 或 DNS |
分布式存储替代 | GlusterFS、MinIO、Ceph(推荐) |
使用对象存储 | 阿里云 OSS、腾讯云 COS(适合上云) |
📌 研究方向:GlusterFS、MinIO、Ceph
七、相关配置文件汇总
文件 | 作用 |
---|---|
/etc/exports | NFS 服务端主配置文件 |
/var/lib/nfs/etab | 当前生效的导出配置(由 exportfs 生成) |
/proc/mounts | 当前系统的挂载信息 |
/etc/fstab | 开机自动挂载配置 |
八、常见排错命令
命令 | 用途 |
---|---|
rpcinfo -p [IP] | 检查 NFS 服务是否注册成功 |
showmount -e [IP] | 查看服务端共享了哪些目录 |
df -h | 查看是否挂载成功 |
tail /var/log/messages | 查看系统日志报错 |
exportfs -v | 查看当前导出的共享目录详情 |
九、总结
核心知识点 | 说明 |
---|---|
为何使用存储? | 解决集群环境下用户数据一致性访问问题 |
NFS 原理 | 基于 RPC 协议的网络文件系统,依赖 rpcbind + nfs 服务 |
部署流程 | 安装 → 启动 rpcbind → 启动 nfs → 配置 /etc/exports → 创建目录 → 客户端挂载 |
权限控制 | rw/ro , sync/async |
用户压缩 | root_squash , all_squash , anonuid/anongid 是关键 |
安全挂载 | 使用 noexec,nosuid,nodev 提升安全性 |
单点风险 | NFS 有单点故障,建议后期升级为分布式存储 |
十、存储与备份的串联
场景 | 方案 |
---|---|
日常存储 | 使用 NFS 提供共享目录 |
定期备份 | 结合 rsync + cron 将 /share_data 备份到另一台服务器 |
异地容灾 | 将 NFS 数据同步至对象存储(如 OSS) |
实时同步 | 使用 inotify + rsync 或 sersync 实现变更自动同步 |
灾难恢复 | 备份保留多个版本(如 tar + date ),配合 md5sum 校验完整性 |
示例:每日备份脚本
#!/bin/bash
DATE=$(date +%F_%H-%M)
BACKUP_DIR="/backup/$(hostname)"
SRC_DIR="/share_data/"mkdir -p $BACKUP_DIRtar czf $BACKUP_DIR/share_data-$DATE.tar.gz $SRC_DIR
md5sum $BACKUP_DIR/share_data-$DATE.tar.gz > $BACKUP_DIR/share_data-$DATE.md5# 清理7天前备份
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete
💡 理念:
存储解决“访问一致性”问题,备份解决“数据安全性”问题,两者缺一不可。