LinuxのTCPスタックをsysctlでチューニングする方法|somaxconn・バッファサイズ調整で高負荷時の接続詰まりを解消

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxトラブルシューティング > LinuxのTCPスタックをsysctlでチューニングする方法|somaxconn・バッファサイズ調整で高負荷時の接続詰まりを解消
「Webサーバーへのアクセスが急増したとき、接続エラーが増えてパフォーマンスが落ちた経験はないだろうか。」
CPUもメモリも余裕があるのに接続が詰まる場合、Linuxカーネルのデフォルトパラメータがボトルネックになっていることが多い。特に「接続受付キューの上限」「TIME_WAIT接続の滞留」「TCP送受信バッファの不足」はデフォルト値が小規模サーバー向けのままで、本番の高負荷環境に合っていないことがある。

この記事では、net.core.somaxconn・tcp_max_syn_backlog・tcp_fin_timeout・tcp_rmem/tcp_wmemの各パラメータについて、何をしているか・現状確認コマンド・推奨設定値・永続化の手順を実機ベースで解説する。
実行環境:RHEL 9.4 / Rocky Linux 9.4 / Ubuntu 24.04 LTS で動作確認済み。

この記事のポイント

・somaxconnのデフォルト128は高負荷サーバーには低すぎる。4096以上を推奨
・tcp_tw_reuseはNATやロードバランサー配下では有効だが設定前に動作確認が必要
・tcp_rmem/tcp_wmemを広げると帯域効率は上がるがメモリ使用量も増える
・変更は/etc/sysctl.d/に.confを置いて永続化し、sysctl -pで即時反映する


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜTCPチューニングが必要か

Linuxカーネルが持つTCP関連パラメータの多くは、数十年前のサーバー環境を想定したデフォルト値のまま出荷されている。
例えば、接続受付キューの上限を決める net.core.somaxconn はRHEL 9系でデフォルト4096に引き上げられているが、ディストリビューションやバージョンによっては128のままになっている。1秒間に数百の新規接続が来るWebサーバーでは、このキューがすぐに溢れてSYN_DROPが多発する。

高負荷時に起きやすい主な症状を整理しておく。
・接続が突然切れる、タイムアウトが増える → 受付キュー溢れ or TIME_WAIT枯渇
・大量データ転送が遅い → TCPバッファ不足
・短時間に大量接続が来るとリセットが増える → SYNバックログ不足

いずれも、アプリ側のチューニングより先にカーネルパラメータを見直すと改善できることが多い。

チューニング前に現状を把握する

変更前に現在のパラメータ値とTCP接続の状態を記録しておく。後で「変更前後でどう変わったか」を比較するためだ。

1. TCPパラメータの現在値を確認する

# チューニング対象パラメータを一覧で確認 sysctl -a 2>/dev/null | grep -E 'somaxconn|syn_backlog|fin_timeout|tw_reuse|tcp_mem|tcp_rmem|tcp_wmem'

RHEL 9.4での実行結果(デフォルト値)は以下のようになる。

# sysctl output on RHEL 9.4 (default values before tuning) net.core.somaxconn = 4096 net.ipv4.tcp_max_syn_backlog = 512 net.ipv4.tcp_fin_timeout = 60 net.ipv4.tcp_tw_reuse = 2 net.ipv4.tcp_mem = 182418 243227 364836 net.ipv4.tcp_rmem = 4096 131072 6291456 net.ipv4.tcp_wmem = 4096 16384 4194304

Ubuntu 24.04では net.core.somaxconn が4096、古いCentOS 7では128になっている場合がある。まず自分のサーバーの値を把握することが大切だ。

2. TCP接続の現状を確認する

ss -s コマンドでTCPセッションの集計を確認する(Linux ポート確認の全コマンド)。

ss -s

Total: 1842 TCP: 1347 (estab 312, closed 989, orphaned 1) Transport Total IP IPv6 RAW 2 2 0 UDP 18 10 8 TCP 358 342 16 INET 378 354 24 FRAG 0 0 0

TIME_WAIT(closed内に含まれる)が多い場合はタイムアウト系パラメータを調整する。estabが急増している場合はsomaxconnとバッファを先に見直す。

接続受付キューを設定する(somaxconn・tcp_max_syn_backlog)

TCPの接続確立には「SYNキュー」と「ACCEPTキュー」の2段階がある。

1. net.core.somaxconnとは

net.core.somaxconn はACCEPTキューの最大長を決める。アプリが accept() を呼ぶ前に「確立済み接続を積んでおけるバッファ」の上限だ。

・デフォルト:ディストリビューションによって128または4096
・推奨値(高負荷Webサーバー):4096以上
・設定例:

