Linux命令-nfsstat(显示 NFS(Network File System)客户端和服务器统计信息)

nfsstat 是 Linux 中一个显示 NFS(Network File System)客户端和服务器统计信息的命令。它用于监控 NFS 性能、排查 NFS 相关问题,显示 NFS 和 RPC 调用的详细统计信息。

📖 基本语法

bash 复制代码
nfsstat [选项]

重要特性

  • 显示 NFS 客户端统计信息
  • 显示 NFS 服务器统计信息
  • 显示 RPC 统计信息
  • 支持重置统计计数器
  • 显示详细的 NFS 调用统计

🎯 常用选项

选项 说明
-s 显示 NFS 服务器统计信息。
-c 显示 NFS 客户端统计信息。
-n 显示 NFS 统计信息(客户端和服务器)。
-r 显示 RPC 统计信息。
-o 指定要显示的统计类别。
-z 重置(清零)统计计数器。
-m 显示挂载的 NFS 文件系统信息。
-2 显示 NFSv2 统计信息。
-3 显示 NFSv3 统计信息。
-4 显示 NFSv4 统计信息。
-l 以列表格式显示。
-v 显示详细输出。
-h 显示帮助信息。

💡 核心用法示例

1. 基本统计信息
bash 复制代码
# 显示所有 NFS 统计信息(客户端和服务器)
nfsstat

# 显示 NFS 客户端统计信息
nfsstat -c

# 显示 NFS 服务器统计信息
nfsstat -s

# 显示 NFS 客户端和服务器统计信息
nfsstat -cn
nfsstat -sn

# 显示 RPC 统计信息
nfsstat -r

# 显示所有统计信息
nfsstat -c -s -r
2. 按 NFS 版本显示
bash 复制代码
# 显示 NFSv2 统计信息
nfsstat -2

# 显示 NFSv3 统计信息
nfsstat -3

# 显示 NFSv4 统计信息
nfsstat -4

# 显示特定版本的客户端统计
nfsstat -c -3
nfsstat -c -4

# 显示特定版本的服务器统计
nfsstat -s -3
nfsstat -s -4
3. 显示挂载信息
bash 复制代码
# 显示挂载的 NFS 文件系统信息
nfsstat -m

# 显示特定挂载点的信息
mount | grep nfs
nfsstat -m | grep "/mnt/nfs"

# 显示详细的挂载信息
nfsstat -m -v
4. 重置统计信息
bash 复制代码
# 重置所有 NFS 统计计数器
sudo nfsstat -z

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

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

# 重置 RPC 统计
sudo nfsstat -r -z

# 重置特定版本统计
sudo nfsstat -3 -z
sudo nfsstat -4 -z
5. 高级用法
bash 复制代码
# 显示特定统计类别
nfsstat -o all          # 显示所有类别
nfsstat -o net          # 显示网络统计
nfsstat -o rpc          # 显示 RPC 统计
nfsstat -o proc2        # 显示 NFSv2 过程统计
nfsstat -o proc3        # 显示 NFSv3 过程统计
nfsstat -o proc4        # 显示 NFSv4 过程统计

# 以列表格式显示
nfsstat -l

# 显示详细输出
nfsstat -v

# 组合使用多个选项
nfsstat -c -3 -l        # 以列表格式显示 NFSv3 客户端统计
nfsstat -s -4 -v        # 显示详细的 NFSv4 服务器统计

📊 输出解读

NFS 客户端统计示例
复制代码
Client rpc stats:
calls      retrans    authrefrsh
125678     12         0

Client nfs v3:
null         getattr      setattr      lookup       access       readlink     
0 0%         1250 10%     45 0%        5678 45%     2345 19%     123 1%       
read         write        create       mkdir        symlink      mknod        
3456 28%     234 2%       67 0%        12 0%        5 0%         0 0%         
remove       rmdir        rename       link         readdir      readdirplus  
89 0%        4 0%         23 0%        8 0%         456 4%       567 5%       
fsstat       fsinfo       pathconf     commit       
34 0%        12 0%        5 0%         45 0%        

关键字段解释

  • calls:RPC 调用总数
  • retrans:重传次数(高值可能表示网络问题)
  • authrefrsh:认证刷新次数
  • 各 NFS 操作百分比:显示每种操作的分布情况
