UDPについての簡単な説明(パケット長、受信能力、パケットロス、プロセス構造の選択)

UDPについての簡単な説明(パケット長、受信能力、パケットロス、プロセス構造の選択)

UDPパケットの理論上の長さはいくらですか?適切なUDPパケットの長さはどのくらいでしょうか?

最終更新 2023/12/08 5:52
不朽的传奇
読了目安 5 分
カテゴリ
共有
タグ
技術アップデート

UDP データグラム長、UDP データグラムの理論的な長さ

UDP データグラムの理論的な長さはどれくらいか、適切な UDP データグラムのサイズはどのくらいか。TCP/IP 詳解 第1巻 第11章の UDP データグラムのヘッダーから、UDP の最大パケット長は 216-1 バイトであることがわかる。UDP ヘッダーが 8 バイトを占め、さらに IP 層でカプセル化された IP ヘッダーが 20 バイトを占めるため、UDP データグラムの最大理論長は 216-1-8-20 = 65507 となる。

img

しかし、これはあくまで UDP データグラムの最大理論長である。まず、TCP/IP は通常、リンク層、ネットワーク層、トランスポート層、アプリケーション層の 4 層プロトコルシステムと考えられている。UDP はトランスポート層に属し、伝送過程において UDP パケット全体は下位層プロトコルのデータフィールドとして伝送される。その長さは下位の IP 層やデータリンク層プロトコルの制約を受ける。

MTU 関連の概念

イーサネット(Ethernet)データフレームの長さは 46~1500 バイトの間でなければならない。これはイーサネットの物理的特性による。この 1500 バイトはリンク層の MTU(最大転送単位)と呼ばれる。インターネットプロトコルは IP フラグメンテーションを許可しており、これによりデータパケットを十分に小さな断片に分割して、そのデータパケットの元のサイズよりも小さい MTU を持つリンクを通過させることができる。このフラグメンテーションはネットワーク層で行われ、パケットをリンクに送信するネットワークインターフェースの MTU の値が使用される。この MTU の値が MTU(Maximum Transmission Unit)である。これは、通信プロトコルの特定の層を通過できる最大データパケットサイズ(バイト単位)を指す。この最大転送単位のパラメータは通常、通信インターフェース(ネットワークインターフェースカード、シリアルポートなど)に関連する。

インターネットプロトコルでは、あるインターネット伝送経路の「パスMTU」は、送信元アドレスから宛先アドレスまでの「経路」上のすべての IP ホップの MTU の最小値として定義される。

注意: loopback の MTU は上記の制限を受けない。loopback MTU 値を確認する:

img

[root@bogon ~]# cat /sys/class/net/lo/mtu

65536

IP フラグメンテーションが UDP データグラム長に与える影響

前述のとおり、ネットワークインターフェースカードの制約により、MTU の長さは 1500 バイトに制限されている。この長さはリンク層のデータ領域を指す。この値を超えるパケットはフラグメント化される可能性があり、そうでなければ送信できない。パケット交換ネットワークは信頼性が低く、パケットロスが発生する。IP プロトコルの送信側は再送を行わない。受信側はすべてのフラグメントを受信した後にのみ再構成して上位層プロトコルの処理コードに渡す。そうでなければ、アプリケーションから見るとこれらのパケットは破棄されたものと見なされる。

同じ瞬間におけるネットワークパケットロスの確率が均等であると仮定すると、大きな IP データグラムは必然的に破棄される確率が高くなる。なぜなら、1 つのフラグメントが失われるだけで IP データグラム全体が受信できなくなるからである。MTU を超えないパケットにはフラグメンテーションの問題は発生しない。

MTU の値にはリンク層のヘッダーとトレーラの 18 バイトは含まれない。したがって、この 1500 バイトがネットワーク層 IP データグラムの長さ制限となる。IP データグラムのヘッダーは 20 バイトであるため、IP データグラムのデータ領域の最大長は 1480 バイトとなる。この 1480 バイトは、TCP から送られてくる TCP セグメントや UDP から送られてくる UDP データグラムを格納するために使用される。さらに、UDP データグラムのヘッダーは 8 バイトであるため、UDP データグラムのデータ領域の最大長は 1472 バイトとなる。この 1472 バイトが使用可能なバイト数である。

img

送信する UDP データが 1472 より大きい場合はどうなるか?つまり、IP データグラムが 1500 バイトより大きく、MTU より大きい場合である。この場合、送信側の IP 層はフラグメンテーション(分割)を行う必要がある。データグラムを複数の断片に分割し、各断片が MTU より小さくなるようにする。受信側の IP 層はデータグラムの再構成を行う必要がある。さらに深刻なのは、UDP の特性により、ある断片データが転送中に失われた場合、受信側はデータグラムを再構成できず、UDP データグラム全体が破棄されることになる。したがって、一般的な LAN 環境では、UDP データを 1472 バイト以下に制御することが望ましい。

