chatGPTとのやり取りをもとに得られた知見を示したものです。内容の正確性や最新性を必ずしも保証するものではありませんよ。
nfsサーバにて
rpc-srv/tcp: nfsd: got error -11 when sending 3268 bytes - shutting down socket
TCP: out of memory -- consider tuning tcp_memという文言が表示されていて実際にnfsサーバへのアクセスに問題が生じた.
こちらは、nfsサーバがTCPソケット経由でnfsクライアントにデータを送信しようとしたら、エラー11で送れなかったを意味するみたい。
その時は送れなかったので、後で送ればいいのですが、nfsdはこのエラーを受けると、そのTCPソケットを閉じてしまい、nfsクライアントとの接続が遮断される。
って原因は二行目にあるように「TCP: out of memory -- consider tuning tcp_mem」と
TCPバッファ用メモリーが切迫したためと見受ける
TCPスタックは、送受信に使うバッファを動的に確保しますが、上限がある。
目下の確保している値は「cat /proc/sys/net/ipv4/tcp_mem」で見れて
cat /proc/sys/net/ipv4/tcp_mem
560532 747377 1121064
と3つの値がでる(数字はページ単位[4KB])。左から
っとこのように上限が決められている。
今回はTCPコネクションが大量に張って大きなI/Oを流した結果、TCP バッファがカーネル設定上限に達して新しいバッファ確保に失敗し、このメッセージが出た。
そんな感じっぽい。
本システムは「/proc/sys/net/ipv4/tcp_mem」の内容から 1121064 ページ、4.27GB がTCPメモリの上限である。
っで不具合が起こった時点での使用量は「cat /proc/net/sockstat」で見れて
sockets: used 28983
TCP: inuse 13 orphan 0 tw 0 alloc 28507 mem 1195737
UDP: inuse 9 mem 2
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0であった。
TCP行のmem欄が現在のTCPメモリ使用量を表す。 1195737 なので 1195737 * 4GB -> 4.56GB
1195737(4.56GB) は highの値 1121064(4.27GB)を超えている。なのでエラーとなっている様子。
TCPメモリの上限を引き上げる
主メモリーのサイズにも寄りますが、問題の起こったマシンは 48GB のメモリー量です。TCPに8 - 12 GB 位充てても問題ないようで、2.5倍くらいに上げます。
echo "net.ipv4.tcp_mem = 1401330 1868442 2802660" | tee /etc/sysctl.d/99-tcp.conf
sysctl -pあと tcp_rmem(受信バッファ) と tcp_wmem(送信バッファ) も再定義する。っが大きかったり小さかったりすると 1接続当たりのメモリー効率が悪化するみたい
っで
tcp_rmem/tcp_wmemの書式は 最小値 デフォルト 最大値 で単位は バイト 。最大値を16MB程度にすれば 大容量I/O にも対応できるみたい。でもこれらはkernelで自動調節されるみたいで微妙?
ソケットバッファ上限(net.core.rmem_max, net.core.wmem_max) も最大値に合わせておきます
なのでまとめて
「/etc/sysctl.conf」
には
### --- TCPメモリ関連 ---
# TCP全体で使えるメモリ制限( 5GB, 7GB, 10GB )
net.ipv4.tcp_mem = 1401330 1868442 2802660
# TCP受信・送信バッファの自動チューニング範囲(4 KB. 512 KB, 32MB )
net.ipv4.tcp_rmem = 4096 524288 33554432
net.ipv4.tcp_wmem = 4096 524288 33554432
# ソケット単位のバッファ最大値
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
# TCPの自動受信バッファチューニングを有効化(通常有効)
net.ipv4.tcp_moderate_rcvbuf = 1
### --- ネットワークキュー / バッファ関連 ---
# バックログキュー拡張(同時接続待ちの多いNFS向け)
net.core.netdev_max_backlog = 250000
# SYNバックログ(TCPハンドシェイクの待機キュー)
net.ipv4.tcp_max_syn_backlog = 8192
# 一時ポート範囲拡大(大量同時接続対策)
net.ipv4.ip_local_port_range = 1024 65000
### --- TCP挙動調整 ---
# ウィンドウスケーリングを有効化(高帯域対応)
net.ipv4.tcp_window_scaling = 1
# タイムウェイトソケット再利用を有効化
net.ipv4.tcp_tw_reuse = 1
# FIN_WAIT2 ソケットのタイムアウト短縮(秒)
net.ipv4.tcp_fin_timeout = 15
### --- NFS特有のパフォーマンス改善に寄与する関連設定 ---
# VMバッファ制御(ページキャッシュ圧迫防止)
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10記載後「sysctl -p」で反映されます
nfsサーバのCPUコア数に応じて増やす。
16coreCPUなら 16 - 32 threads で定義します.
NFSv4.1 NFSv4.2 なら 1MB以上のIOサイズを指定できるが、Linuxカーネルの実装で基本的に最大が1MBみたい。
数値はバイト単位. 1048576は 1MB となる。
mount -t nfs -o rsize=1048576,wsize=1048576 ...