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 性能瓶颈。

相关推荐
A小辣椒28 分钟前
TShark:Wireshark CLI 功能
linux
A小辣椒4 小时前
TShark:基础知识
linux
AlfredZhao6 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao21 小时前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334661 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪1 天前
linux 拷贝文件或目录到指定的位置
linux
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式