web-dev-qa-db-ja.com

Linux IPルーティングパラメータのチューニング-secret_intervalおよびtcp_mem

今日、HAProxy VMの1つで少しフェイルオーバーの問題がありました。掘り下げたところ、次のことがわかりました。

 Jan 26 07:41:45 haproxy2カーネル:[226818.070059] __ratelimit:10個のコールバックが抑制されました
 Jan 26 07:41:45 haproxy2カーネル:[226818.070064]ソケットメモリ不足
 Jan 26 07:41:47 haproxy2カーネル:[226819.560048]ソケットメモリ不足
 Jan 26 07:41:49 haproxy2カーネル:[226822.030044]ソケットメモリ不足

このリンク のように、net.ipv4.tcp_memのデフォルト設定が低くなっているようです。そのため、デフォルトから4倍に増やしました(これはUbuntuサーバーですが、Linuxの種類が重要かどうかはわかりません)。

現在の値は次のとおりです:45984 61312 91968 
新しい値は次のとおりです:183936 245248 367872 

その後、奇妙なエラーメッセージが表示され始めました。

 Jan 26 08:18:49 haproxy1カーネル:[2291.579726]ルートハッシュチェーンが長すぎます!
 Jan 26 08:18:49 haproxy1カーネル:[2291.579732] secret_intervalを調整してください!

Shh ..それは秘密です!!

これは明らかに/proc/sys/net/ipv4/route/secret_intervalと関係があり、デフォルトで600に制御されます ルートキャッシュの定期的なフラッシュ

secret_intervalは、すべてのルートハッシュエントリがどれだけ新しい/古いものであるかに関係なく、どれだけ頻繁に消去されるかをカーネルに指示します。私たちの環境では、これは一般的に悪いことです。キャッシュがクリアされるたびに、CPUは1秒あたり数千のエントリの再構築でビジー状態になります。ただし、メモリリークを防ぐために、これを1日に1回実行するように設定しました(メモリリークは発生していません)。

これを減らして満足していますが、単に古い値をルートから押し出すのではなく、定期的にルートキャッシュ全体を削除することをお勧めするのは奇妙に思えます。キャッシュを高速化します。

調査の結果、/proc/sys/net/ipv4/route/gc_elasticityが見つかりました。これは、ルートテーブルのサイズを抑えるためのより良いオプションのようです。

gc_elasticityは、カーネルがルートハッシュエントリの期限切れを開始する前に受け入れる平均バケット深度として最もよく説明できます。これにより、アクティブなルートの上限を維持できます。

ルートキャッシュがより積極的にプルーニングされることを期待して、弾力性を8から4に調整しました。secret_intervalは、私たちには正しいと感じません。しかし、たくさんの設定があり、どれが本当にここに行くのが正しい方法なのかは不明です。

  • / proc/sys/net/ipv4/route/gc_elasticity(8)
  • / proc/sys/net/ipv4/route/gc_interval(60)
  • / proc/sys/net/ipv4/route/gc_min_interval(0)
  • / proc/sys/net/ipv4/route/gc_timeout(300)
  • / proc/sys/net/ipv4/route/secret_interval(600)
  • / proc/sys/net/ipv4/route/gc_thresh(?)
  • rhash_entries(カーネルパラメータ、デフォルトは不明?)

Linuxルーティングを悪化させたくないので、これらの設定のいくつかをいじることを恐れています。

トラフィックの多いHAProxyインスタンスに対して、チューニングするのに最適なルーティングパラメータを誰かにアドバイスできますか?

30
Jeff Atwood

この問題に遭遇したことはありません。ただし、その深さを減らすために、おそらくハッシュテーブルの幅を増やす必要があります。 「dmesg」を使用すると、現在のエントリ数がわかります。

$ dmesg | grep '^IP route'
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)

この値は、カーネルブートコマンドラインパラメータrhash_entriesで変更できます。まず手動で試してから、lilo.confまたはgrub.confに追加してください。

例:kernel vmlinux rhash_entries=131072

HAProxy VM(ルートハッシュサイズは合計RAMに応じて調整されます)に割り当てるメモリが少ないため、ハッシュテーブルが非常に制限されている可能性があります。

tcp_memについては、ご注意ください。初期設定では、1 GBのRAMで実行していたと思います。その3分の1をTCPソケットに割り当てることができます。これで367872 * 4096バイトが割り当てられました= 1.5 GBの= RAM to TCPソケット。メモリ不足にならないように十分注意する必要があります。経験則では、メモリの1/3をHAProxyに割り当て、 TCP=スタックへの別の1/3と、システムの残りの部分への最後の1/3です。

「ソケットメモリ不足」メッセージは、tcp_rmemtcp_wmemのデフォルト設定から送信されたものと思われます。デフォルトでは、各ソケットの出力に64 kB、入力に87 kBが割り当てられています。これは、プロキシー接続の場合、ソケット・バッファーのみで合計300 kBであることを意味します。 HAProxyの16または32 kBに追加すると、1 GBのRAMで3000接続のみがサポートされます。

tcp_rmemtcp_wmem(中間パラメーター)のデフォルト設定を変更することで、メモリを大幅に削減できます。書き込みバッファで4096という低い値と、tcp_rmemで7300または16060(5または11 TCPセグメント)の値で良好な結果が得られます。再起動せずにこれらの設定を変更できます。ただし、これらは新しい接続にのみ適用されます。

sysctls にあまり触れたくない場合は、最新のHAProxy 1.4-dev8を使用すると、グローバル構成から、またサイド(クライアントまたはサーバー)からこれらのパラメーターを微調整できます。

これが役に立てば幸いです!

28
Willy Tarreau

Out of socket memory errorは誤解を招くことがよくあります。ほとんどの場合、インターネットに面したサーバーでは、メモリ不足に関連する問題を示しているわけではありません。 ブログ投稿 ではるかに詳細に説明したように、最も一般的な理由は、孤立ソケットの数です。孤立ソケットは、ファイル記述子に関連付けられていないソケットです。特定の状況では、制限(Out of socket memory error)から2倍または4倍離れていても、カーネルは/proc/sys/net/ipv4/tcp_max_orphansを発行します。これはインターネット向けサービスで頻繁に発生し、完全に正常です。この場合の正しい行動は、tcp_max_orphansを、トラフィックのピークで通常見られる孤児の数の4倍以上になるように調整することです。

あなたが本当にあなたが何を知っているのでない限り、tcp_memまたはtcp_rmemまたはtcp_wmemのチューニングを推奨するアドバイスを聞かないでくださいやっている。通常、これらのアドバイスを提供する人はしません。彼らのブードゥー教はしばしばあなたの環境にとって間違っているか不適切であり、あなたの問題を解決しません。それはさらに悪化するかもしれません。

8
tsuna