一覧NW-18-2 · 通信品質と切り分け

QoSによる帯域と優先度の制御

同じ5パケットを使い、容量、取出し順、帯域、投入間隔を変更します。待ち時間と損失を比較し、どの変更で誰の待ち時間が変わったか確かめます。

説明

出口の送信速度より速くパケットが集まると、キューで順番を待ちます。容量を超えると破棄され、優先度を変えると誰が先に送られるかが変わります。

同じ5パケットを使い、容量、取出し順、帯域、投入間隔を変更します。待ち時間と損失を比較し、どの変更で誰の待ち時間が変わったか確かめます。

1到着順と送信量

1 Mbit/sの出口へ、短時間にA・B・V・C・Wが到着します。A/B/Cは1500バイト、音声扱いのV/Wは200バイトです。時刻の単位はmsで、priority0を高優先度とします。

python3 -c到着列を表示 'from queue_model import PACKETS; print(PACKETS)'名前・到着ms・バイト数・優先度

先頭のAを送信し終えるまで12msかかります。その間に残り4個が到着します。このモデルは指定バイト数だけを帯域へ計上し、Ethernetなどの追加長や伝搬時間は含めません。

2先着順で送る

待機用の枠を4個にしてFIFOで送ります。送信中の1個は枠に含めません。出力のwaitは到着から送信開始までの時間です。

python3 queue_model.py出口の送信を計算 --policy fifo到着順 --capacity 4待機枠4個

全5個が送れますが、Vは22ms、Wは33.6ms待ちます。小さいパケットでも、先に並んだ大きなパケットの送信が終わるまで順番が来ません。最後の送信完了は39.2msです。

3待機枠を小さくする

同じ到着列のまま、待機枠だけを2個に減らします。満杯の間に到着したパケットを捨てます。

python3 queue_model.py --policy fifo同じFIFO --capacity 2枠だけを2個へ変更

CとWが捨てられ、5個中2個で損失率40%になります。送れたVの待ち時間22msは変わりません。枠を小さくすれば、すべてのパケットの遅延が小さくなるわけではありません。

4音声を先に取り出す

枠を4個へ戻し、待機中はV/Wを先に取り出す方式に変えます。すでに送信中のパケットは中断しません。

python3 queue_model.py同じ到着列で計算 --policy priority待機中の高優先度を先に送信 --capacity 4全パケットを保持

Aの送信後、V→W→B→Cの順になります。Vの待ちは10ms、Wは9.6msへ短くなり、その分B/Cが後になります。総送信量と帯域は同じなので、最後の完了39.2msは変わりません。

5優先度と受入れ可否は別

優先制御でも枠が2個なら、満杯になった後のWは受け入れられません。このモデルは既存の低優先パケットを追い出す処理を持ちません。

python3 queue_model.py --policy priority優先度による取出し --capacity 2待機枠を制限

Vは先に取り出せますが、CとWの損失は残ります。取出し順、キューの容量、満杯時の破棄方針をそれぞれ設定する必要があります。また、高優先の到着が続けば低優先が長時間待つ可能性があります。

6出口の帯域を増やす

取出し順をFIFOに戻し、出口を2 Mbit/sへ変更します。枠は4個です。

python3 queue_model.py --policy fifo --capacity 4FIFO・枠4個 --rate 2出口2 Mbit/s

総送信時間は19.6msになり、Vの待ちは10ms、Wは14.8msになります。優先度を変えた場合と違い、各パケットの送信に必要な時間そのものが短くなっています。

7送出時刻を整えた場合

出口を1 Mbit/sへ戻し、その速度に合わせてパケットを順に投入します。整える前の到着時刻と、出口キューで観測する到着時刻は異なります。

python3 queue_model.py --policy fifo --capacity 2同じ出口条件 --shaped投入時刻を送信速度に合わせる

出口キューのwaitはすべて0ですが、Vは元の到着2msから投入24msまで22ms、手前で待っています。シェーピングは到着の偏りを抑える一方、待ち時間が消えるとは限りません。遅延を測る区間をそろえて比較します。

まとめ

容量、取出し順、帯域は別の条件で、遅延と損失への影響も異なります。

キューの待ち時間だけでなく、手前のシェーパーを含む測定区間も確認します。

操作履歴と解説を振り返れます。

シェル / 通信の調査