sysctl -w net.core.somaxconn=4096

注意:アプリ側(nginx, Apacheなど)も内部でlistenバックログを指定している。例えばnginxの listen 80 backlog=4096; のように合わせて設定しないと効果が出ない。

2. net.ipv4.tcp_max_syn_backlogとの違い

net.ipv4.tcp_max_syn_backlog は3ウェイハンドシェイクが完了する前の「SYNキュー」の最大長だ。SYNを受け取ったがACKがまだ来ていない接続を保持する。

・デフォルト:512程度(カーネルバージョンやRAM容量によって変動)
・推奨値:somaxconnの2倍程度
・DDoSのSYNフラッドが心配な場合は net.ipv4.tcp_syncookies=1(デフォルトで有効)と併用する

sysctl -w net.ipv4.tcp_max_syn_backlog=8192

3. 設定後の確認

nginxのバックログと合わせた設定後、ss -lnt で確認する。

# Recv-Q が 0 のまま安定しているかを確認(キュー溢れがないこと) ss -lnt sport = :80

State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 4096 0.0.0.0:80 0.0.0.0:*

Send-Q の数値(ここでは4096)がsomaxconnと一致しているかも確認する。

接続タイムアウトを短縮する(tcp_fin_timeout / tcp_tw_reuse)

短時間に大量の接続を扱うサーバーでは、クローズ処理中の接続がポートを使いっぱなしにすることがある。TIME_WAITが溢れるとエフェメラルポートが枯渇し、新規接続ができなくなる。

1. tcp_fin_timeoutを短縮する

FIN_WAIT_2状態の接続を保持し続ける秒数だ。デフォルトは60秒。短縮すると古い接続がはやく解放される。

# 60秒 → 30秒に短縮する例 sysctl -w net.ipv4.tcp_fin_timeout=30

あまり短くしすぎると(例: 5秒)、相手側のFINパケットが来る前に接続が強制切断されるリスクがある。15~30秒が実用的な範囲だ。

2. tcp_tw_reuseの注意点

tcp_tw_reuse=1 はTIME_WAIT状態のソケットを新規接続に再利用する設定だ。デフォルト2はループバック限定で有効。

・値の意味:0=無効、1=有効(全インターフェース)、2=ループバックのみ有効(デフォルト)
・外部クライアントと大量通信するサーバーには 1 が有効だが、NATが絡む環境では予期しない動作を招くことがある
・設定変更前に必ず開発環境でテストすること

# ループバック以外でも TIME_WAIT ソケットを再利用する sysctl -w net.ipv4.tcp_tw_reuse=1

3. TIME_WAIT接続数の確認

# TIME_WAIT 接続の数を数える ss -nat | grep TIME-WAIT | wc -l

数千以上が継続する場合はエフェメラルポートの枯渇が近い。以下でポート範囲も確認する。

sysctl net.ipv4.ip_local_port_range

net.ipv4.ip_local_port_range = 32768 60999

デフォルトは約28,000ポート。TIME_WAITがこれを超えると接続エラーになる。ポート範囲を広げるか(例: 1024 65535)、タイムアウトを短縮するかを選ぶ。

送受信バッファサイズを最適化する(tcp_rmem / tcp_wmem)

大容量ファイルの転送や、高RTT(遠距離・WAN越し)環境でスループットが出ない場合は、TCP送受信バッファが原因のことがある。

tcp_rmem は受信バッファ(受け取る側)、tcp_wmem は送信バッファ(送り出す側)を制御する。各パラメータには「最小値 デフォルト値 最大値」の3つを指定する。

# 現在のバッファ設定を確認 sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem

net.ipv4.tcp_rmem = 4096 131072 6291456 net.ipv4.tcp_wmem = 4096 16384 4194304

単位はバイト。デフォルト値は最大6MB(受信)、4MB(送信)程度だ。高RTT環境では最大値をさらに拡大すると改善できる。

1. バッファを拡張する目安

「帯域幅(bps) × RTT(秒)」が「帯域遅延積(BDP)」と呼ばれる。この値より小さいバッファでは理論帯域が出ない。

例:100Mbps回線、RTT 20ms の場合
・BDP = 100,000,000 bps × 0.020秒 ÷ 8 = 250,000バイト(約244KB)
・デフォルトの最大6MBならこの環境では問題なし
・1Gbps、RTT 100msの場合:BDP = 12.5MB → デフォルト上限を超えるため拡張が必要

2. バッファを変更する例