NFS 服务器统计示例
复制代码
Server rpc stats:
calls      badcalls   nullrecv   badlen     xdrcall    
234567     12         0          5          3          

Server nfs v3:
null         getattr      setattr      lookup       access       readlink     
0 0%         4567 19%     234 1%        12345 53%    3456 15%     123 0%       
read         write        create       mkdir        symlink      mknod        
2345 10%     456 2%       89 0%         23 0%        5 0%         0 0%         
remove       rmdir        rename       link         readdir      readdirplus  
67 0%        4 0%         34 0%         12 0%        234 1%       345 1%       
fsstat       fsinfo       pathconf     commit       
23 0%        12 0%        5 0%          45 0%        

关键字段解释

  • badcalls:错误的 RPC 调用数
  • nullrecv:空接收数
  • badlen:错误长度调用数
  • xdrcall:XDR 解码错误数
RPC 统计示例
复制代码
rcp:
calls      badcalls   retrans    badxids    timeouts   wait       newcred     
345678     23         45         12         34         5          0           
timers     toobig     nomem      cantsend   
12         3          0          2          

🔧 实用场景示例

1. 监控 NFS 性能
bash 复制代码
# 监控 NFS 客户端性能
watch -n 5 'nfsstat -c'

# 监控 NFS 服务器性能
watch -n 5 'nfsstat -s'

# 监控重传次数(网络问题指标)
watch -n 2 'nfsstat -c | grep -A1 "Client rpc stats"'

# 监控 NFSv4 性能
watch -n 5 'nfsstat -c -4'

# 监控特定操作的性能
watch -n 3 'nfsstat -c -3 | grep -E "(read|write)"'
2. 排查 NFS 问题
bash 复制代码
# 检查重传率(高重传率表示网络问题)
nfsstat -c | awk '/^Client rpc stats:/ {getline; print "重传率:", $2/$1*100 "%"}'

# 检查错误调用率
nfsstat -s | awk '/^Server rpc stats:/ {getline; print "错误调用率:", $2/$1*100 "%"}'

# 检查认证问题
nfsstat -c | grep "authrefrsh"

# 检查超时情况
nfsstat -r | grep "timeouts"

# 检查网络缓冲区问题
nfsstat -r | grep -E "(toobig|nomem|cantsend)"
3. 性能分析脚本
bash 复制代码
#!/bin/bash
# NFS 性能监控脚本

LOG_FILE="/var/log/nfs_performance.log"
INTERVAL=60  # 监控间隔(秒)
ALERT_THRESHOLD=5  # 重传率警报阈值(%)
ALERT_EMAIL="admin@example.com"

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')
    
    # 获取客户端统计
    local client_stats=$(nfsstat -c)
    local server_stats=$(nfsstat -s)
    local rpc_stats=$(nfsstat -r)
    
    # 解析关键指标
    local calls=$(echo "$client_stats" | awk '/^Client rpc stats:/ {getline; print $1}')
    local retrans=$(echo "$client_stats" | awk '/^Client rpc stats:/ {getline; print $2}')
    local badcalls=$(echo "$server_stats" | awk '/^Server rpc stats:/ {getline; print $2}')
    local timeouts=$(echo "$rpc_stats" | awk '/^rpc:/ {getline; print $5}')
    
    # 计算重传率
    local retrans_rate=0
    if [[ $calls -gt 0 ]]; then
        retrans_rate=$(echo "scale=2; $retrans / $calls * 100" | bc)
    fi
    
    # 计算错误率
    local error_rate=0
    local server_calls=$(echo "$server_stats" | awk '/^Server rpc stats:/ {getline; print $1}')
    if [[ $server_calls -gt 0 ]]; then
        error_rate=$(echo "scale=2; $badcalls / $server_calls * 100" | bc)
    fi
    
    # 记录到日志
    echo "[$timestamp] NFS 性能指标:" >> "$LOG_FILE"
    echo "  客户端调用次数: $calls" >> "$LOG_FILE"
    echo "  重传次数: $retrans" >> "$LOG_FILE"
    echo "  重传率: ${retrans_rate}%" >> "$LOG_FILE"
    echo "  服务器错误调用: $badcalls" >> "$LOG_FILE"
    echo "  错误率: ${error_rate}%" >> "$LOG_FILE"
    echo "  RPC 超时次数: $timeouts" >> "$LOG_FILE"
    
    # 检查操作分布(NFSv3 示例)
    echo "  NFSv3 操作分布:" >> "$LOG_FILE"
    echo "$client_stats" | grep -A20 "Client nfs v3:" | head -20 >> "$LOG_FILE"
    
    # 检查警报条件
    if (( $(echo "$retrans_rate > $ALERT_THRESHOLD" | bc -l) )); then
        echo "[警报] 重传率过高: ${retrans_rate}%" >> "$LOG_FILE"
        echo "NFS 重传率异常: ${retrans_rate}% (阈值: ${ALERT_THRESHOLD}%)" | \
            mail -s "NFS 性能警报 - $timestamp" "$ALERT_EMAIL"
    fi
    
    if [[ $timeouts -gt 10 ]]; then
        echo "[警报] RPC 超时过多: $timeouts" >> "$LOG_FILE"
        echo "RPC 超时次数异常: $timeouts" | \
            mail -s "NFS RPC 超时警报 - $timestamp" "$ALERT_EMAIL"
    fi
    
    echo "--------------------------------------" >> "$LOG_FILE"
}

