Linux IPルーティングパラメーターの調整— secret_intervalおよびtcp_mem


30

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

1月26日07:41:45 haproxy2カーネル:[226818.070059] __ratelimit:10コールバックの抑制
1月26日07:41:45 haproxy2カーネル:[226818.070064]ソケットメモリ不足
1月26日07:41:47 haproxy2カーネル:[226819.560048]ソケットメモリ不足
1月26日07:41:49 haproxy2カーネル:[226822.030044]ソケットメモリ不足

このリンクごとに、のデフォルト設定が低いことに関係しているようですnet.ipv4.tcp_mem。そのため、デフォルトの4倍に増やしました(これはUbuntu Serverであり、Linuxフレーバーが重要かどうかはわかりません)。

現在の値:45984 61312 91968
新しい値:183936 245248 367872

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

Jan 26 08:18:49 haproxy1 kernel:[2291.579726]ルートハッシュチェーンが長すぎます!
Jan 26 08:18:49 haproxy1 kernel:[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インスタンスに対して、どのルーティングパラメーターを調整するのが最適かをアドバイスできますか?

回答:


28

この問題に遭遇したことはありません。ただし、ハッシュテーブルの深さを減らすには、おそらくハッシュテーブルの幅を増やす必要があります。「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で実行しており、その1/3をTCPソケットに割り当てることができると思われます。367872 * 4096バイト= 1.5 GBのRAMをTCPソケットに割り当てました。メモリ不足にならないように十分注意してください。経験則では、メモリの1/3をHAProxyに、さらに1/3をTCPスタックに、最後の1/3をシステムの残りに割り当てます。

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

tcp_rmemand tcp_wmem(middle param)のデフォルト設定を変更することにより、メモリを大幅に削減できます。書き込みバッファの値が4096で、7300または16060インチtcp_rmem(5または11 TCPセグメント)の値で良い結果が得られます。再起動せずにこれらの設定を変更できますが、新しい接続にのみ適用されます。

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

これが役立つことを願っています!


8

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_rmemtcp_wmem自分何をしているのか本当にわかっていない限りは聞いてはいけません。これらのアドバイスを提供する人は通常そうではありません。彼らのブードゥー教はあなたの環境にとってしばしば間違っているか不適切であり、あなたの問題を解決しません。さらに悪化するかもしれません。


1
これが発生すると、メッセージはdmesgで異なり、「孤立したソケットが多すぎます」と表示されます。ただし、孤児は大量のメモリを消費する可能性があることに同意します。
ウィリータロー

数を超える/proc/sys/net/ipv4/tcp_max_orphansと、別のエラーが発生します。たとえば、スタック交換スタック全体/proc/sys/net/ipv4/tcp_max_orphansは65536であり/proc/net/sockstat、TCPはinuse 2996 orphan 171 tw 15972 alloc 2998 mem 1621-無視できない違いです。
ジェフダルガス

-4

これらのパラメータの一部は定期的に調整されます。高スループット、低レイテンシの取引プラットフォームの標準は次のとおりです。

net.ipv4.tcp_rmem = 4096 16777216 33554432
net.ipv4.tcp_wmem = 4096 16777216 33554432
net.ipv4.tcp_mem = 4096 16777216 33554432
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 30000
net.core.netdev_max_backlog = 30000

1
Willyの数学によると、標準のメモリプレッシャー#(中央の数字)は68 GBです。3回(rmem、wmem、mem)??
ジェフアトウッド

10
これらの調整パラメータは間違っており、ベンチ環境で非常に頻繁に検出され、盲目的にコピー&ペーストされます。少数の同時セッションで問題は発生しませんが、100個のTCPソケットでも3.2 GBのRAMを割り当てます。待ち時間が短い限り、疑わしいことに気付くことはありません。転送中にリモートマシンを取り外して、出力バッファがいっぱいになるのを見るか、ローカルタスクをフリーズして入力バッファがいっぱいになるのを見るだけです。これは...正気です
ウィリーTarreau

6
ジェフ、これは3回ではありません。tcp_memはページ単位で、グローバルサイズを定義します。tcp_rmemおよびtcp_wmemはバイト単位で、ソケットごとのサイズを定義します。
ウィリータロー

これらの調整可能パラメータは間違っているように見えます。小さなデータを使用する同時サーバーの場合、あまり多くのソケットバッファーを予約したくなく、tcp_memはr / wmemとはまったく異なり、同じ数値を使用しても意味がありません(一方は接続ごとにバイトですシステムあたりのページ数)
19:12に確認
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.