カーネルソケット構造とTCP_DIAG


18

(TCPを使用して)リアルタイムデータサーバーに接続するソフトウェアに取り組んでいますが、いくつかの接続が切断されています。私の推測では、クライアントはサーバーからのデータを十分な速度で読み取っていません。したがって、TCPソケットを監視したいと思います。このために、私は「ss」ツールを見つけました。

このツールを使用すると、すべてのソケットの状態を確認できます。コマンドの出力の例を次に示します ss -inm 'src *:50000'

ESTAB      0      0             184.7.60.2:50000       184.92.35.104:1105
  mem:(r0,w0,f0,t0) sack rto:204 rtt:1.875/0.75 ato:40

私の質問は次のとおりです。記憶部とはどういう意味ですか?私は、データがカーネル構造(から来ていることがわかったツールのソースコードを見てみるとsocksock.h)。より正確には、フィールドから来ます:

r = sk->sk_rmem_alloc
w = sk->sk_wmem_queued;
f = sk->sk_forward_alloc;
t = sk->sk_wmem_alloc;

誰かがその意味を知っていますか?私の推測は次のとおりです。

  • rmem_alloc :インバウンドバッファのサイズ
  • wmem_alloc :アウトバウンドバッファのサイズ
  • sk_forward_alloc :???
  • sk->sk_wmem_queued :???

バッファサイズは次のとおりです。

net.ipv4.tcp_rmem = 4096        87380   174760
net.ipv4.tcp_wmem = 4096        16384   131072
net.ipv4.tcp_mem = 786432       1048576 1572864
net.core.rmem_default = 110592
net.core.wmem_default = 110592
net.core.rmem_max = 1048576
net.core.wmem_max = 131071

バッファサイズの構成は何ですか?ソケット接続で受信バッファが飽和し​​ているのを見ますか?パーティーはEWOULDBLOCKで接続をドロップしますか?
カールソン

私のソケットのサイズは非常に小さいと思うので、投稿を更新しました。EWOULDBLOCKについてはわかりません。クライアントはJAVAにあり、サーバーによって切断されたとだけ言います。サーバーはC ++であり、情報なしで接続を切断したとだけ言っています。サーバーのソースコードがないため、その動作を変更できません。クライアントは、数秒しか続かない場合でも、少し過負荷になると切断されるようです。
ツイスター

サーバーでバッファサイズの構成を調整できますか?クライアントでバッファサイズを監視できますか?クライアントのソースにアクセスできますか?netstat -apncを実行してバッファーサイズを監視しましたか?カーネル内のバッファサイズを増やして、何が起こるかを確認しようとしましたか?
カールソン

はい、それらはすでにサーバーの最大値に設定されています(net.ipv4.tcp_ *プロパティより大きくすることはできないと思いますよね?)netstat -apncの場合、バッファーサイズは表示されません。それが私がssを見た理由です。カーネルの場合、私はサーバーのルートではなく、ここのITチームはかなり頑固です。値を変更するように依頼する前に、何が起こるかを確認する必要があります...そして、はい、クライアントソースにアクセスできます。
ツイスター

netstat -apncは、Linuxの送信および受信キューの合計サイズを示します。サーバーは、最大利用可能にバッファを設定し、あなたはまだあなたが高いOSレベルで設定をバッファリングする必要があるかもしれない飽和している場合
Karlson

回答:


7

sk_forward_alloc 前方割り当てメモリは、ソケットのクォータで現在利用可能なメモリの合計です。

sk_wmem_queued 送信キューでキューに入れられ、まだ送信されていないか、まだ確認されていないソケット送信バッファーによって使用されるメモリの量です。

TCPメモリ管理の詳細については、「TCP / IPアーキテクチャ、Linuxでの設計と実装」の第9章をご覧ください。SameerSeth、M。Ajaykumar Venkatesulu著


この定義sk_wmem_queuedがからどのように異なっているのかわかりませんが、これについてsk_wmem_alloc少し拡張していただけますか?(答えがわかっている場合は、unix.stackexchange.com / questions / 551444 / …の質問に自由に答えを追加してください
little-dude

1

ssのマニュアルページを参照してください。

<fwd_alloc>
   The  memory allocated by the socket as cache, but not used for receiving/sending packet yet. If need memory to send/receive packet, the memory in this cache will be used before allocate additional memory.

<wmem_queued>
   The memory allocated for sending packet (which has not been sent to layer 3)

0

私は同じ質問をし、私はここに答えをコピーしますので:sk_wmem_queuedsk_wmem_alloc

Linuxネットワークスタックに貢献しているEric Dumazetにメールを送りました。その答えは次のとおりです。

sk_wmem_allocトランスポートスタックの後にキューイングされたskbのバイト数を追跡​​します:qdiscレイヤーおよびNIC TXリングバッファー。

TCP書き込みキューに1 MBのデータがあり、まだ送信されていない場合(cwnd制限)、sk_wmem_queue約1MBですが、sk_wmem_alloc約0になります

これら3つのタイプのキュー(ソケットバッファー、qdiscキュー、およびデバイスキュー)を理解するための非常に優れたドキュメントは、この記事(かなり長い)です。簡単に言うと、ソケットはパケットを直接qdiscキューにプッシュし、デバイスキューに転送することから始まります。qdiscキューがいっぱいになると、ソケットは独自の書き込みキューでデータのバッファリングを開始します。

ネットワークスタックは、パケットをキューイング規則に直接配置するか、キューがいっぱいの場合は上位層(ソケットバッファーなど)にプッシュバックします。

つまり、基本的にsk_wmem_queuesは、ソケットバッファ(sock.sk_write_queuesk_wmem_allocが使用するメモリですが、qdiscおよびデバイスキューのパケットが使用するメモリです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.