# 主循环
while true; do
    monitor_nfs
    sleep "$INTERVAL"
done
4. NFS 健康检查脚本
bash 复制代码
#!/bin/bash
# NFS 健康检查脚本

CHECK_INTERVAL=300  # 检查间隔(秒)
LOG_FILE="/var/log/nfs_health.log"
ALERT_EMAIL="admin@example.com"

# NFS 挂载点列表
NFS_MOUNTS=(
    "/mnt/nfs_share1"
    "/mnt/nfs_share2"
    "/data/nfs_backup"
    "/home/nfs_homes"
)

echo "开始 NFS 健康检查 $(date)" >> "$LOG_FILE"
echo "检查间隔: ${CHECK_INTERVAL}秒" >> "$LOG_FILE"
echo "======================================" >> "$LOG_FILE"

check_nfs_health() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local issues_found=0
    
    echo "[$timestamp] NFS 健康检查:" >> "$LOG_FILE"
    
    # 1. 检查 NFS 挂载点
    echo "  1. 挂载点检查:" >> "$LOG_FILE"
    for mount_point in "${NFS_MOUNTS[@]}"; do
        if mountpoint -q "$mount_point"; then
            # 获取挂载信息
            local mount_info=$(mount | grep " $mount_point ")
            local nfs_version=$(echo "$mount_info" | grep -o "vers=[0-9.]*" | cut -d= -f2)
            local mount_options=$(echo "$mount_info" | grep -o "\([^ ]*,\)*[^ ]*" | tail -1)
            
            echo "    ✓ $mount_point" >> "$LOG_FILE"
            echo "      版本: NFSv${nfs_version:-未知}" >> "$LOG_FILE"
            echo "      选项: ${mount_options}" >> "$LOG_FILE"
            
            # 测试读写
            local test_file="$mount_point/.nfs_test_$(date +%s)"
            if touch "$test_file" 2>/dev/null; then
                echo "      写测试: 正常" >> "$LOG_FILE"
                rm -f "$test_file"
            else
                echo "      写测试: 失败" >> "$LOG_FILE"
                ((issues_found++))
            fi
        else
            echo "    ✗ $mount_point: 未挂载" >> "$LOG_FILE"
            ((issues_found++))
        fi
    done
    
    # 2. 检查 NFS 统计信息
    echo "  2. 统计信息检查:" >> "$LOG_FILE"
    
    # 客户端统计
    local client_stats=$(nfsstat -c 2>/dev/null)
    if [[ -n "$client_stats" ]]; then
        local retrans=$(echo "$client_stats" | awk '/^Client rpc stats:/ {getline; print $2}')
        local calls=$(echo "$client_stats" | awk '/^Client rpc stats:/ {getline; print $1}')
        
        if [[ $calls -gt 0 ]]; then
            local retrans_rate=$(echo "scale=2; $retrans / $calls * 100" | bc)
            echo "    客户端重传率: ${retrans_rate}%" >> "$LOG_FILE"
            
            if (( $(echo "$retrans_rate > 5" | bc -l) )); then
                echo "    [警告] 重传率偏高" >> "$LOG_FILE"
                ((issues_found++))
            fi
        fi
    else
        echo "    客户端统计: 不可用" >> "$LOG_FILE"
    fi
    
    # 服务器统计(如果运行 NFS 服务器)
    if systemctl is-active nfs-server >/dev/null 2>&1 || \
       systemctl is-active nfs-kernel-server >/dev/null 2>&1; then
        local server_stats=$(nfsstat -s 2>/dev/null)
        if [[ -n "$server_stats" ]]; then
            local badcalls=$(echo "$server_stats" | awk '/^Server rpc stats:/ {getline; print $2}')
            local server_calls=$(echo "$server_stats" | awk '/^Server rpc stats:/ {getline; print $1}')
            
            if [[ $server_calls -gt 0 ]]; then
                local error_rate=$(echo "scale=2; $badcalls / $server_calls * 100" | bc)
                echo "    服务器错误率: ${error_rate}%" >> "$LOG_FILE"
                
                if (( $(echo "$error_rate > 1" | bc -l) )); then
                    echo "    [警告] 错误率偏高" >> "$LOG_FILE"
                    ((issues_found++))
                fi
            fi
        fi
    fi
    
    # 3. 检查 RPC 服务
    echo "  3. RPC 服务检查:" >> "$LOG_FILE"
    local rpc_services=("rpcbind" "rpc.statd" "rpc.mountd")
    
    for service in "${rpc_services[@]}"; do
        if pgrep -x "$service" >/dev/null; then
            echo "    ✓ $service: 运行中" >> "$LOG_FILE"
        else
            echo "    ✗ $service: 未运行" >> "$LOG_FILE"
            ((issues_found++))
        fi
    done
    
    # 4. 检查网络连接
    echo "  4. 网络连接检查:" >> "$LOG_FILE"
    local nfs_ports=("2049" "111" "20048" "20049")
    
    for port in "${nfs_ports[@]}"; do
        if ss -tuln | grep -q ":$port "; then
            echo "    ✓ 端口 $port: 监听中" >> "$LOG_FILE"
        else
            echo "    ✗ 端口 $port: 未监听" >> "$LOG_FILE"
            ((issues_found++))
        fi
    done
    
    # 总结
    echo "  5. 检查总结:" >> "$LOG_FILE"
    if [[ $issues_found -eq 0 ]]; then
        echo "    ✓ 所有检查通过,NFS 状态正常" >> "$LOG_FILE"
    else
        echo "    ✗ 发现 $issues_found 个问题" >> "$LOG_FILE"
        
        # 发送警报邮件
        echo "NFS 健康检查发现问题: $issues_found 个" | \
            mail -s "NFS 健康检查警报 - $timestamp" "$ALERT_EMAIL"
    fi
    
    echo "--------------------------------------" >> "$LOG_FILE"
}

