自作サーバを半年運用して

世間ではディスられ傾向にある自作サーバですが、自分では初期コスト以外のメリットもあると考えています。

まず、手間がかかることです。
手間をかけて運用を安定化させていく中で、問題や疑問にぶちあたりまくりました。
単にバッドノウハウがたまっていくだけでなく、チューニングすべき箇所や、リソース配分の極端な偏りや、普通だったら考えもしない見えにくいボトルネックが自然と見えてきました。
システムの負荷をLAやIO wait等でざっくりみて「もう限界だー」とベンダーサーバに乗り換えたところで、同じ理由がボトルネックになるのは目に見えています。
ハードウェアが変わってもOSは変わりませんからね。
箱だし設定で高いサーバをつかってもお金の無駄です。うらやまけしからんです。

壊れるけどメンテは案外しやすい
ハイスペックなサーバを必要最低限の台数で運用していた時と、安い自作サーバを並べて1,2台壊れてもいい運用を比べると、データセンターにいかなきゃいけない頻度はあまり変わらない感覚です。
台数が少ないと、メモリエラーやディスク故障など、安全を考えるとその場で対応しないといけないので、なんだかんだで手間がかかります。
共食い修理も自作サーバの利点ですね。MiG-21とF-15くらいの感覚です。

中の人が育つ
どこかの豆腐屋の86じゃないですけど、完成されたベンダーのサーバと比べるとやはり問題だらけです。
ひとつひとつの問題をじっくり解決することによって、みっちり経験をつむことができました。
自作サーバを将来捨てないといけない時が来るかもしれませんが、サーバのリソースをしゃぶりつくすくらいまでチューニングノウハウがたまったので、自分の会社はいつハイスペックなサーバに乗り換えてもコストに見合った使い方もできるし、増える続けるコストに悩むことはないでしょう。

とかいろいろ書いてみたら、自作サーバじゃなくても環境があれば十分ふかぼりして楽しめますよね。そもそも予算が潤沢にあれば考える必要がまったくないことです。
ちなみに自分はProliant大好きです。

netfilterのconntrack_maxとhash sizeの関係

netfilterに片足を突っ込んでしまってから、あまり気にかからないところが気になるようになってしまいました。墓穴を掘り続ける日々が続いています。

今回はconntrack_maxとhash size(conntrack_buckets)の関係についてです。

先に書いておきます。メモリ容量から逆算するconntrack_maxとhash sizeの計算公式はココに書いてあります。チューニングの推奨値とは別の疑問です。

conntrackテーブルにある[ASSURED]の数が実質の上限数を左右するところまでは、なんとなくつかんでいたんですが、負荷の高いGWでもピークで1万本程度と、限界値となるパラメータの設定値についてあまり気にしていませんでした。

疑問を持ったきっかけは、今週うっかりapサーバが[ASSURED]なconntrackテーブルを10万本もっていることに気づいてしまったことです。
大半がnginx->apacheのローカルホストからローカルホストへのリバースプロクシのconntrackテーブルでした。

apサーバはpuppetを通るとconntrack_maxを、特に何も考えずに524288に設定されるようになっているのですが、ぐぐったらすぐに出てくる某所に書いてあるconntrack_max / 8だと65536でドロップが出るはずですが、まったくでていません。

なんとなく調べた結果は以下のような感じです。

・conntrack_max / 8 は最初に書いたwikiにあるように、hash sizeの推奨値であって、上限値ではない。
・あくまでconntrack_maxの値が上限値。

ヒントはnetfilterのソース読んだり、よく分からないwikiでみつけたのですが、大量に保持しているconntrackテーブルに対して、hash size(conntrack_buckets)はconntrackテーブルをハッシュ化してすばやく検索できるようにするもの(?)といった感じです。
conntrack_maxだけでかくしても問題ないけど、検索するためのハッシュ領域が少なすぎて効率が悪いという内容みたいですね。

iptablesでゴリゴリFWしている場合は、conntrackテーブルを活用したほうが効率がいいはずですが、gwでマスカレードだけしてるとか、apサーバではそもそもconntrackテーブルを大量にを保持するだけCPUとメモリの無駄になっているかもしれません。

conntrackのタイムアウトを短めにしてCPUとメモリを節約したほうがパフォーマンスがよくなるかもしれませんね。
もう少し調べないとだめです。

自作サーバの節電対策をしてみた

データセンターの電気代は固定ですし、エコはエゴだと思っているので、グリーン的な要素はいっさいありません。
安くて台数そろえてナンボの自作サーバ。数ワットでも節電できればさらに詰め込めるのでは?という趣旨です。目標はアイドルで一割減。