インターネットプログラミングの場合は状況が異なる。なぜなら、インターネット上のルーターは MTU を異なる値に設定する可能性があるからである。MTU が 1500 であると仮定してデータを送信した場合、経由するあるネットワークの MTU が 1500 バイト未満であれば、システムは一連のメカニズムを使用して MTU 値を調整し、データグラムが目的地に正常に到達できるようにする。インターネット上の標準 MTU 値は 576 バイトであるため、インターネットでの UDP プログラミングを行う際は、UDP データ長を 548 バイト(576-8-20)以内に制御するのが望ましい。

UDP パケットロス

UDP パケットロスとは、ネットワークカードがデータパケットを受信した後、Linux カーネルの TCP/IP プロトコルスタックが UDP データパケットを処理する過程で発生するロスを指す。主な原因は 2 つある:

  1. UDP データパケットの形式エラーまたはチェックサムチェックの失敗。
  2. アプリケーションが UDP データパケットを処理する時間がない。

原因 1 については、UDP データパケット自体のエラーは稀であり、アプリケーション側で制御できないため、本ドキュメントでは説明しない。

まず、一般的な UDP パケットロス検出方法を紹介する。netstat コマンドに -su パラメータを付けて使用する。

# netstat -su
Udp:
 2495354 packets received
 2100876 packets to unknown port received.
 3596307 packet receive errors
 14412863 packets sent
 RcvbufErrors: 3596307
 SndbufErrors: 0

上記の出力から、"packet receive errors" を含む行があることがわかる。定期的に netstat -su を実行し、行頭の数字が増加している場合、UDP パケットロスが発生していることを示す。

以下に、アプリケーションが処理できずに UDP パケットロスが発生する一般的な原因を紹介する:

1. Linux カーネルのソケットバッファサイズが小さすぎる場合 # cat /proc/sys/net/core/rmem_default
# cat /proc/sys/net/core/rmem_max

ソケットバッファのデフォルト値と最大値を確認できる。

rmem_default と rmem_max はどれくらいのサイズに設定すべきか?サーバーの性能負荷が小さく、処理遅延に厳しい要件がない場合は、1M 程度に設定すればよい。サーバーの性能負荷が大きい場合や処理遅延に厳しい要件がある場合は、rmem_default と rmem_max を慎重に設定する必要がある。小さすぎるとパケットロスが発生し、大きすぎるとスノーボール現象が発生する可能性がある。

  1. サーバーの負荷が高すぎ、大量の CPU リソースを消費し、Linux カーネルソケットバッファ内の UDP データパケットをタイムリーに処理できず、パケットロスが発生する。

一般に、サーバー負荷が高くなる理由は 2 つある:受信する UDP パケットが多すぎること、サーバープロセスに性能ボトルネックが存在すること。受信する UDP パケットが多すぎる場合は、スケールアップを検討する必要がある。サーバープロセスの性能ボトルネックは性能最適化の範疇であり、ここでは詳しく議論しない。

  1. ディスク I/O がビジー状態

サーバーで大量の I/O 操作が行われると、プロセスがブロックされ、CPU がディスク I/O を待機し、カーネルソケットバッファ内の UDP データパケットをタイムリーに処理できなくなる。ビジネス自体が I/O 集約型である場合、アーキテクチャを最適化し、キャッシュを適切に使用してディスク I/O を削減することを検討する必要がある。

ここで見落とされがちな問題がある:多くのサーバーではローカルディスクにログを記録する機能があり、運用の誤操作によりログの記録レベルが高すぎたり、特定のエラーが突然大量に発生したりすると、ディスクにログを書き込む I/O 要求が多くなり、ディスク I/O がビジー状態になり、UDP パケットロスが発生する。

運用の誤操作については、運用環境の管理を強化し、エラーを防止できる。ビジネスで大量のログを記録する必要がある場合は、メモリログやリモートログを使用できる。

  1. 物理メモリが不足し、スワップが発生する

スワップは本質的にディスク I/O のビジー状態の一種であるが、特殊であり見落とされやすいため、別途列挙する。

物理メモリの使用を適切に計画し、システムパラメータを適切に設定することで、この問題を回避できる。

  1. ディスクが満杯で I/O ができない

ディスクの使用計画が不十分で、監視が不十分なため、ディスクが書き込みで満杯になり、サーバープロセスが I/O できず、ブロック状態になる。最も根本的な対策は、ディスクの使用を計画し、業務データやログファイルでディスクがいっぱいになるのを防ぎ、同時に監視を強化することである。例えば、ディスク使用率が 80% に達したら継続的にアラートを出す汎用ツールを開発し、十分な対応時間を確保する。

