Linux命令-nfsstat(列出NFS客户端和服务器的工作状态)

nfsstat 是 Linux 中一个监控 NFS(Network File System)协议活动的命令行工具。它通过读取内核维护的 NFS 统计信息,提供 RPC(远程过程调用)层和 NFS 层的详细性能数据,是 NFS 性能调优和故障排查的重要工具。

📦 安装方法

nfsstat 通常包含在 nfs-utilsnfs-common 软件包中:

bash 复制代码
# Debian/Ubuntu 系统
sudo apt update && sudo apt install nfs-common

# RHEL/CentOS 系统
sudo dnf install nfs-utils

# Arch Linux 系统
sudo pacman -S nfs-utils

安装后验证版本:

bash 复制代码
nfsstat --version

📖 基本语法

bash 复制代码
nfsstat [选项] [间隔时间 [次数]]

默认行为:如果不指定选项,默认显示客户端和服务器端的 NFS 和 RPC 统计信息。

🎯 常用选项

选项 说明
-c 显示客户端统计信息。
-s 显示服务器端统计信息。
-n 显示 NFS 统计信息(按版本)。
-r 显示 RPC 统计信息。
-a 显示 NFS_ACL 信息。
-z 重置统计计数器为零。
-m 显示每个 NFS 挂载文件系统的统计信息。
-v 版本 指定 NFS 版本(2/3/4),如 -v 4
-l 实时监控模式(默认间隔 5 秒)。
`-T u d`

📊 输出字段详解

1. RPC 服务器端统计
复制代码
Server rpc:
Connection oriented:
    calls       被接收的 RPC 调用总数
    badcalls    被 RPC 层拒绝的调用总数
    nullrecv    当认为 RPC 调用被接收时,RPC 调用不可用的次数
    badlen      长度短于 RPC 调用最小大小的 RPC 调用数目
    xdrcall     报头不能进行 XDR 解码的 RPC 调用数目
    dupchecks   在重复请求高速缓存中查询的 RPC 调用数目
    dupreqs     被找到的重复 RPC 调用数目
2. RPC 客户端统计
复制代码
Client rpc:
    calls       产生的 RPC 调用总数
    badcalls    被 RPC 层拒绝的调用总数
    badxid      不对应于任何未完成调用、从服务器接收的应答次数
    timeouts    在等待从服务器返回的应答时,调用超时的次数
    newcreds    认证信息必须被刷新的次数
    badverfs    在响应中由于验证字符无效而导致调用失败的次数
3. NFS 操作统计(按版本)

NFS 操作按版本(v2/v3/v4)显示,包括:

  • null:空操作(测试连接)
  • getattr:获取文件属性
  • setattr:设置文件属性
  • lookup:查找文件
  • read:读取文件
  • write:写入文件
  • create:创建文件
  • remove:删除文件
  • rename:重命名文件
  • readdir:读取目录
  • 等等...

💡 核心用法示例

1. 查看完整统计信息
bash 复制代码
# 查看客户端和服务器端的完整统计信息(默认)
nfsstat

# 查看客户端统计信息
nfsstat -c

# 查看服务器端统计信息
nfsstat -s

# 查看 NFS 统计信息(按版本)
nfsstat -n

# 查看 RPC 统计信息
nfsstat -r

# 查看所有信息(包括 NFS_ACL)
nfsstat -a
2. 查看特定 NFS 版本统计
bash 复制代码
# 查看 NFSv3 统计信息
nfsstat -v 3

# 查看 NFSv4 统计信息
nfsstat -v 4

# 查看客户端 NFSv3 统计
nfsstat -c -v 3

# 查看服务器端 NFSv4 统计
nfsstat -s -v 4
3. 实时监控模式
bash 复制代码
# 实时监控,默认5秒刷新一次
nfsstat -l

# 实时监控,指定2秒刷新间隔
nfsstat -l 2

# 实时监控客户端统计
nfsstat -c -l

# 实时监控服务器端统计,3秒间隔
nfsstat -s -l 3
4. 查看挂载点统计信息
bash 复制代码
# 查看所有 NFS 挂载点的统计信息
nfsstat -m