またラップトップチューニングと違って、APサーバはパフォーマンス優先なのでいろいろアイドルに持っていくことは期待できません。
コールを減らすためにアプリに手をつけるのも効果がみにくいために非現実的です。
ですので無駄に火がはいっているものをどんどんオフにしていきました。以下のような感じです。

  • オンボードオーディオデバイス
  • プライマリVGAをオンボードにする
  • USB3.0コントローラ(USB2.0だけ使う)
  • SATA2コントローラ(SATA3のポートだけ使う)
  • WoL
  • パラレル、シリアルポート
  • IGPUの定格を下げる
  • メモリクロックを下げる(1600→1033で0.5Wほど下がったがパフォーマンス優先のために1600で)
  • USBポートをサスペンド

これで5W近く減らすことができました。アイドル状態で32Wちょっとから28W前後までもっていくことができました。掛ける台数なので、浮いた電気で1ラック2,3台はサーバが増やせそうですね。

BICC Rally of Tsumagoi 2013に行って来ました

忙しい中安価で防寒具を集めたのに、現地の気温は10度。パルコールはダートラ状態・・・。

 

朝早く出たつもりだったのに鶴ヶ島で左足筋トレ大会とか、行く先々でラリー参加車に間違われたり、飲みすぎて二日酔いでヘブン状態で帰ってきたりと、いろいろ楽しめました。
来年は出場したいですね。

netfiterのip_conntrackの上限について掘り下げてみた

conntrackの値を監視しようとしてスクリプトを作っている最中にこんなことに気づきました。

cat /proc/sys/net/ipv4/netfilter/ip_conntrack_count
53424

いくらなんでも多すぎじゃね、っていうか実際こんなにコネクションが残ってたらポートが枯渇するかどうかっていう話になってしまいます。

さっそく内容を確認してみました。conntrackコマンドでもprocfsでもどちらでも確認することができます。
5万行でてくるのでheadで一部だけ見ます。

$ sudo head -n 3 /proc/net/ip_conntrack
tcp      6 180817 ESTABLISHED src=10.x.x.xx dst=1.xx.x.xx sport=80 dport=52843 [UNREPLIED] src=1.xx.x.xx dst=xxx.xx.x.xxx sport=52843 dport=80 mark=0 use=2
tcp      6 88234 ESTABLISHED src=10.x.x.xx dst=1.xx.xxx.xxx sport=80 dport=64778 [UNREPLIED] src=1.x.xxx.xxx dst=xxx.xx.x.xxx sport=64778 dport=80 mark=0 use=2
tcp      6 329583 ESTABLISHED src=10.x.x.xx dst=1.x.x.x sport=80 dport=63624 [UNREPLIED] src=1.x.x.xx dst=xxx.xx.x.xxx sport=63624 dport=9 mark=0 use=2

3個目のカラムはタイムアウトです。ESTABLISHEDなTCPだとデフォルト値の5日間残ります。この時点で慌ててタイムアウトの値を小さくしたのですが、テーブルをFLUSHするのも怖いので、5日間かけて消えてなくなるのをじっくり待つことにしました。

しかし[UNREPLIED]ってなんぞやと思い調べてみたところ、公式に回答がのっていました。

http://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#THECONNTRACKENTRIES

通信が双方から行われていないと[UNREPLIED]になるようです。TCPのセッションとしては残っていないけど、conntrackのテーブルに記憶されている状態なのかな。
[ASSURED]は破棄されないと書いてあるので、実際は[ASSURED]の数が上限値という感じでしょうか。こちらは全体で100ちょっとでした。

さらにこんなものをみつけました。

http://archive.linux.or.jp/JF/JFdocs/netfilter-faq-3.html#ss3.16

あなたは /proc/net/ip_conntrack を見て、UNREPLIED エントリに非常に大きな タイマ値(最高で5日)が割り当てられているのに気付き、どうして我々が (明らかにコネクションではない) UNREPLIED エントリに無駄に conntrack エントリを使おうとするのかと不思議に思われたのですね?
その答えは簡単です: UNREPLIED エントリは、テンポラリなエントリだからです。 つまり、コネクション追跡エントリが限界まで来たらすぐに、古い UNREPLIED エントリを削除します。言いかえると、conntrack を何も持たないよりは、 UNREPLIED エントリの中の有用かもしれない情報を、それが実際に必要 とするまで保持しておくのがよいだろうというわけです。

「何度もトラッキングしなおすよりメモリにおいといたほうがいいだろwww」

ってことですかね。
しかし、メモリにたくさんとっておいてスキャンするコストと、少ない件数をメモリに残しておいて新しくトラッキングさせるのは、どっちがコストが安いんでしょうね。
もう少し調べる必要がありそうです。