UDP 受信能力テスト

テスト環境

プロセッサ:Intel(R) Xeon(R) CPU X3440 @ 2.53GHz、4 コア、8 ハイパースレッド、ギガビットイーサネットカード、8G メモリ

モデル 1

単一マシン、シングルスレッド非同期 UDP サービス、ビジネスロジックなし、受信操作のみ、UDP ヘッダー以外は 1 バイトデータ。

テスト結果

img

img

img

現象:

  1. 単一マシンの UDP パケット受信処理能力は毎秒約 150 万に達する。
  2. 処理能力はプロセス数の増加に伴って向上する。
  3. 処理がピークに達したとき、CPU リソースは完全には使い切られていない。

結論:

  1. UDP の処理能力は非常に大きい。
  2. 現象 2 と現象 3 から、性能のボトルネックは CPU ではなくネットワークカードにある。CPU を増やすと処理能力が向上するのは、パケットロス(UDP_ERROR)の数が減少するためである。

モデル 2

その他のテスト条件はモデル 1 と同じ。UDP ヘッダー以外は 100 バイトデータ。

テスト結果

img

img

img

現象:

  1. 100 バイトのパケットサイズは、通常のビジネスシナリオに比較的適している。
  2. UDP の処理能力は非常に大きく、単一マシンのピークは毎秒 75 万に達する。
  3. 4、8 プロセス時には、CPU 使用率は記録されていない(ネットワークカードの帯域が完全に消費された)。ただし、CPU が完全に消費されたわけではないことは確かである。
  4. プロセス数の増加に伴い、処理能力は明確に向上しないが、パケットロス(UDP_ERROR)の数は大幅に減少する。

モデル 3

単一マシン、単一プロセス、マルチスレッド非同期 UDP サービス、マルチスレッドで 1 つの fd を共有、ビジネスロジックなし、UDP ヘッダー以外は 1 バイトデータ。

テスト結果:

img

現象:

  1. スレッド数の増加に伴い、処理能力は向上せず、むしろ低下する。

結論:

  1. マルチスレッドで 1 つの fd を共有すると、かなりのロック競合が発生する。
  2. マルチスレッドで 1 つの fd を共有すると、パケットが到着したときにすべてのスレッドがアクティブになり、頻繁なコンテキストスイッチが発生する。

最終結論:

  1. UDP の処理能力は非常に大きく、日常のビジネスシナリオでは UDP が性能のボトルネックになることは通常ない。
  2. プロセス数が増加しても処理能力は明確に向上しないが、パケットロスの数は明確に減少する。
  3. 今回のテストでは、ボトルネックは CPU ではなくネットワークカードにあった。
  4. 複数プロセスで異なるポートを監視するモデルを採用し、複数プロセスや複数スレッドで同じポートを監視しないこと。

まとめ

img

さらに探索

関連読書

その他の記事
最近の更新 2026/05/25

CodeWF.Markdown:PDFテキストはコピー可能、画像は埋め込み可能。WeChat公式アカウント/知乎/掘金にコピーしてもHTMLソースが表示されない

CodeWF.Markdown と Vex における Markdown のエクスポートと公開コピーの技術実装を共有:MarkdownDocumentExporter、ExportKind、共有画像読み込み、SVG/GIF/WebP のラスタライズ、Word 埋め込みメディアリソース、テキスト選択可能なPDF、Windows CF_HTML リッチHTMLクリップボード、拡張可能なレイアウトテーマ。

続きを読む
最近の更新 2026/05/25

Vex 1.1.0:無料でオープンソースの .NET + Avalonia クロスプラットフォーム Markdown エディター

Vex 1.1.0 の紹介。無料でオープンソースの .NET + Avalonia クロスプラットフォーム Markdown エディターです。動的編集、リアルタイムプレビュー、アウトラインジャンプ、ソースモード、プレビューの更新、検索と置換、テーマとタイポグラフィ、選択可能なテキストの PDF/PNG/Word エクスポート、WeChat 公式アカウントへのコピー、新しいユーザーガイドを特集しています。

続きを読む
最近の更新 2026/05/25

CodeWF.Markdown:Avalonia 12 ベースの Markdown レンダリングコントロール

この記事では、CodeWF.Markdown のリポジトリアドレス、NuGet インストール方法、フルパッケージライン、Lite パッケージライン、リアルタイム編集プレビュー、タイポグラフィテーマ、コードハイライト、画像プレビュー、数式、複数ビューアのカバレッジ、インクリメンタルレンダリング機能について紹介します。

続きを読む