# 主循环
while true; do
    check_nfs_health
    sleep "$CHECK_INTERVAL"
done
5. NFS 性能优化监控
bash 复制代码
#!/bin/bash
# NFS 性能优化监控脚本

LOG_FILE="/var/log/nfs_optimization.log"
INTERVAL=30  # 监控间隔(秒)
SAMPLE_COUNT=10  # 采样次数
ALERT_EMAIL="admin@example.com"

echo "开始 NFS 性能优化监控 $(date)" >> "$LOG_FILE"
echo "监控间隔: ${INTERVAL}秒" >> "$LOG_FILE"
echo "采样次数: ${SAMPLE_COUNT}" >> "$LOG_FILE"
echo "======================================" >> "$LOG_FILE"

# 性能基准测试函数
benchmark_nfs() {
    local mount_point="$1"
    local test_size_mb=100
    local test_file="$mount_point/nfs_benchmark_$(date +%s).dat"
    
    echo "  对 $mount_point 进行基准测试:" >> "$LOG_FILE"
    
    # 写性能测试
    local write_start=$(date +%s.%N)
    dd if=/dev/zero of="$test_file" bs=1M count=$test_size_mb oflag=direct 2>/dev/null
    local write_end=$(date +%s.%N)
    local write_time=$(echo "$write_end - $write_start" | bc)
    local write_speed=$(echo "scale=2; $test_size_mb / $write_time" | bc)
    
    echo "    写速度: ${write_speed} MB/s" >> "$LOG_FILE"
    
    # 读性能测试
    local read_start=$(date +%s.%N)
    dd if="$test_file" of=/dev/null bs=1M iflag=direct 2>/dev/null
    local read_end=$(date +%s.%N)
    local read_time=$(echo "$read_end - $read_start" | bc)
    local read_speed=$(echo "scale=2; $test_size_mb / $read_time" | bc)
    
    echo "    读速度: ${read_speed} MB/s" >> "$LOG_FILE"
    
    # 清理测试文件
    rm -f "$test_file"
    
    # 返回速度值
    echo "$write_speed $read_speed"
}