1
python3 -c 'from queue_model import PACKETS; print(PACKETS)'
[('A', 0, 1500, 1), ('B', 1, 1500, 1), ('V', 2, 200, 0), ('C', 3, 1500, 1), ('W', 4, 200, 0)]
2
python3 queue_model.py --policy fifo --capacity 4
{
  "sent": [
    {
      "id": "A",
      "arrival": 0,
      "start": 0,
      "finish": 12.0,
      "wait": 0
    },
    {
      "id": "B",
      "arrival": 1,
      "start": 12.0,
      "finish": 24.0,
      "wait": 11.0
    },
    {
      "id": "V",
      "arrival": 2,
      "start": 24.0,
      "finish": 25.6,
      "wait": 22.0
    },
    {
      "id": "C",
      "arrival": 3,
      "start": 25.6,
      "finish": 37.6,
      "wait": 22.6
    },
    {
      "id": "W",
      "arrival": 4,
      "start": 37.6,
      "finish": 39.2,
      "wait": 33.6
    }
  ],
  "dropped": [],
  "loss_percent": 0.0
}
3
python3 queue_model.py --policy fifo --capacity 2
{
  "sent": [
    {
      "id": "A",
      "arrival": 0,
      "start": 0,
      "finish": 12.0,
      "wait": 0
    },
    {
      "id": "B",
      "arrival": 1,
      "start": 12.0,
      "finish": 24.0,
      "wait": 11.0
    },
    {
      "id": "V",
      "arrival": 2,
      "start": 24.0,
      "finish": 25.6,
      "wait": 22.0
    }
  ],
  "dropped": [
    "C",
    "W"
  ],
  "loss_percent": 40.0
}
4
python3 queue_model.py --policy priority --capacity 4
{
  "sent": [
    {
      "id": "A",
      "arrival": 0,
      "start": 0,
      "finish": 12.0,
      "wait": 0
    },
    {
      "id": "V",
      "arrival": 2,
      "start": 12.0,
      "finish": 13.6,
      "wait": 10.0
    },
    {
      "id": "W",
      "arrival": 4,
      "start": 13.6,
      "finish": 15.2,
      "wait": 9.6
    },
    {
      "id": "B",
      "arrival": 1,
      "start": 15.2,
      "finish": 27.2,
      "wait": 14.2
    },
    {
      "id": "C",
      "arrival": 3,
      "start": 27.2,
      "finish": 39.2,
      "wait": 24.2
    }
  ],
  "dropped": [],
  "loss_percent": 0.0
}
5
python3 queue_model.py --policy priority --capacity 2
{
  "sent": [
    {
      "id": "A",
      "arrival": 0,
      "start": 0,
      "finish": 12.0,
      "wait": 0
    },
    {
      "id": "V",
      "arrival": 2,
      "start": 12.0,
      "finish": 13.6,
      "wait": 10.0
    },
    {
      "id": "B",
      "arrival": 1,
      "start": 13.6,
      "finish": 25.6,
      "wait": 12.6
    }
  ],
  "dropped": [
    "C",
    "W"
  ],
  "loss_percent": 40.0
}
6
python3 queue_model.py --policy fifo --capacity 4 --rate 2
{
  "sent": [
    {
      "id": "A",
      "arrival": 0,
      "start": 0,
      "finish": 6.0,
      "wait": 0
    },
    {
      "id": "B",
      "arrival": 1,
      "start": 6.0,
      "finish": 12.0,
      "wait": 5.0
    },
    {
      "id": "V",
      "arrival": 2,
      "start": 12.0,
      "finish": 12.8,
      "wait": 10.0
    },
    {
      "id": "C",
      "arrival": 3,
      "start": 12.8,
      "finish": 18.8,
      "wait": 9.8
    },
    {
      "id": "W",
      "arrival": 4,
      "start": 18.8,
      "finish": 19.6,
      "wait": 14.8
    }
  ],
  "dropped": [],
  "loss_percent": 0.0
}
7
python3 queue_model.py --policy fifo --capacity 2 --shaped
{
  "sent": [
    {
      "id": "A",
      "arrival": 0,
      "start": 0,
      "finish": 12.0,
      "wait": 0
    },
    {
      "id": "B",
      "arrival": 12,
      "start": 12,
      "finish": 24.0,
      "wait": 0
    },
    {
      "id": "V",
      "arrival": 24,
      "start": 24,
      "finish": 25.6,
      "wait": 0
    },
    {
      "id": "C",
      "arrival": 25.6,
      "start": 25.6,
      "finish": 37.6,
      "wait": 0.0
    },
    {
      "id": "W",
      "arrival": 37.6,
      "start": 37.6,
      "finish": 39.2,
      "wait": 0.0
    }
  ],
  "dropped": [],
  "loss_percent": 0.0
}

演習完了