# 查看特定挂载点的统计信息
nfsstat -m /mnt/nfs
nfsstat -m /data /home

# 查看挂载点详细信息(包括服务器、标志、重传计数等)
nfsstat -m | head -20
5. 重置统计计数器
bash 复制代码
# 重置所有统计计数器
nfsstat -z

# 重置客户端统计
nfsstat -c -z

# 重置服务器端统计
nfsstat -s -z

# 重置特定版本统计
nfsstat -v 3 -z
6. 组合使用选项
bash 复制代码
# 查看客户端 NFS 和 RPC 统计
nfsstat -c -n -r

# 查看服务器端 NFSv4 和 ACL 统计
nfsstat -s -v 4 -a

# 以数字形式显示(不解析主机名)
nfsstat -n

🔍 输出解读示例

示例1:服务器端统计输出
bash 复制代码
nfsstat -s

输出示例:

复制代码
Server rpc:
Connection oriented:
    calls          719949194
    badcalls       0
    nullrecv       0
    badlen         0
    xdrcall        0
    dupchecks      58478624
    dupreqs        33

Server NFSv3:
    calls          132880073
    badcalls       0
    null           1365467   0%
    getattr        496667075 68%
    setattr        8864191   1%
    lookup         66510206  9%
    access         19131659  2%
    read           80123469  10%
    write          18740690  2%
    create         4135195   0%
    ...

关键指标分析

  • badcalls:应为0或接近0,高值表示RPC问题
  • timeouts:客户端超时次数,高值表示网络延迟
  • getattr 比例:通常最高,文件属性获取操作
  • read/write 比例:反映实际数据传输量
示例2:挂载点统计输出
bash 复制代码
nfsstat -m

输出示例:

复制代码
/mnt/nfs from 192.168.1.100:/export/data
 Flags: rw,relatime,vers=3,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.1.100,mountvers=3,mountport=635,mountproto=udp,local_lock=none,addr=192.168.1.100
 Attr cache: acregmin=3,acregmax=60,acdirmin=30,acdirmax=60

关键信息

  • 服务器地址192.168.1.100:/export/data
  • NFS版本vers=3
  • 读写大小rsize=131072,wsize=131072
  • 超时设置timeo=600(600毫秒)
  • 重传次数retrans=2
  • 属性缓存:文件属性缓存时间

🔧 实用场景示例

场景1:NFS性能监控脚本
bash 复制代码
#!/bin/bash
# NFS性能监控脚本

LOG_FILE="/var/log/nfs_monitor.log"
INTERVAL=30  # 监控间隔(秒)
ALERT_THRESHOLD=10  # 错误率阈值(%)

echo "开始NFS性能监控 $(date)" >> "$LOG_FILE"
echo "监控间隔: ${INTERVAL}秒" >> "$LOG_FILE"
echo "错误率警报阈值: ${ALERT_THRESHOLD}%" >> "$LOG_FILE"
echo "======================================" >> "$LOG_FILE"