monitor_nfs_performance() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    echo "[$timestamp] NFS 性能监控:" >> "$LOG_FILE"
    
    # 获取所有 NFS 挂载点
    local nfs_mounts=$(mount -t nfs,nfs4 2>/dev/null | awk '{print $3}')
    
    if [[ -z "$nfs_mounts" ]]; then
        echo "  未找到 NFS 挂载点" >> "$LOG_FILE"
        return
    fi
    
    # 对每个挂载点进行监控
    for mount_point in $nfs_mounts; do
        echo "  挂载点: $mount_point" >> "$LOG_FILE"
        
        # 获取挂载选项
        local mount_options=$(mount | grep " $mount_point " | grep -o "\([^ ]*,\)*[^ ]*" | tail -1)
        echo "    挂载选项: $mount_options" >> "$LOG_FILE"
        
        # 获取 NFS 版本
        local nfs_version=$(mount | grep " $mount_point " | grep -o "vers=[0-9.]*" | cut -d= -f2)
        echo "    NFS 版本: v${nfs_version:-未知}" >> "$LOG_FILE"
        
        # 获取统计信息
        local client_stats=$(nfsstat -c 2>/dev/null)
        
        # 分析操作分布
        if [[ -n "$client_stats" ]]; then
            # 获取读写操作比例
            local read_ops=$(echo "$client_stats" | grep -A30 "Client nfs v${nfs_version:-3}:" | \
                           grep -E "^\s*read\s+" | awk '{print $2}' | tr -d '%')
            local write_ops=$(echo "$client_stats" | grep -A30 "Client nfs v${nfs_version:-3}:" | \
                            grep -E "^\s*write\s+" | awk '{print $2}' | tr -d '%')
            
            echo "    读操作比例: ${read_ops:-0}%" >> "$LOG_FILE"
            echo "    写操作比例: ${write_ops:-0}%" >> "$LOG_FILE"
            
            # 获取重传率
            local calls=$(echo "$client_stats" | awk '/^Client rpc stats:/ {getline; print $1}')
            local retrans=$(echo "$client_stats" | awk '/^Client rpc stats:/ {getline; print $2}')
            
            if [[ $calls -gt 0 ]]; then
                local retrans_rate=$(echo "scale=2; $retrans / $calls * 100" | bc)
                echo "    重传率: ${retrans_rate}%" >> "$LOG_FILE"
                
                # 重传率警报
                if (( $(echo "$retrans_rate > 3" | bc -l) )); then
                    echo "    [警告] 重传率偏高,可能存在网络问题" >> "$LOG_FILE"
                    echo "NFS 重传率警报: $mount_point 重传率 ${retrans_rate}%" | \
                        mail -s "NFS 网络问题警报 - $timestamp" "$ALERT_EMAIL"
                fi
            fi
        fi
        
        # 定期进行基准测试(每10次监控执行一次)
        local sample_count_file="/tmp/nfs_sample_count_$(echo "$mount_point" | tr '/' '_')"
        local current_count=$(cat "$sample_count_file" 2>/dev/null || echo "0")
        
        if [[ $current_count -ge $SAMPLE_COUNT ]]; then
            echo "    执行基准测试..." >> "$LOG_FILE"
            benchmark_nfs "$mount_point"
            echo "0" > "$sample_count_file"
        else
            echo "    跳过基准测试 (${current_count}/${SAMPLE_COUNT})" >> "$LOG_FILE"
            echo $((current_count + 1)) > "$sample_count_file"
        fi
        
        echo "" >> "$LOG_FILE"
    done
    
    echo "--------------------------------------" >> "$LOG_FILE"
}

