Анализ сетевых ботлнеков (заметки)

Dmitry Zuikov
3 min readSep 17, 2016

--

Это промежуточная заметка, возможно потом напишу что-то более связное.

Для начала попробовал реализовать методику обнаружения сетевых ботлнеков по методике, описанной в документе

“ANALYZING PACKET INTERARRIVAL TIMES DISTRIBUTION TO DETECT NETWORK BOTTLENECKS” (DOI: 10.1007/0–387–31170-X_2)

Если коротко, методика состоит в том, что вычисляется статистика по межпакетным интервалам для каждого потока (flow, далее — поток), и потом для этой статистики считаются моменты: skewness и kurtosis. По большому положительному значению kurtosis делается вывод, что ботлнек присутствует. Методика неинвазивная, т.е только анализируется проходящий трафик, никакой дополнительный трафик не генерируется.

Из документа было не вполне ясно, вычисляются ли эти значения для одного потока, или для всех потоков разом, но это возможно я не слишком внимательно прочитал документ.

На текущий момент:

Написал зонд, который собирает статистику в кольцевом буфере для каждого потока, захватывая пакеты при помощи PACKET_MMAP. Используются наносекудные таймстемпы, которые этот механизм возвращает. Статистика периодически пишется в файл, который впоследствии обрабатывается. Зонд собирает не менее 100 и не более 500 пакетов от каждого потока, таймаут для потоков принимается за 2 минуты, но это неважно, в основном, что бы удалять старые потоки и не потреблять всю память.

Захватил несколько минут разного трафика, как локального так и внешнего facebook, youtube), никакой дополнительной фильтрации не делал.

Для рассчетов использовал пакет hstats , для построения гистограмм примерно такое:

На текущий момент:

Попробовал PACKET_MMAP: все работает, можно брать.

Попробовал libdill — развитие libmill (легкие потоки для C), потому что мне надоел бойлерплейт вокруг poll и таймеров, тут же всё это скрыто и каждый “параллельный” (конкурентный на самом деле) кусок кода выглядит как простая функция с бесконечным циклом внутри.

В целом, впечатления нормальные, но нет явного вызова шедулера, нужно использовать их обертки вокруг функций (receive, send и т.д.), это не всегда удобно, но можно вставить msleep(now()) в безопасное место основного цикла. Это приводит к вызову шедулера.

Если кто-то не в курсе, основное отличие этих корутин (они же “горутины”) от нормальных потоков в том, что корутины используют явную отдачу управления в шедулер (внутренний шедулер библиотеки). В Си есть несколько способов это делать, тут это делается при помощи setjmp/longjmp в общем случае, для x86 написан какой-то код на ассемблере, видимо более легковесное тоже самое. Но в любом случае, setjmp/longjmp не дороже, чем обычные потоки. Из плохих новостей то, что весь код приходится писать с отдачей управления, в случае других языков это можно делать автоматически в компиляторе, в Си — явно расставлять yield-ы.

Собственно, о результатах измерений:

Для собранного трафика методика показывает высокие положительные значение kurtosis в любом случае — и если считать отдельно по потокам, и если считать для всех потоков разом, и если примеять медианную фильтрацию и если не применять. Автор методики советует отбрасывать первый и последний квинтили, но думаю, что это бесполезно.

Мысли пока такие:

  • Действительно, есть боттлнек (что им считать?). Он, конечно же, есть у провайдера, на 80 мегабит, но любой, даже самый быстрый поток из измеренных, не более единиц мегабит (youtube)
  • Ошибка измерений, неточно генерируются таймстемпы. Надо проверять, но автор вообще использует таймстемпы, которые генерирует libpcap.
  • Попробовать конфигурацию заведомо без ботлнека, т.е генератор трафика и приемник в рамках одного сегмента.

Продолжение следует…

UPD:

Выяснилось, что я ошибся в формате вывода статистики, и поэтому потоки не разделялись по направлениям. Исправление этой ошибки привело к тому, что для потоков со скоростями много меньше предельной пропускной способности канала kurtosis от PDF отрицательный (например, youtube), а для потоков, работающих на пределе этой пропускной способности — довольно большой положительный (например, speedtest). Т.е методика как бы… работает?!

UPD2:

Довольно сносно работает при следующих параметрах:

Количество пакетов в окне: 512–1024
Периодичность дампа: 1 секунда
Рассчёт kurtosis: по каждому потоку отдельно, от результатов взять среднее или медиану, и то, и другое неплохо себя показывает.

--

--