2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

背景

大規模なクローリングを行うバッチシステムを構築している際、TCPコネクションが同時に多数確立することでTIME_WAIT状態のものでいっぱいになっていました。、これにより、利用可能なエフェメラルポートが枯渇してクローリングの時間が長くなりすぎていたので、カーネルパラメータをチューニングしてみました。

参考

確認

  • 使用ポート数
    • netstat | grep tcp | wc -lなどで確認可能
  • TIME_WAIT
    • netstat -nat | grep TIME_WAIT | wc -lなどで確認可能
    • 自身のWEBサーバーでlistenしている場合はgrep -v :80grep -v :443などで除く必要がある
  • カーネルパラメータ
    • cat /etc/sysctl.confで確認
    • sysctl -aで一覧確認
    • sysctl -n {param}で対象パラメータの設定値を確認

カーネルパラメータ

今回のような事象に有効なlinuxカーネルのパラメータについて
デフォルトはcentos 7.9.2009での値

net.core.somaxconn

  • default : 128
  • description : ESTABLISHED状態のソケット上限
  • note : アプリケーション側での設定で接続数増やそうと頑張ってもここを増やさないと変わらない

net.ipv4.tcp_max_syn_backlog

  • default : 512
  • description : SYN_RECEIVED状態のソケット上限
  • note : net.core.somaxconnの上限値が優先される

net.ipv4.tcp_tw_reuse

  • default : 2
  • description : TIME_WAIT状態から1秒以上経過したソケットのポートを新しい接続に再利用する

net.ipv4.tcp_fin_timeout

  • default : 60
  • description : FIN_WAIT_2のタイムアウト設定
  • note : TIME_WAITのタイムアウトではない.相手から最後のFINパケットを受け取るまで待機し、TIME_WAITに移行する

net.ipv4.tcp_max_tw_buckets

  • default : NR_FILE*2
  • description : システムが許容する TIME_WAIT 状態にあるソケットの最大数

net.ipv4.ip_local_port_range

  • default : 32768 60999
  • description : 使用可能なポート範囲
  • note : netstatで確認した大まかなポート使用数が設定値より十分に小さければ問題ない. 上限は1024 65535

net.ipv4.ip_local_reserved_ports

  • default : -
  • description : 予約済みのポート.port_rangeを広げた場合などに使用

設定

上記を踏まえて高負荷条件下での設定値を考えます

  1. net.ipv4.tcp_tw_reuseを1にする
    • TIME_WAIT状態が溜まっているような場合はこれがよく効きます
  2. net.core.somaxconnを増やす
    • こちらはデフォルト値が128と少ないので増やしたほうがいい
    • よく見る設定値としては1024や2048でしょうか
    • net.ipv4.tcp_max_syn_backlogも一緒に増やす
  3. net.ipv4.tcp_fin_timeoutを減らす
    • FIN_WAIT_2状態が溜まっているような場合には有効
    • 設定値は状況によって変化しうる
      • e.g. バッチなら5秒, WEBサーバーなら30秒とか

一時的に設定する例

sysctl -n {name}={value}

# sysctl -w net.core.somaxconn=1024
net.core.somaxconn=1024
# sysctl -w net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_reuse=1
# sysctl -w net.ipv4.tcp_fin_timeout=30
net.ipv4.tcp_fin_timeout=30

永久的に設定する場合

  1. vi /etc/sysctl.conf : 設定値の書き換え
  2. sysctl -p : 更新の反映
# vi /etc/sysctl.conf
# cat /etc/sysctl.conf
net.core.somaxconn = 1024
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_fin_timeout=30
# sysctl -p

例のようにとりあえずシステムに影響のない範囲から始めて、様子見ながら状況に応じて他のパラメータなども設定していくという流れが良いかと思われます。

結果

自分の場合、アプリケーション側でのコネクションプーリングに加え上記の設定を反映させることでクローリング終了までの時間が50h -> 7hくらいに大幅に改善しました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?