# 主循环
while true; do
    monitor_nfs_performance
    sleep "$INTERVAL"
done

⚠️ 重要注意事项

  1. 权限要求:查看统计信息通常不需要特殊权限,但重置统计需要 root 权限
  2. 统计重置:重置统计会清零所有计数器,影响历史数据分析
  3. 版本差异 :不同 Linux 发行版的 nfsstat 输出格式可能略有不同
  4. NFSv4 差异:NFSv4 的统计信息与 NFSv3 有所不同
  5. 性能影响 :频繁运行 nfsstat 对系统性能影响很小

🔄 相关命令

命令 说明
mount 显示挂载信息,包括 NFS 挂载
showmount 显示 NFS 服务器上的挂载信息
rpcinfo 显示 RPC 服务信息
nfsiostat 显示 NFS 挂载点的 I/O 统计(需要安装 nfs-utils)
iotop 显示进程级别的 I/O 统计

📌 最佳实践

  1. 定期监控:建立定期的 NFS 性能监控机制
  2. 基线建立:在系统正常时建立性能基线
  3. 警报设置:设置合理的警报阈值(如重传率 > 5%)
  4. 日志记录:记录历史统计信息用于趋势分析
  5. 版本升级:考虑升级到 NFSv4 以获得更好的性能和安全性

🎯 快速参考卡

复制代码
基本查看:
  nfsstat                     # 显示所有统计
  nfsstat -c                  # 客户端统计
  nfsstat -s                  # 服务器统计
  nfsstat -r                  # RPC 统计
  nfsstat -m                  # 挂载信息

按版本查看:
  nfsstat -2                  # NFSv2 统计
  nfsstat -3                  # NFSv3 统计
  nfsstat -4                  # NFSv4 统计
  nfsstat -c -3               # NFSv3 客户端统计

重置统计:
  sudo nfsstat -z             # 重置所有统计
  sudo nfsstat -c -z          # 重置客户端统计
  sudo nfsstat -s -z          # 重置服务器统计

关键指标:
  重传率 = retrans / calls * 100%
  错误率 = badcalls / calls * 100%
  操作分布:read, write, lookup 等

监控命令:
  watch -n 5 'nfsstat -c'     # 每5秒监控客户端
  nfsstat -c | grep retrans   # 检查重传次数
  nfsstat -s | grep badcalls  # 检查错误调用

nfsstat 是管理和优化 NFS 性能的重要工具,特别适合排查 NFS 相关的性能问题和网络问题。通过定期监控和分析统计信息,可以及时发现并解决 NFS 性能瓶颈。

相关推荐
念恒123062 小时前
Linux基础开发工具(yum篇)
linux·c语言
如鹿觅水2 小时前
OpenWrt 如何通过简单设置启用AP路由模式的图文教程
运维·服务器
何中应2 小时前
服务器主机时钟未同步告警解决
linux·运维·服务器
爱学习的小囧2 小时前
VM硬件版本20与17核心区别(ESXi 8.0适配+实操指南)
运维·服务器·网络·数据库·esxi·vmware·虚拟化
阿梦Anmory2 小时前
如何使用 SCP 从 Windows 传输文件到 Ubuntu 服务器
服务器·windows·ubuntu
呆子也有梦2 小时前
游戏服务端大地图架构通俗指南:从“分区管理”到“动态调度”
服务器·后端·游戏·架构·系统架构
磊 子2 小时前
编译链接过程讲解
linux·运维·服务器
哼?~2 小时前
Socket--UDP 构建简单聊天室
linux·网络·udp
JACK的服务器笔记3 小时前
《服务器测试百日学习计划——Day19:PCIe自动检测脚本,用Python把lspci设备清点标准化》
服务器·python·学习