monitor_nfs() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    echo "[$timestamp] NFS状态监控:" >> "$LOG_FILE"
    
    # 1. 检查NFS挂载状态
    echo "  1. NFS挂载点检查:" >> "$LOG_FILE"
    if mount | grep -q "type nfs"; then
        mount | grep "type nfs" | while read line; do
            local mount_point=$(echo "$line" | awk '{print $3}')
            local server=$(echo "$line" | awk '{print $1}')
            echo "    ✓ $mount_point (服务器: $server)" >> "$LOG_FILE"
        done
    else
        echo "    ⚠ 未发现NFS挂载点" >> "$LOG_FILE"
    fi
    
    # 2. 获取NFS统计信息
    echo "  2. NFS统计信息:" >> "$LOG_FILE"
    
    # 客户端统计
    local client_stats=$(nfsstat -c 2>/dev/null)
    if [ $? -eq 0 ]; then
        # 提取关键指标
        local client_calls=$(echo "$client_stats" | grep -A5 "Client rpc:" | grep "calls" | awk '{print $2}')
        local client_badcalls=$(echo "$client_stats" | grep -A5 "Client rpc:" | grep "badcalls" | awk '{print $2}')
        local client_timeouts=$(echo "$client_stats" | grep -A5 "Client rpc:" | grep "timeouts" | awk '{print $2}')
        
        if [ -n "$client_calls" ] && [ "$client_calls" -gt 0 ]; then
            local error_rate=$(echo "scale=2; $client_badcalls * 100 / $client_calls" | bc)
            echo "    客户端RPC调用: $client_calls" >> "$LOG_FILE"
            echo "    客户端错误调用: $client_badcalls" >> "$LOG_FILE"
            echo "    客户端超时次数: $client_timeouts" >> "$LOG_FILE"
            echo "    客户端错误率: ${error_rate}%" >> "$LOG_FILE"
            
            # 错误率警报
            if [ $(echo "$error_rate > $ALERT_THRESHOLD" | bc) -eq 1 ]; then
                echo "    [警报] 客户端错误率超过阈值: ${error_rate}% > ${ALERT_THRESHOLD}%" >> "$LOG_FILE"
            fi
        fi
    fi
    
    # 3. 检查挂载点性能
    echo "  3. 挂载点性能检查:" >> "$LOG_FILE"
    nfsstat -m 2>/dev/null | while read line; do
        if echo "$line" | grep -q "from "; then
            local mount_info=$(echo "$line")
            echo "    $mount_info" >> "$LOG_FILE"
            
            # 检查重传次数
            local retrans=$(echo "$line" | grep -o "retrans=[0-9]*" | cut -d= -f2)
            if [ -n "$retrans" ] && [ "$retrans" -gt 5 ]; then
                echo "    [警告] 重传次数过高: $retrans" >> "$LOG_FILE"
            fi
        fi
    done
    
    # 4. 检查NFS服务状态
    echo "  4. NFS服务状态:" >> "$LOG_FILE"
    if systemctl is-active nfs-server &>/dev/null; then
        echo "    ✓ NFS服务器服务运行中" >> "$LOG_FILE"
    else
        echo "    ⚠ NFS服务器服务未运行" >> "$LOG_FILE"
    fi
    
    if systemctl is-active rpcbind &>/dev/null; then
        echo "    ✓ RPC绑定服务运行中" >> "$LOG_FILE"
    else
        echo "    ⚠ RPC绑定服务未运行" >> "$LOG_FILE"
    fi
    
    echo "--------------------------------------" >> "$LOG_FILE"
}

# 主循环
while true; do
    monitor_nfs
    sleep "$INTERVAL"
done
场景2:NFS性能问题诊断
bash 复制代码
#!/bin/bash
# NFS性能问题诊断脚本

echo "NFS性能问题诊断报告"
echo "生成时间: $(date)"
echo "======================================"

# 1. 系统基本信息
echo "1. 系统基本信息:"
echo "   主机名: $(hostname)"
echo "   内核版本: $(uname -r)"
echo "   系统负载: $(uptime)"
echo "   内存使用: $(free -h | grep Mem | awk '{print $3"/"$2}')"
echo ""

# 2. NFS挂载点检查
echo "2. NFS挂载点检查:"
if mount | grep -q "type nfs"; then
    mount | grep "type nfs" | while read line; do
        local device=$(echo "$line" | awk '{print $1}')
        local mount_point=$(echo "$line" | awk '{print $3}')
        local options=$(echo "$line" | awk '{print $6}' | tr ',' ' ')
        
        echo "   挂载点: $mount_point"
        echo "   服务器: $device"
        echo "   挂载选项: $options"
        
        # 检查挂载点可访问性
        if timeout 5 ls "$mount_point" &>/dev/null; then
            echo "   状态: ✓ 可访问"
        else
            echo "   状态: ✗ 不可访问"
        fi
        echo ""
    done
else
    echo "   未发现NFS挂载点"
    echo ""
fi

