Linux TCPパラメータチューニング
6918 ワード
この文章を書く前に、tcp too many orphaned sockets問題が引き起こした思考について、主に下ポートについて話しました.socket関連も一部のパラメータのチューニングに関連していますが、最近、ネット上の問題がいくつかのチューニングに関連しているので、TCPチューニングに関するブログを単独で整理しても、そんなに冗長で雑然としていないと思います.
(以下、/etc/sysctl.confにおけるパラメータの変更はすべて永続的な変更であり、後述しない.方法:パラメータを/etc/sysctl.confに追加し、sysctl-pを実行してパラメータを有効にし、永続的に有効にする)
ポート切れの問題については、前のブログでも話していましたが、ここはくどくありません.一般的にサービス側としては、1つのポートを傍受し、forループしてaccept接続を行い、処理すればよい.したがって、サービス側ポートが消費されることは一般的には存在しない.例えばgolangのコード:
もちろん、サーバーには通常1つのサービスしかありません.他のサービスもあるかもしれません.あるいは、あなたのサービスが要求を受けた後、clientとして他のサービスを呼び出します.このとき、マシンのポート範囲に注目する必要があります.チューニングポイント1:デフォルトポート範囲
状況に応じて調整できます.たとえば、次のようにします.
accpet呼び出しに成功すると接続が確立され、javaではsocketが直接返され、golangではnetが返されるようにパッケージされています.Connですが、最終的な結果は同じです.このsocketを持って読み書きすることで、socketの本質はファイル記述子です.これは前のブログでも話しました.
上のくだらない話がこんなに多いのは、socketがファイルリソースとしてLinuxシステムの制限を受け、勝手に無限に使用することはできません.この制限は、ファイル記述子リソースに対するLinuxの制限に現れます.利点2:チューニング可能なパラメータは次のとおりです.ユーザーレベルLinuxシステムユーザーが最大で開くファイル制限 を表示
開くファイル制限vim/etc/security/limitsを変更します.conf
ここでrootは、どのユーザのオープンファイル数制限を変更するかを指定します.使用可能な'*'番号は、すべてのユーザーの制限を変更することを示します.ソフトまたはhardは、ソフトリミットを変更するかハードリミットを変更するかを指定します.102400は、変更する新しい制限値、すなわち最大オープンファイル数を指定します(ソフト制限値がハード制限値以下であることに注意してください).システムレベル調整の利点3:Linuxシステムの同時オープンファイル数に対するハード制限の表示:
この制限とは、システム全体でサポートする最大値がfile-max制限、/etc/sysctlを変更するすべてのユーザの合計を指す.confファイル
普通の良い機械ではこの値はまだ大きいです.
Linuxのファイルリソースに対する制限について述べたほか、TCPは情報を送受信する際にバッファがあり、バッファはメモリリソースであり、すべてのLinuxシステムもこのリソースを制限しなければならないことを知っています.
チューニングポイント4:バッファチューニングTCPTCPデータ受信、送信ウィンドウサイズ を設定.
この2つのパラメータもあります
最初の値はsocket受信バッファに割り当てられた最小バイト数である.2番目の値はデフォルト値(rmem_defaultで上書きされます)で、バッファはシステム負荷が重くない場合にこの値に増加します.3番目の値は、受信バッファ空間の最大バイト数(rmem_maxで上書きされる)である. TCPが総メモリを使用することができるというパラメータは、システム内のTCPのすべての使用可能なメモリ総量 を制限することを意味する、以前のブログにも記載されている.
1つ目の値はメモリ使用の下限です.2つ目の値は、メモリ圧力モードがバッファに圧力を適用し始める上限である.3番目の値はメモリ使用の上限です.この階層では、メッセージを破棄してメモリの使用を減らすことができます.大きなBDPでは、これらの値を大きくすることができます(ただし、単位はバイトではなくメモリページです).
上記のパラメータでは、状況に応じて大きくすることができます.
オンラインHbaseクラスタはアクセス数が急増したときに短時間で要求の一部が失敗したことを発見し、1台のマシン上でdmesgがエラーログを発見したのは以下の通りである.
これは、ファイアウォールが開いているため、ファイアウォールは接続ごとに追跡され、この数に制限があり、超えたらパケットが失われます.そのため、このパラメータを大きくする必要があります.以下のようにします.チューニングポイント4:
チューニングポイント5
この2つのパラメータがサービスに与える影響は重要ですが、nginxを逆エージェントとして使用すると、突然トラフィックが急増すると、このときnginxは大量の502を返す可能性があります.その1つの原因は、この2つのパラメータの構成が低すぎるためだと思います.この2つのパラメータは一般的に機械に設定されているのは比較的小さく、特に注意を喚起する必要がある.たとえば、デフォルト値は次のようになります.
この2つのパラメータはどういう意味ですか?netdev_max_backlogはTCP半接続キューサイズに対応し、対応図中のsync queue somaxconnはTCPの全接続キューサイズに対応し、対応図中のaccept queue TCPは3回手に入れ、第1ステップserverでclientのsynを受信すると、関連情報を半接続キュー(sync queue)に入れ、syn+ackをclientに返信する(第2ステップ)
(sync flood攻撃もこの弱点を利用して、直接あなたのsync queuを満たして、この時他のリクエストの接続も入ってこない.)
ステップ3でserverはclientのackを受信し、このとき全接続キューが満たされていない場合は、半接続キューから関連情報を取り出して全接続キューに入れます.そうしないとtcp_を押します.abort_on_overflow指示の実行.
ここでは、2つのパラメータについて説明します.チューニングポイント6:
tcp_abort_on_overflowが0であることは、3回目の握手で3ステップ目のときに全接続キューがいっぱいになった場合、serverはclientから送られてきたackを捨てます(server側では接続が確立されていないと考えられています)が、serverはしばらくしてsyn+ackをclientに再送信します(つまり握手を再開する2ステップ目)、clientのタイムアウト待ちが短いと異常になりやすいことを示しています.tcp_の場合abort_on_overflowの値が1の場合、rstという接続に直接なります.
また、TCP接続の場合、その半接続キューと全接続キューはnetdev_を直接使用するものではないmax_backlogとsomaxconnの値は、min(backlog,somaxconn)に依存し、backlogはコードを書くときにsocketを作成するときに入力される半接続キューのサイズはmax(64,/proc/sys/net/ipv 4/tcp_max_syn_backlog)に依存します.バージョンによってosが若干異なります
マシンに大量のFINが現れたらWAIT2, TIME_WAITなどの状態では、次のパラメータを調整する必要があります.調整の利点7:
TIME_WAIT状態は2つのMSL(Max Segment Lifetime)が続き、Windowsではデフォルトで4分、つまり240秒となる.一般的にTIME_WAIT状態でのsocketはリサイクルできないため,上記パラメータを最適化し,ポート占有を回避する必要がある.
CLOSEならWAIT状態は?このときは自分のコードに問題があるかどうかを見るべきで、この状態は受動的に閉じる側がFINメッセージを受け取った後、アクティブに閉じる側にFINを送信していない状態です.
注意:上記のすべての調整の利点は、自分の実行環境に基づいて適切な値を選択する必要があります.まず、テスト環境の検証を経てオンラインに置くことが望ましいです.
参照先:
https://blog.csdn.net/Just_shunjian/article/details/78288229 https://testerhome.com/topics/7509somaxconn、アリミドルウェアに関するブログ:http://jm.taobao.org/2017/05/25/525-1/https://blog.csdn.net/erlib/article/details/50236919 https://colobu.com/2014/09/18/linux-tcpip-tuning/golang tcpプログラミング:https://tonybai.com/2015/11/17/tcp-programming-in-golang/https://cnblogs.com/pangguoping/p/5830328.html
(以下、/etc/sysctl.confにおけるパラメータの変更はすべて永続的な変更であり、後述しない.方法:パラメータを/etc/sysctl.confに追加し、sysctl-pを実行してパラメータを有効にし、永続的に有効にする)
0 x 01ポート関連
ポート切れの問題については、前のブログでも話していましたが、ここはくどくありません.一般的にサービス側としては、1つのポートを傍受し、forループしてaccept接続を行い、処理すればよい.したがって、サービス側ポートが消費されることは一般的には存在しない.例えばgolangのコード:
//
func main() {
l, err := net.Listen("tcp", ":8888")
if err != nil {
fmt.Println("listen error:", err)
return
}
for {
c, err := l.Accept()
if err != nil {
fmt.Println("accept error:", err)
break
}
// start a new goroutine to handle
// the new connection.
go handleConn(c)
}
}
もちろん、サーバーには通常1つのサービスしかありません.他のサービスもあるかもしれません.あるいは、あなたのサービスが要求を受けた後、clientとして他のサービスを呼び出します.このとき、マシンのポート範囲に注目する必要があります.チューニングポイント1:デフォルトポート範囲
# sysctl -a|grep ip_local_port_range
net.ipv4.ip_local_port_range = 32768 60999
状況に応じて調整できます.たとえば、次のようにします.
net.ipv4.ip_local_port_range = 1024 65535
0 x 02リソース関連
accpet呼び出しに成功すると接続が確立され、javaではsocketが直接返され、golangではnetが返されるようにパッケージされています.Connですが、最終的な結果は同じです.このsocketを持って読み書きすることで、socketの本質はファイル記述子です.これは前のブログでも話しました.
//golang net.Conn Read Write :
// Read implements the Conn Read method.
func (c *conn) Read(b []byte) (int, error) {
if !c.ok() {
return 0, syscall.EINVAL
}
n, err := c.fd.Read(b)
if err != nil && err != io.EOF {
err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return n, err
}
// Write implements the Conn Write method.
func (c *conn) Write(b []byte) (int, error) {
if !c.ok() {
return 0, syscall.EINVAL
}
n, err := c.fd.Write(b)
if err != nil {
err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return n, err
}
上のくだらない話がこんなに多いのは、socketがファイルリソースとしてLinuxシステムの制限を受け、勝手に無限に使用することはできません.この制限は、ファイル記述子リソースに対するLinuxの制限に現れます.利点2:チューニング可能なパラメータは次のとおりです.
#ulimit -n
65535
開くファイル制限vim/etc/security/limitsを変更します.conf
root soft nofile 102400
root hard nofile 102400
ここでrootは、どのユーザのオープンファイル数制限を変更するかを指定します.使用可能な'*'番号は、すべてのユーザーの制限を変更することを示します.ソフトまたはhardは、ソフトリミットを変更するかハードリミットを変更するかを指定します.102400は、変更する新しい制限値、すなわち最大オープンファイル数を指定します(ソフト制限値がハード制限値以下であることに注意してください).
# sysctl -a|grep file-max
fs.file-max = 65535
この制限とは、システム全体でサポートする最大値がfile-max制限、/etc/sysctlを変更するすべてのユーザの合計を指す.confファイル
fs.file-max = 6815744
普通の良い機械ではこの値はまだ大きいです.
Linuxのファイルリソースに対する制限について述べたほか、TCPは情報を送受信する際にバッファがあり、バッファはメモリリソースであり、すべてのLinuxシステムもこのリソースを制限しなければならないことを知っています.
チューニングポイント4:
net.core.optmem_max = 513920
net.core.rmem_default = 256960
net.core.rmem_max = 513920
net.core.wmem_default = 256960
net.core.wmem_max = 513920
この2つのパラメータもあります
net.ipv4.tcp_rmem = 8760 256960 4088000
net.ipv4.tcp_wmem = 8760 256960 4088000
最初の値はsocket受信バッファに割り当てられた最小バイト数である.2番目の値はデフォルト値(rmem_defaultで上書きされます)で、バッファはシステム負荷が重くない場合にこの値に増加します.3番目の値は、受信バッファ空間の最大バイト数(rmem_maxで上書きされる)である.
net.ipv4.tcp_mem = 131072 262144 524288
1つ目の値はメモリ使用の下限です.2つ目の値は、メモリ圧力モードがバッファに圧力を適用し始める上限である.3番目の値はメモリ使用の上限です.この階層では、メッセージを破棄してメモリの使用を減らすことができます.大きなBDPでは、これらの値を大きくすることができます(ただし、単位はバイトではなくメモリページです).
上記のパラメータでは、状況に応じて大きくすることができます.
0 x 03ファイアウォール関連
オンラインHbaseクラスタはアクセス数が急増したときに短時間で要求の一部が失敗したことを発見し、1台のマシン上でdmesgがエラーログを発見したのは以下の通りである.
nf_conntrack: table full, dropping packet
これは、ファイアウォールが開いているため、ファイアウォールは接続ごとに追跡され、この数に制限があり、超えたらパケットが失われます.そのため、このパラメータを大きくする必要があります.以下のようにします.チューニングポイント4:
net.netfilter.nf_conntrack_max=1048576
net.nf_conntrack_max=1048576
0 x 04あいまいないくつかのパラメータを比較
チューニングポイント5
net.core.netdev_max_backlog = 400000
net.core.somaxconn = 100000
この2つのパラメータがサービスに与える影響は重要ですが、nginxを逆エージェントとして使用すると、突然トラフィックが急増すると、このときnginxは大量の502を返す可能性があります.その1つの原因は、この2つのパラメータの構成が低すぎるためだと思います.この2つのパラメータは一般的に機械に設定されているのは比較的小さく、特に注意を喚起する必要がある.たとえば、デフォルト値は次のようになります.
# sysctl -a|grep netdev_max
net.core.netdev_max_backlog = 1000
# sysctl -a|grep somaxconn
net.core.somaxconn = 128
この2つのパラメータはどういう意味ですか?netdev_max_backlogはTCP半接続キューサイズに対応し、対応図中のsync queue somaxconnはTCPの全接続キューサイズに対応し、対応図中のaccept queue TCPは3回手に入れ、第1ステップserverでclientのsynを受信すると、関連情報を半接続キュー(sync queue)に入れ、syn+ackをclientに返信する(第2ステップ)
(sync flood攻撃もこの弱点を利用して、直接あなたのsync queuを満たして、この時他のリクエストの接続も入ってこない.)
ステップ3でserverはclientのackを受信し、このとき全接続キューが満たされていない場合は、半接続キューから関連情報を取り出して全接続キューに入れます.そうしないとtcp_を押します.abort_on_overflow指示の実行.
ここでは、2つのパラメータについて説明します.チューニングポイント6:
net.ipv4.tcp_abort_on_overflow=0
net.ipv4.tcp_synack_retries = 2
tcp_abort_on_overflowが0であることは、3回目の握手で3ステップ目のときに全接続キューがいっぱいになった場合、serverはclientから送られてきたackを捨てます(server側では接続が確立されていないと考えられています)が、serverはしばらくしてsyn+ackをclientに再送信します(つまり握手を再開する2ステップ目)、clientのタイムアウト待ちが短いと異常になりやすいことを示しています.tcp_の場合abort_on_overflowの値が1の場合、rstという接続に直接なります.
また、TCP接続の場合、その半接続キューと全接続キューはnetdev_を直接使用するものではないmax_backlogとsomaxconnの値は、min(backlog,somaxconn)に依存し、backlogはコードを書くときにsocketを作成するときに入力される半接続キューのサイズはmax(64,/proc/sys/net/ipv 4/tcp_max_syn_backlog)に依存します.バージョンによってosが若干異なります
0 x 05接続回収
マシンに大量のFINが現れたらWAIT2, TIME_WAITなどの状態では、次のパラメータを調整する必要があります.調整の利点7:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
TIME_WAIT状態は2つのMSL(Max Segment Lifetime)が続き、Windowsではデフォルトで4分、つまり240秒となる.一般的にTIME_WAIT状態でのsocketはリサイクルできないため,上記パラメータを最適化し,ポート占有を回避する必要がある.
CLOSEならWAIT状態は?このときは自分のコードに問題があるかどうかを見るべきで、この状態は受動的に閉じる側がFINメッセージを受け取った後、アクティブに閉じる側にFINを送信していない状態です.
注意:上記のすべての調整の利点は、自分の実行環境に基づいて適切な値を選択する必要があります.まず、テスト環境の検証を経てオンラインに置くことが望ましいです.
参照先:
https://blog.csdn.net/Just_shunjian/article/details/78288229 https://testerhome.com/topics/7509somaxconn、アリミドルウェアに関するブログ:http://jm.taobao.org/2017/05/25/525-1/https://blog.csdn.net/erlib/article/details/50236919 https://colobu.com/2014/09/18/linux-tcpip-tuning/golang tcpプログラミング:https://tonybai.com/2015/11/17/tcp-programming-in-golang/https://cnblogs.com/pangguoping/p/5830328.html