Hatena::ブログ(Diary)

逆襲のWebエンジニア RSSフィード Twitter

2011-10-12

TIME_WAITのチューニングとkernelリビルド for CentOS 6.0

久しぶりにSRPMからkernelリビルドしてみたので、
過去を振り返りつつ手順をメモ。

ソーシャルゲームや外部のAPIを使用するサービスなどにありがちなんですが、
Webサーバは、受けるHTTPリクエストが多くなると、
外部のWebサーバにHTTPリクエストを送る処理も多くなったりします。
その場合に問題となるのが、tcpのコネクションです。

TIME_WAIT状態のコネクションが多くなると、
接続できる数は上限があるので、接続できたりできなかったり不安定な状態になります。
そうなると、まあ担当者はかなりテンパってますね。
でも負荷的にはサーバはテンパってなかったりします。

TIME_WAIT多発対策はざっくり

  • サーバ増強
    • 緊急対応ということで、あくまで一時的な対応。富豪ならこれでよし。
  • 使用できるTCPポート番号を増やした
    • 増加量が上回る場合は、焼け石に水。
  • tcp_tw_recycleを有効にしてコネクションの再利用
    • パケットのタイムスタンプの影響で外部との通信で問題あり
  • TIME_WAITの値を60秒→15秒に変更
    • TIME_WAITが減り安定動作

そんなわけで、TIME_WAITのチューニングで落ち着きました。
CentOS 5.3でTIME_WAITを15秒にしたカーネルを数年利用していますが、
とくに問題もなく安定しています。

手間だったのは、
この設定変更をするためには、カーネルのリビルドが必要となるため、
全てのサーバに適用するため数台ずつ停止し少しずつ適用していきました。

以下、CentOS 6.0のTIME_WAIT 15秒版カーネルのリビルド手順です。
CentOS5.3の頃と手順はあまり変わらないですが、
少しパスの変更があったようです。

参考 centosとfedora projectのwiki
http://wiki.centos.org/HowTos/RebuildSRPM
http://fedoraproject.org/wiki/Building_a_custom_kernel

TIME_WAITのチューニングとkernelリビルド手順 for CentOS 6.0
1. rpmのビルドに必要なモジュールのインストール

yum install rpm-build.x86_64 \
redhat-rpm-config.noarch \
patchutils.x86_64 \
elfutils-libelf-devel.x86_64 \
binutils-devel.x86_64 \
hmaccalc.x86_64 \
rng-tools.x86_64

他にgccなども必要です

2. SRPM(カーネル)の入手と解凍

cd /usr/local/src
wget http://mirror.centos.org/centos/6.0/updates/SRPMS/kernel-2.6.32-71.29.1.el6.src.rpm
rpm -ivh kernel-2.6.32-71.29.1.el6.src.rpm

3. パッチの作成

■パッチ作成のためのソースをコピーする
cd ~/rpmbuild/SPECS
rpmbuild -bp kernel.spec
cd ~/rpmbuild/BUILD
cp -r ~/rpmbuild/BUILD/kernel-2.6.32-71.29.1.el6/linux-2.6.32-71.29.1.el6.x86_64 ~/rpmbuild/BUILD/kernel-2.6.32-71.29.1.el6.orig
cp -r ~/rpmbuild/BUILD/kernel-2.6.32-71.29.1.el6/linux-2.6.32-71.29.1.el6.x86_64 ~/rpmbuild/BUILD/kernel-2.6.32-71.29.1.el6.new

rpmbuild中にPGPの鍵作成に時間がかかりすぎる場合は、
次のコマンドを別コンソールで実行する。

rngd -r /dev/urandom

特にOS新規インストールのサーバは、この画面から進まない・・・。

### Now generating a PGP key pair to be used for signing modules.
### ---------------- 途中 省略 ---------------
### If one isn't available, the pseudo-random number generator can be used:
###
### rngd -r /dev/urandom
###
+ gpg --homedir . --batch --gen-key /root/rpmbuild/SOURCES/genkey
gpg: WARNING: unsafe permissions on homedir `.'


■tcp.hファイルを修正する
cd ~/rpmbuild/BUILD
vi kernel-2.6.32-71.29.1.el6.new/include/net/tcp.h

次の1行を修正する。(TIME_WAITを60秒→15秒)
修正前
#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
修正後
#define TCP_TIMEWAIT_LEN (15*HZ) /* how long to wait to destroy TIME-WAIT

■パッチを作成する
diff -uNrp kernel-2.6.32-71.29.1.el6.orig kernel-2.6.32-71.29.1.el6.new > ../SOURCES/tcph.patch

4. ビルドの準備

■パッチを適用するためkernel.specファイルを修正する
cd ~/rpmbuild/SPECS
vi kernel.spec

修正前
# % define buildid .local
修正後
%define buildid .tcp15

※新カーネルインストールの際にkernel-firmwareの同じbuildid版を要求されたのでやめました。

# empty final patch file to facilitate testing of kernel patches
Patch00: tcph.patch  ←追加
Patch999999: linux-kernel-test.patch

ApplyOptionalPatch tcph.patch  ←追加
ApplyOptionalPatch linux-kernel-test.patch

5. TIME_WAIT変更版カーネルのビルド

rpmbuild -ba kernel.spec

6. カーネルのアップデート

cd ~/rpmbuild/RPMS/x86_64
rpm -Uvh --force kernel-2.6.32-71.29.1.el6.x86_64.rpm kernel-2.6.32-71.29.1.el6.x86_64.rpm

再起動
reboot

7. TIME_WAITの確認

1秒間隔でウォッチ
watch -n 1 "netstat -a | grep http"

次のようにTIME_WAITになるので、
15秒後に消えたら動作しています。

Every 1.0s: netstat -a | grep http tcp 0 0 *:http *:* LISTEN
tcp 0 0 ::ffff:192.168.xxx.xxx:http ::ffff:192.168.xxx.xxx:30439 TIME_WAIT


以上、とくにかくリビルドに時間かかるので、時間に余裕があるときに放置しながらがよいかと思います。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証