# 3. NFS统计信息分析
echo "3. NFS统计信息分析:"
echo "   3.1 客户端统计:"
nfsstat -c | head -20 | sed 's/^/      /'

echo ""
echo "   3.2 服务器端统计:"
nfsstat -s | head -20 | sed 's/^/      /'

echo ""
echo "   3.3 挂载点详细统计:"
nfsstat -m | head -30 | sed 's/^/      /'

# 4. 网络连接检查
echo ""
echo "4. 网络连接检查:"
echo "   4.1 NFS相关端口:"
netstat -tulpn | grep -E '(2049|111|875)' | while read line; do
    echo "     $line"
done

echo ""
echo "   4.2 到NFS服务器的连接:"
mount | grep "type nfs" | awk '{print $1}' | cut -d: -f1 | sort -u | while read server; do
    echo "     服务器: $server"
    ping -c 3 -W 2 "$server" 2>/dev/null | grep -E "(packet loss|rtt)" | sed 's/^/        /'
done

# 5. 性能指标检查
echo ""
echo "5. 性能指标检查:"

# 检查重传率
echo "   5.1 RPC重传率:"
nfsstat -c 2>/dev/null | grep -A10 "Client rpc:" | while read line; do
    if echo "$line" | grep -q "retrans"; then
        local retrans=$(echo "$line" | awk '{print $2}')
        local calls=$(nfsstat -c 2>/dev/null | grep -A10 "Client rpc:" | grep "calls" | awk '{print $2}')
        if [ -n "$calls" ] && [ "$calls" -gt 0 ]; then
            local retrans_rate=$(echo "scale=4; $retrans * 100 / $calls" | bc)
            echo "     重传率: ${retrans_rate}% (重传: $retrans, 总调用: $calls)"
            
            if [ $(echo "$retrans_rate > 5" | bc) -eq 1 ]; then
                echo "     [警告] 重传率过高,可能网络不稳定"
            fi
        fi
    fi
done

# 检查错误率
echo ""
echo "   5.2 RPC错误率:"
nfsstat -c 2>/dev/null | grep -A10 "Client rpc:" | while read line; do
    if echo "$line" | grep -q "badcalls"; then
        local badcalls=$(echo "$line" | awk '{print $2}')
        local calls=$(nfsstat -c 2>/dev/null | grep -A10 "Client rpc:" | grep "calls" | awk '{print $2}')
        if [ -n "$calls" ] && [ "$calls" -gt 0 ]; then
            local error_rate=$(echo "scale=4; $badcalls * 100 / $calls" | bc)
            echo "     错误率: ${error_rate}% (错误: $badcalls, 总调用: $calls)"
            
            if [ $(echo "$error_rate > 1" | bc) -eq 1 ]; then
                echo "     [警告] 错误率过高,可能服务器或网络有问题"
            fi
        fi
    fi
done

# 6. 建议优化措施
echo ""
echo "6. 建议优化措施:"
echo "   1. 如果重传率过高:"
echo "      - 检查网络连接质量"
echo "      - 增加 timeo 参数值"
echo "      - 考虑使用 TCP 替代 UDP"
echo ""
echo "   2. 如果错误率过高:"
echo "      - 检查 NFS 服务器状态"
echo "      - 检查防火墙设置"
echo "      - 验证用户权限"
echo ""
echo "   3. 性能优化建议:"
echo "      - 调整 rsize 和 wsize 参数"
echo "      - 使用 noac 选项禁用属性缓存"
echo "      - 考虑使用 async 选项提高写入性能"
echo ""
echo "======================================"
echo "诊断完成"
场景3:NFS性能基准测试
bash 复制代码
#!/bin/bash
# NFS性能基准测试脚本

TEST_DIR="/mnt/nfs/test"
TEST_FILE_SIZE="1G"
TEST_BLOCK_SIZES="4K 16K 64K 128K 1M"
TEST_ITERATIONS=3
LOG_FILE="nfs_benchmark_$(date +%Y%m%d_%H%M%S).log"

