連休を使って、負荷のキツくなってきたサーバを移転してるのですが。覚悟していたほどではないにしても、色々と問題が発生しました。そのうちのひとつが、Amazon S3への転送に失敗するようになったこと。途中で接続が切れる様子。
$ s3cmd put bkup-data:xxxx.tar.gz /tmp/xxxx.tar.gz Connection reset: Connection reset by peer 99 retries left
使っているのは、Amazon S3のRubyライブラリ。バージョンは1.2.6です。
今回はCentOS 5.3から6.2への移行。S3ライブラリや転送するデータサイズ、相手のバスケットなどは変えていないので、やっぱりカーネル関係なんだろうなと。しかし、なかなか原因が特定できず、結構ハマりました。
以前は定期的に2G~3G程度のファイルを送っていたのですが、何度やっても切られるので断念。試しに2Mくらいのファイルを送ったら成功。50Mではアウト。割と早い段階で壁に当たってしまいます。最初はtarのまとめ単位を変えるなりsplitするなりして小さくして回避しようかとも思ったのですが、このサイズだと実際問題厳しすぎる。
で、まぁ色々やってみて、なんとなく特定できたのはLinuxカーネル2.6.17以降でTCP Windowバッファが自動チューニングされるようになっていると。コイツが、どうにかすると他のギアと干渉しあって接続を切るような挙動をしてしまうようです。実際にそうした干渉を確認できたワケではなく、そうらしいよという記述をこの辺やこの辺りで読んで調整入れたところで上手くいったので、そこで止めてしまった曖昧情報で申し訳ないのですが。
ともあれ上手くいったのは、ソケットのバッファ用メモリサイズを手動で設定すること。
/etc/sysctl.conf に、次のような記述を追加します。
net.core.rmem_max = 1747600 net.core.wmem_max = 1747600 net.ipv4.tcp_wmem = 4096 87380 1747600 net.ipv4.tcp_rmem = 4096 87380 1747600
ファイルを書き換えたら、端末をリブートするか、次のコマンドを実行。
$ sudo sysctl -p
正直なところ、バッファサイズをどの程度にすれば良いのか、よく分かりませんでした。この10倍くらいに設定している例もあれば、半分以下のものもあり。試した人の記述では、転送するファイルの総量が大きいほどに値を下げると上手くいくとありました。もちろん、下げすぎればネットワークのパフォーマンスに悪影響が出ます。せっかく自動チューニングしてくれるのだから、そちらに任せたいのですが…残念。しばらく様子見ながら、値は調整するかもしれません。
恐らく、S3に限らずサーバからソケット繋いでファイル転送する色々なサービスで起きる問題なんじゃないかと。同様の問題に当たって変更される場合、あくまで自己責任でお願いします。
No related posts.