# 最大値を16MBに拡張する例(高帯域・高RTT環境向け) sysctl -w net.ipv4.tcp_rmem="4096 131072 16777216" sysctl -w net.ipv4.tcp_wmem="4096 16384 16777216" # 自動チューニングの上限も合わせて設定する sysctl -w net.core.rmem_max=16777216 sysctl -w net.core.wmem_max=16777216

バッファを大きくしすぎるとメモリ使用量が増える。 接続数が多いサーバーでは「接続数 × バッファ最大値」がメモリに乗ることを考慮して設定する。

設定を永続化する(/etc/sysctl.d/)

sysctl -w の変更は再起動で失われる。永続化するには /etc/sysctl.d/ 配下に設定ファイルを作成する。

1. 設定ファイルを作成する

cat > /etc/sysctl.d/99-tcp-tuning.conf << 'EOF' # TCP受付キュー net.core.somaxconn = 4096 net.ipv4.tcp_max_syn_backlog = 8192 # 接続タイムアウト短縮 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_tw_reuse = 1 # 送受信バッファ(高負荷サーバー向け) net.ipv4.tcp_rmem = 4096 131072 16777216 net.ipv4.tcp_wmem = 4096 16384 16777216 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 EOF

2. 即時反映する

# 設定ファイルを読み込んで即時反映 sysctl -p /etc/sysctl.d/99-tcp-tuning.conf

net.core.somaxconn = 4096 net.ipv4.tcp_max_syn_backlog = 8192 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_rmem = 4096 131072 16777216 net.ipv4.tcp_wmem = 4096 16384 16777216 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216

再起動後も /etc/sysctl.d/99-tcp-tuning.conf が自動で読み込まれ、設定が維持される。

3. 設定済みか確認する

# 個別に確認する sysctl net.core.somaxconn sysctl net.ipv4.tcp_fin_timeout

net.core.somaxconn = 4096 net.ipv4.tcp_fin_timeout = 30

トラブルシュート:設定が反映されない・問題が起きた

1. sysctl -p で「Permission denied」が出る

rootまたはsudoで実行する。SELinuxが有効な環境では追加設定が必要な場合もある。

sudo sysctl -p /etc/sysctl.d/99-tcp-tuning.conf

2. somaxconnを変えてもSend-Qが変わらない

アプリケーション(nginx・Apacheなど)のバックログ設定も合わせて変更する必要がある。nginxの例:

# /etc/nginx/nginx.conf の listen ディレクティブ listen 80 backlog=4096; listen 443 ssl backlog=4096;

設定変更後に systemctl reload nginx を実行する。

3. tcp_tw_reuseを有効にしたら接続が不安定になった

NATやロードバランサー経由の通信では、同一IP:ポートの組み合わせが短時間に再利用されると「古いパケット」と「新しいパケット」が混在してデータ破損が起きることがある。
tcp_tw_reuse=2(ループバックのみ)に戻してから原因を調査する。

sysctl -w net.ipv4.tcp_tw_reuse=2

4. バッファを拡大したらメモリが不足した

free -h でメモリ使用量を確認する。問題が起きた場合は最大値を半分に減らして様子を見る。

# バッファ最大を8MBに下げる sysctl -w net.ipv4.tcp_rmem="4096 131072 8388608" sysctl -w net.ipv4.tcp_wmem="4096 16384 8388608"

本記事のまとめ

LinuxサーバーのTCPスタックチューニングで押さえるべきパラメータをまとめる。

パラメータ デフォルト 高負荷向け推奨値 効果
net.core.somaxconn 128 または 4096 4096以上 ACCEPTキュー拡大
net.ipv4.tcp_max_syn_backlog 512程度 8192 SYNキュー拡大
net.ipv4.tcp_fin_timeout 60秒 30秒 FIN_WAIT_2短縮
net.ipv4.tcp_tw_reuse 2 1(ロードバランサー配下のみ) TIME_WAIT再利用
net.ipv4.tcp_rmem(最大) 6MB 16MB(高RTT環境) 受信スループット向上
net.ipv4.tcp_wmem(最大) 4MB 16MB(高RTT環境) 送信スループット向上

チューニングの手順は「現状確認(sysctl -a・ss -s)→ 変更(sysctl -w)→ 動作確認(ss -lnt / ss -nat)→ 永続化(/etc/sysctl.d/)」の順で進めること。1つずつ変更して効果を確認するのが現場での鉄則だ。

「高負荷でも落ちないサーバー」は、TCPスタック含めた設計の「型」から生まれます

本番環境で障害が起きてから「somaxconnが足りなかった」と気づくのでは遅い。カーネルパラメータを含めたLinuxサーバーの設計をあらかじめ習得しておくことが、安定運用への最短ルートだ。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。