echo "NFS性能基准测试报告" | tee "$LOG_FILE"
echo "测试时间: $(date)" | tee -a "$LOG_FILE"
echo "测试目录: $TEST_DIR" | tee -a "$LOG_FILE"
echo "======================================" | tee -a "$LOG_FILE"

# 检查测试目录
if [ ! -d "$TEST_DIR" ]; then
    echo "错误: 测试目录 $TEST_DIR 不存在" | tee -a "$LOG_FILE"
    exit 1
fi

# 检查写入权限
if [ ! -w "$TEST_DIR" ]; then
    echo "错误: 测试目录 $TEST_DIR 不可写" | tee -a "$LOG_FILE"
    exit 1
fi

# 获取初始统计信息
echo "获取初始NFS统计信息..." | tee -a "$LOG_FILE"
echo "初始客户端统计:" | tee -a "$LOG_FILE"
nfsstat -c >> "$LOG_FILE"
echo "" >> "$LOG_FILE"

echo "初始服务器端统计:" | tee -a "$LOG_FILE"
nfsstat -s >> "$LOG_FILE"
echo "" >> "$LOG_FILE"

# 创建测试文件
echo "创建测试文件 ($TEST_FILE_SIZE)..." | tee -a "$LOG_FILE"
TEST_FILE="$TEST_DIR/benchmark_test.dat"
dd if=/dev/zero of="$TEST_FILE" bs=1M count=1024 2>&1 | tail -1 | tee -a "$LOG_FILE"

# 顺序读写测试
echo "" >> "$LOG_FILE"
echo "顺序读写测试:" | tee -a "$LOG_FILE"
echo "--------------------------------------" | tee -a "$LOG_FILE"

for bs in $TEST_BLOCK_SIZES; do
    echo "块大小: $bs" | tee -a "$LOG_FILE"
    
    # 顺序读测试
    echo "  顺序读:" | tee -a "$LOG_FILE"
    for i in $(seq 1 $TEST_ITERATIONS); do
        echo "    第 $i 次:" | tee -a "$LOG_FILE"
        dd if="$TEST_FILE" of=/dev/null bs="$bs" 2>&1 | grep -E "(copied|bytes)" | tee -a "$LOG_FILE"
    done
    
    # 顺序写测试
    echo "  顺序写:" | tee -a "$LOG_FILE"
    WRITE_FILE="$TEST_DIR/write_test_${bs}.dat"
    for i in $(seq 1 $TEST_ITERATIONS); do
        echo "    第 $i 次:" | tee -a "$LOG_FILE"
        dd if=/dev/zero of="$WRITE_FILE" bs="$bs" count=$((1024*1024/$(echo "$bs" | sed 's/K/*1024/;s/M/*1024*1024/;s/[^0-9*]//g' | bc))) 2>&1 | grep -E "(copied|bytes)" | tee -a "$LOG_FILE"
        rm -f "$WRITE_FILE"
    done
    
    echo "" >> "$LOG_FILE"
done

# 随机读写测试
echo "随机读写测试:" | tee -a "$LOG_FILE"
echo "--------------------------------------" | tee -a "$LOG_FILE"

# 使用 fio 进行随机读写测试(如果可用)
if command -v fio &> /dev/null; then
    FIO_CONFIG="/tmp/fio_test.ini"
    
    cat > "$FIO_CONFIG" << EOF
[global]
ioengine=libaio
direct=1
runtime=30
time_based
group_reporting
size=1G
directory=$TEST_DIR

[sequential-read]
rw=read
bs=128k

[sequential-write]
rw=write
bs=128k

[random-read]
rw=randread
bs=4k

[random-write]
rw=randwrite
bs=4k
EOF
    
    echo "运行 fio 测试..." | tee -a "$LOG_FILE"
    fio "$FIO_CONFIG" --output-format=json > "/tmp/fio_results.json" 2>&1
    
    # 解析结果
    echo "fio 测试结果:" | tee -a "$LOG_FILE"
    grep -A5 "IOPS\|BW" "/tmp/fio_results.json" | tee -a "$LOG_FILE"
    
    rm -f "$FIO_CONFIG" "/tmp/fio_results.json"
