Увеличение размера буфера VMBus для повышения производительности сети в ВМ

В компонентах интеграции Hyper-V шина VMBus играет роль широкой магистрали, по которой как потоки автотранспорта снуют потоки пакетов от виртуальных машин к физическим устройствам. Как и в реальной жизни эта магистраль может быть довольно таки сильно занята, и возникают пробки. Если в обычной жизни стоянка в пробке – это удел автомобилистов, то в виртуализации сам сетевой пакет не может судить, сколько времени ему ожидать очереди на отправку. Для этого каждая виртуальная машина имеет буфер. Размер буфера по умолчанию – 1 Мб. Буфер вмещает в себя 655 пакетов (по 1600 байт каждый). В некоторых случаях, о которых мы сейчас поговорим, этого буфера бывает недостаточно. Виртуальная машина может начать терять пакеты, что сразу же сказывается на скорости работы сети. Забегая вперёд, скажу, что рекомендую увеличить размер буфера до 2 МБ, а в некоторых случаях и до 4 МБ (максимально поддерживаемый размер). Когда, как и для чего, – об этом мы сейчас и поговорим.

Гипервизор, обрабатывая запросы от виртуальных машин, делит всё своё время на интервалы – кванты, через которые он обращается к той или иной машине для обмена данными по шине VMBus. В зависимости от количества прерываний, генерируемых виртуальной машиной, и нагрузки на гипервизор, размер кванта (в теории) может достигать 10 миллисекунд. Это означает, что гипервизор раз в 10 мс будет обращаться к виртуальной машине, чтобы обслужить её очередь пакетов на VMBus. В реалии такой размер кванта возникает не часто, но мы исследуем худший сценарий. Что такое 10 миллисекунд для сервера? Физические серверы могут обслуживать до 260000 пакетов в секунду на 10Гбит интерфейсе. Для виртуальной машины при размере кванта в 10 мс за одну секунду происходит сто сеансов обслуживания. Это значит, что виртуальная машина может передать лишь 65500 пакетов с интерфейса (800 Мбит). Если виртуальная машина будет пытаться передать больше (и если по какой-то причине невысоко количество генерируемых прерываний, отвечающее за уменьшение размера кванта), то пакеты начнут теряться. Это вынудит машину пересылать их повторно, что скажется на скорости работы сети. Это не является ограничением драйверов или компонентов интеграции. Просто в данном редком случае значение размера буфера является недостаточным. Если мы увеличим его с 655 до 2600, то это будет соответствовать максимальным возможностям физического сервера и решит потенциальную проблему.

Увеличение размера буфера следует делать для каждой виртуальной машины. Под это будет выделяться реальная память сервера. Если вас не смущает выделение дополнительных пары мегабайт на каждую виртуальную машину из памяти сервера (увеличение буферов до 2МБ в 512 машинах потребует примерно 1ГБ памяти сервера), то смело вносите изменения во все машины, чтобы более не думать о буфере. Как же это сделать?

Размер буфера задаётся внутри виртуальной машины для каждого сетевого интерфейса. В ОС Windows каждый сетевой интерфейс имеет свой уникальный GUID. Увидеть GUID текущей сетевой карты можно в диспетчере устройств в свойствах драйвера сетевой карты:

В редакторе реестра на виртуальной машине следует найти ветвь HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{GUID}\{index} , соответствующую данному интерфейсу:

Внутри значения индекса следует создать два ключа типа DWORD: ReceiveBufferSize и SendBufferSize. Значения этих ключей считаются в килобайтах в шестнадцатеричном виде. 0x400 соответствует размеру буфера по умолчанию в 1МБ. Изменив значение на 0x800, вы зададите размер буфера в 2 МБ. Задав значение 0x1000, получите размер буфера 4МБ. На примере ниже задаются размеры обоих буферов по 2МБ:

 

Если вы хотите добиться изменения размера буфера в виртуальных машинах Linux, то перед компиляцией ядра с компонентами интеграции 2.1 вимательно посмотрите файл NETVSC.H, где явно задаются значения для NETVSC_SEND_BUFFER_SIZE и NETVSC_RECEIVE_BUFFER_SIZE. Помните, что внесение изменений в эти файлы вы делаете на свою ответственность. После внесения изменений требуется перекомпиляция ядра (или по крайней мере модулей Hyper-V). Если есть интерес к установке и настройке компонент интеграции под Linux, я могу написать статью на примере какого-нибудь неподдерживаемого дистрибутива, например, Debian. Очевидно, что с RedHat и SUSE всё проще – там компоненты интеграции сразу поставляются в комплекте.

Не ожидайте от этих изменений существенного увеличения производительности. В 99% случаев размер кванта существенно меньше 10 мс. Да и очередь пакетов на отправку не превышает 1МБ. Однако, для душевного спокойствия администраторов, для достижения стабильности и повышения доступности я бы рекомендовал увеличить размер буфера до 2 или даже до 4 мегабайт на всех промышленно используемых виртуальных машинах. Сами понимаете, что пара мегабайт памяти на одну машину не стоят ваших мыслей о том, как там работает буфер!