Skip to content

Instantly share code, notes, and snippets.

@githubhjs
Last active September 18, 2025 02:18
Show Gist options
  • Select an option

  • Save githubhjs/c1398c18dc6cd65a2852c774971008f9 to your computer and use it in GitHub Desktop.

Select an option

Save githubhjs/c1398c18dc6cd65a2852c774971008f9 to your computer and use it in GitHub Desktop.
① mountstats 解析器(無需 sudo) 功能:取樣兩次 /proc/self/mountstats(或用 nfsiostat 若系統有),輸出每個 NFS 掛載點的 ops/s(讀/寫)、avg RTT / avg exe、rpc bklog、以及「初步瓶頸判定」。 把下面存成 nfs-mountstats-lite.sh,給執行權限(不需 sudo):
#!/usr/bin/env bash
# nfs-mountstats-lite.sh -- user-space NFS health snapshot
# 用法:./nfs-mountstats-lite.sh [-i interval_sec] [-c samples]
# 預設 interval=2, samples=3(總觀察 ~4 秒)
set -euo pipefail
INT=2; CNT=3
while getopts "i:c:" o; do
case "$o" in
i) INT="$OPTARG";;
c) CNT="$OPTARG";;
esac
done
have_nfsiostat=0
command -v nfsiostat >/dev/null 2>&1 && have_nfsiostat=1
ts() { date "+%F %T"; }
echo "[$(ts)] host=$(hostname) interval=${INT}s samples=${CNT}"
echo "---- NFS mounts ----"
grep -E ' nfs[34]? ' /proc/mounts || true
echo
if [ "$have_nfsiostat" -eq 1 ]; then
echo "nfsiostat 可用:匯總顯示(含 avg RTT/exe、bklog,使用者權限即可)"
echo "------------------------------------------------------------------"
nfsiostat -h "$INT" "$CNT" | awk '
BEGIN{FS=":"}
/^\/|^[A-Za-z0-9\.\-]+:\/.* mounted on /{
gsub(" mounted on ", " -> ");
print "\n[FS] " $0
}
/avg RTT/ || /avg exe/ || /rpc bklog/ || /read:/ || /write:/ {
gsub(/^[ \t]+/,"",$0); print " " $0
}'
echo
else
echo "找不到 nfsiostat,改以 mountstats 粗解析(字段較原始)"
echo "------------------------------------------------------------------"
snap() { grep -A200 -E '^device .+ nfs' /proc/self/mountstats; }
TMP1=$(mktemp); TMP2=$(mktemp)
snap >"$TMP1"; sleep "$INT"; snap >"$TMP2"
# 只做最保守的統計:READ/WRITE 總次數差值 ≈ ops/s;其餘給出原始片段供觀察
awk -v intv="$INT" '
function flush(){
if (dev!=""){
rops = r2 - r1; wops = w2 - w1;
printf "\n[FS] %s -> %s\n", dev, mnt;
if (rops || wops){
printf " ops/s (READ/WRITE): %.2f / %.2f\n", rops/intv, wops/intv;
} else {
print " ops/s: (無差值,可能閒置)"
}
print " *以下為原始 mountstats 片段(找 avg rtt/exe、rpc bklog 關鍵詞)"
for(i=0;i<lines;i++) print " " buf[i];
}
dev=""; mnt=""; r1=r2=w1=w2=0; lines=0;
}
FNR==1 { pass++ }
/^device .* nfs/{
flush()
dev=$2; mnt=$5; next
}
/READ:/{
# 嘗試抓「ops」欄(不同核心格式不同,僅保守匹配第一個數字為 ops)
if (pass==1){split($0,a,/[ :]+/); for(i=1;i<=NF;i++) if ($i ~ /^[0-9]+$/){r1+=$i; break}}
else {split($0,a,/[ :]+/); for(i=1;i<=NF;i++) if ($i ~ /^[0-9]+$/){r2+=$i; break}}
}
/WRITE:/{
if (pass==1){split($0,a,/[ :]+/); for(i=1;i<=NF;i++) if ($i ~ /^[0-9]+$/){w1+=$i; break}}
else {split($0,a,/[ :]+/); for(i=1;i<=NF;i++) if ($i ~ /^[0-9]+$/){w2+=$i; break}}
}
{
if (pass==2 && lines<20){ buf[lines]=$0; lines++ } # 帶 20 行上下文協助人工判讀
}
END{ flush() }
' "$TMP1" "$TMP2"
rm -f "$TMP1" "$TMP2"
echo
fi
echo "---- 客戶端 RPC 統計(重傳/逾時) ----"
nfsstat -c -o net -o rpc 2>/dev/null || echo "(nfsstat 不可用)"
echo
echo "初步判定指南:"
echo " exe ≫ rtt → 伺服器/後端 I/O 在忙;rtt 高且 retrans/timeout 升 → 網路路徑;"
echo " rpc bklog 持續 >0 或連線數偏少 → 客戶端並行度不足(nconnect/應用多執行緒)。"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment