Redis.confのtcp-backlog
で混乱しています:
# TCP listen() backlog.
#
# In high requests-per-second environments you need an high backlog in order
# to avoid slow clients connections issues. Note that the Linux kernel
# will silently truncate it to the value of /proc/sys/net/core/somaxconn so
# make sure to raise both the value of somaxconn and tcp_max_syn_backlog
# in order to get the desired effect.
tcp-backlog 511
tcp-backlog
は「完全な接続キュー」(3方向ハンドシェイクが完了しました。説明は ここ )または「不完全な接続キュー」のサイズですか?
「完全な接続キュー」を意味する場合、不完全な接続キューのサイズを制限するtcp_max_syn_backlog
を上げる必要があるのはなぜですか?
Tcp-backlogは、「完全な接続キュー」(スリーウェイハンドシェイクが完了しました。ここで説明します)または「不完全な接続キュー」のサイズですか?
_tcp-backlog
_は完全な接続キューのサイズです。実際、Redisはこの構成をlisten(int s, int backlog)
呼び出しの2番目のパラメーターとして渡します。
@GuangshengZuoはすでにこの質問に対して良い答えを持っていました。それで、私はもう一方に焦点を合わせます。
「完全な接続キュー」を意味する場合、不完全な接続キューのサイズを制限するtcp_max_syn_backlogを上げる必要があるのはなぜですか?
あなたが言及したドキュメントからの引用:
実装では、SYNキュー(または不完全な接続キュー)と受け入れキュー(または完全な接続キュー)の2つのキューを使用します。状態SYNRECEIVEDの接続はSYNキューに追加され、状態がESTABLISHEDに変わると、つまり3ウェイハンドシェイクのACKパケットが受信されると、後で受け入れキューに移動されます。名前が示すように、accept呼び出しは、単にacceptキューからの接続を消費するために実装されます。この場合、listen syscallのbacklog引数によって、受け入れキューのサイズが決まります。
_complete connection queue
_のアイテムが_incomplete connection queue
_から移動されていることがわかります。
大きなsomaxconn
と小さな_tcp_max_syn_backlog
_がある場合、_complete connection queue
_に移動するのに十分なアイテムがない可能性があり、_complete connection queue
_がいっぱいになることはありません。多くのリクエストは、2番目のキューに移動する前に、最初のキューからすでに削除されている可能性があります。
したがって、somaxconn
の値を上げるだけでは機能しない可能性があります。あなたはそれらの両方を上げる必要があります。
Tcp-backlogは、受け入れキューまたは完全な接続キューのサイズです。
あなたが言及したドキュメントが言ったように:
Linuxでは、listen syscallのmanページに記載されているように、状況は異なります。
TCPソケットでのバックログ引数の動作はLinux2.2で変更されました。これで、不完全な接続要求の数ではなく、受け入れを待機している完全に確立されたソケットのキューの長さが指定されます。最大長不完全なソケットのキューの数は、/ proc/sys/net/ipv4/tcp_max_syn_backlogを使用して設定できます。
これは、現在のLinuxバージョンが2つの異なるキューで2番目のオプションを使用することを意味します。システム全体の設定で指定されたサイズのSYNキューと、アプリケーションで指定されたサイズの受け入れキュー
Redisサーバーは、tcp-backlogの構成を使用して、listen()で受け入れキューのサイズを指定します。また、SYNキューのサイズは、Linuxの管理者によって決定されます。
「完全な接続キュー」を意味する場合、不完全な接続キューのサイズを制限するtcp_max_syn_backlogを上げる必要があるのはなぜですか?
Tcp_max_syn_backlogを上げることは、遅いクライアント接続の問題を回避するを目的としています。 redisサーバーとの3ウェイハンドシェイクを実行している遅いクライアントがあり、これらのクライアントが応答の読み取りと要求の送信に時間がかかる場合、それらは遅いため、redisサーバーのSYNキューを長時間使用します。
また、場合によっては、これらの非効率的なクライアントが原因で、SYNキューがいっぱいになります。 SYNキューがいっぱいになると、redisサーバーは新しいクライアントを受け入れることができません。したがって、これに対処するには、tcp_max_syn_backlogを上げる必要があります。
昨日、Redis InActionの第6章を読みました。JoshuaCarltonは次のように書いています。「Redisのパブリッシュ/サブスクライブモデルの欠点の1つは、メッセージを受信するためにクライアントを常に接続する必要があることです。切断すると、クライアントがメッセージを失う可能性があります。また、古いバージョンのRedisは、サブスクライバーが遅いと、使用できなくなったり、クラッシュしたり、強制終了されたりする可能性があります。」
次に、Joshua Carltonは次のように述べています。「プッシュメッセージングは便利ですが、何らかの理由でクライアントが常に接続を維持できない場合に問題が発生します。この制限に対処するために、2つの異なるプルメッセージングメソッドを作成します。 PUBLISH/SUBSCRIBEの代わりに使用できます。ファーストイン、ファーストアウトのキューと多くの共通点があるため、最初に単一受信者のメッセージングから始めます。このセクションの後半で、メッセージの複数の受信者を持つことができる方法。複数の受信者がある場合、メッセージが切断されていても、すべての受信者に到達する必要があるときに、RedisPUBLISHとSUBSCRIBEを置き換えることができます。」よりパフォーマンスが高いかどうかを知りたい切断損失を検出して修復するためにUDPプロトコルを利用する代わりに、RedisPUBLISHとSUBSCRIBEをJoshuaCarltonのセクション6.5.2複数受信者のパブリッシュ/サブスクライブの置き換えに置き換えます。
Could we set a high tcp_max_syn_backlog in redis.conf to prevent either of
Joshua Carlsonの単一受信者メッセージング、および複数受信者メッセージング方式は、各メッセージが20バイトである1秒あたり20,000メッセージの負荷の下で切断されませんか?