else
    echo "fio 未安装,跳过随机读写测试" | tee -a "$LOG_FILE"
    echo "安装命令: sudo apt install fio 或 sudo yum install fio" | tee -a "$LOG_FILE"
fi

# 获取测试后统计信息
echo "" >> "$LOG_FILE"
echo "获取测试后NFS统计信息..." | tee -a "$LOG_FILE"
echo "测试后客户端统计:" | tee -a "$LOG_FILE"
nfsstat -c >> "$LOG_FILE"
echo "" >> "$LOG_FILE"

echo "测试后服务器端统计:" | tee -a "$LOG_FILE"
nfsstat -s >> "$LOG_FILE"
echo "" >> "$LOG_FILE"

# 计算性能差异
echo "性能统计对比:" | tee -a "$LOG_FILE"
echo "--------------------------------------" | tee -a "$LOG_FILE"

# 清理测试文件
rm -f "$TEST_FILE"
echo "清理测试文件完成" | tee -a "$LOG_FILE"

echo "" >> "$LOG_FILE"
echo "======================================" | tee -a "$LOG_FILE"
echo "基准测试完成" | tee -a "$LOG_FILE"
echo "详细日志已保存到: $LOG_FILE" | tee -a "$LOG_FILE"

⚠️ 重要注意事项

  1. 权限要求:查看服务器端统计需要 root 权限。
  2. 统计重置-z 选项会重置所有统计计数器,谨慎使用。
  3. 版本差异 :不同 Linux 发行版的 nfsstat 选项可能略有差异。
  4. 实时监控-l 选项在监控期间会持续占用终端。
  5. 网络影响:NFS 性能受网络延迟、带宽和服务器负载影响。
  6. 缓存影响:客户端缓存会影响统计数据的准确性。

🔄 相关命令

命令 用途 说明
nfsstat NFS 统计信息 显示 NFS 和 RPC 统计
mount 挂载信息 查看 NFS 挂载点和选项
showmount NFS 共享查看 查看 NFS 服务器共享目录
rpcinfo RPC 信息 查看 RPC 服务状态
nfsiostat NFS I/O 统计 类似 iostat,专用于 NFS

📈 性能指标解读

  1. 低错误率badcalls 应接近 0,高值表示认证或网络问题。
  2. 合理重传retrans 应小于总调用的 5%,高值表示网络不稳定。
  3. 操作分布getattr 通常占比最高,read/write 反映实际数据流量。
  4. 超时监控timeouts 高值表示服务器响应慢或网络延迟高。
  5. 缓存命中 :高 getattr 调用可能表示属性缓存效率低。

nfsstat 是 NFS 性能分析和故障排查的必备工具,通过监控关键指标可以帮助识别网络问题、服务器负载、配置不当等性能瓶颈。

相关推荐
web守墓人4 小时前
【linux】Mubuntu v1.0.11更新日志
linux·前端
哈__5 小时前
Linux生产环境MongoDB部署与安全加固:用户权限、防火墙、远程访问完整方案
linux·安全·mongodb
浅时光_c11 小时前
3 shell脚本编程
linux·开发语言·bash
Lucis__12 小时前
一文读懂TCP通信机制:基于相关API构建可靠性连接
linux·网络·tcp/ip
_深海凉_12 小时前
LeetCode热题100-有效的括号
linux·算法·leetcode
鹿鸣天涯13 小时前
Xftp传输文件时,解决“无法显示远程文件夹”方法
运维·服务器·计算机
unDl IONA14 小时前
服务器部署,用 nginx 部署后页面刷新 404 问题,宝塔面板修改(修改 nginx.conf 配置文件)
运维·服务器·nginx
零号全栈寒江独钓14 小时前
基于c/c++实现linux/windows跨平台获取ntp网络时间戳
linux·c语言·c++·windows
Web极客码14 小时前
WordPress管理员角色详解及注意事项
运维·服务器·wordpress