В первой части исследования мы оценивали эффективность включения GPU-ускорения для RemoteFX в однопользовательском режиме. Это второй этап, в котором займёмся проверкой и оценкой производительности для нескольких одновременных терминальных сеансов, чтобы понять границы масштабируемости облачного сервера с выделенной видеокартой.   Введение Конфигурация тестовой среды Методика тестирования Обработка данных Анализ результатов и наиболее интересные графики Задержки обработки пользовательского ввода и нагрузка на процессор Частота кадров Использование оперативной памяти Нагрузка на видеокарту Общие сетевые метрики Заключение Приложения Set-DataCollectors.ps1 Set-DataCollectors.cmd Start-SyncedTest.ps1 Start-SyncedTest.cmd helper.psm1 blg2csv.ps1 blg2csv.cmd figures_alt.ipynb figures.ipynb Диагностические счётчики UDP трафик TCP трафик Утилизация ресурсов vCPU в режиме одного пользователя для первых двух тестов составляла в среднем 40-50%. Поэтому, предварительные замеры для двух и трёх сессий были выполнены без изменения конфигурации виртуального сервера. Однако оказалось, что узким местом масштабирования, в первую очередь, являются именно ресурсы vCPU и vRAM: общая нагрузка стала так высока, что монитору производительности перестало хватать ресурсов для фиксации показаний счётчиков и в замерах стали появляться значительные пробелы.   Поэтому конфигурация виртуальной машины была изменена: были добавлены ядра и оперативная память.   2 -> 6 vCPU Intel(R) Xeon(R) CPU E5-2696 v4 @ 2.20GHz 8 -> 12 GB RAM GPU NVIDIA GRID M60-1Q, Dedicated Memory 929 MB, Shared Memory 4095 -> 6143 MB гостевая ОС Windows Server 2019 Standart x64 1809 (Version 10.0.17763.1577), DirectX 12 network in/out rate limit 50 Mbps Языком интерфейса по умолчанию был сделан английский: для решения "белых пятен" в замерах вместо сбора данных через PerfMon были попытки использовать командлет Get-Counter с Real Time приоритетом процесса. А русские названия счётчиков памяти усложняли эти попытки. Дело в том, что когда вы определяете новый сборщик данных PerfMon через GUI, то видите псевдонимы счётчиков, которые зависят от языка интерфейса. Но фактически, при работе, используются "родные" английские имена. Это можно увидеть в xml файле, если сохранить сборщик как шаблон. Утилита logman тоже работает с английскими названиями. Командлет Get-Counter работает именно с псевдонимами. То есть, от языка интерфейса зависит, какая из двух команд завершится ошибкой: Принципиально такой подход не решил проблему, пробелы остались, хотя и в меньшем объёме. Но стало проще конфигурировать сбор данных в PerfMon / PowerShell, а, после разделения счётчиков на две группы, наконец-таки заработали счётчики оперативной памяти! Не претерпела существенных изменений. Проводились те же самые три теста: ввод текста + 3D BenchMark ввод текста + просмотр локальных видеофайлов ввод текста + просмотр youtube-ролика Отличие от первой части заключалось в том, что серия тестов повторялась сначала для одной, затем для двух и для трёх одновременных терминальных сессий. А набор счётчиков из первой части был разделён на две группы: Общие метрики: '\Memory\% Committed Bytes In Use' '\Memory\Available Bytes' '\Processor Information(_Total)\% Processor Time' '\NVIDIA GPU(*)\% GPU Usage' '\NVIDIA GPU(*)\% GPU Memory Usage' '\NVIDIA GPU(*)\% FB Usage' '\NVIDIA GPU(*)\% Video Decoder Usage' '\NVIDIA GPU(*)\% Video Encoder Usage' Метрики сеансов: '\User Input Delay per Session(#id)\Max Input Delay' # задержка в указанном сеансе '\RemoteFX Network(RDP-Tcp#N)\Loss Rate' '\RemoteFX Network(RDP-Tcp#N)\Current TCP Bandwidth' '\RemoteFX Network(RDP-Tcp#N)\Current UDP Bandwidth' '\RemoteFX Network(RDP-Tcp#N)\Total Sent Rate' '\RemoteFX Network(RDP-Tcp#N)\TCP Sent Rate' '\RemoteFX Network(RDP-Tcp#N)\UDP Sent Rate' '\RemoteFX Network(RDP-Tcp#N)\Total Received Rate' '\RemoteFX Network(RDP-Tcp#N)\TCP Received Rate' '\RemoteFX Network(RDP-Tcp#N)\UDP Received Rate' '\RemoteFX Graphics(RDP-Tcp#N)\Input Frames/Second' '\RemoteFX Graphics(RDP-Tcp#N)\Output Frames/Second' '\RemoteFX Graphics(RDP-Tcp#N)\Frame Quality' '\RemoteFX Graphics(RDP-Tcp#N)\Average Encoding Time' '\RemoteFX Graphics(RDP-Tcp#N)\Graphics Compression ratio' '\RemoteFX Graphics(RDP-Tcp#N)\Frames Skipped/Second - Insufficient Server Resources' '\RemoteFX Graphics(RDP-Tcp#N)\Frames Skipped/Second - Insufficient Network Resources' '\RemoteFX Graphics(RDP-Tcp#N)\Frames Skipped/Second - Insufficient Client Resources' Общие метрики не зависели от количества активных сеансов, счётчиков всегда было восемь в любом тесте для любого количества пользователей. А вот метрики сеаснов добавлялись для каждого пользователя отдельно, так как учитывали только свою терминальную сессию. Чтобы не заниматься ручной перенастройкой PerfMon при входе очередного пользователя на терминальный сервер, были написаны скрипты, которые автоматически настраивали группы сборщиков данных в зависимости от текущих терминальных сессий. Замеры и тесты тоже запускались скриптами - для удобства и синхронизации: пользователям достаточно было запустить сценарий и указать нужный тест, который стартовал в начале каждой новой минуты у всех одновременно. Спустя несколько секунд этот же скрипт в сессии администратора запускал сбор данных. Большинство счётчиков сеанса использует номер терминального сеанса, а счётчик задержек - id. Поэтому, по окончании теста в журнал тестирования matches.csv записывались данные текущего теста: пользователи, id и номера сессий, имена файлов с замерами: Такое журналирование процесса тестирования помогло на этапе обработки данных сопоставить пользователей с их счётчиками. Исходный код скриптов доступен в приложении: (пере-)установка сборщиков данных в PerfMon — Set-DataCollectors.ps1 и Set-DataCollectors.cmd Одновременный запуск тестов и замеров — Start-SyncedTest.ps1 и Start-SyncedTest.cmd Вспомогательный код был вынесен в отдельный файл модуля PowerShell — helper.psm1 Скрипт конвертации двоичных файлов в формат csv из первой части также был модифицирован: теперь он учитывал наличие данных по нескольким сессиям и исправлял заголовки с помощью файла matches.csv. Исходный код скриптов обработки двоичных файлов с результатами замеров можно посмотреть в приложении — blg2csv.ps1 и blg2csv.cmd Обработка данных и построение графиков, как и раньше, выполнена в Jupiter-блокнотах с помощью библиотек pandas и matplotlib. Теперь на одну метрику приходилось уже девять графиков вместо трёх, поэтому, для наглядности, графики располагались на диаграмме двумя способами: Исходный код обоих блокнотов есть в приложении — figures.ipynb и figures_alt.ipynb Пожалуй, один из самых важных, наряду с частотой кадров, показателей с точки зрения конечного пользователя. Измеряет максимальную разницу между тем, когда ввод помещается в очередь и когда приложение получает его в традиционном цикле обработки сообщений. Интересен он ещё тем, что в тесте '3D BenchMark' этот показатель получился аномально высоким: задержка измерялась секундами для двух одновременных сеансов и десятками секунд в случае трёх сеансов! В норме показатель измеряется в миллисекундах.   Диаграмма с таким расположением графиков приведена для лучшей демонстрации аномалии. Последующие диаграммы будут с другим расположением графиков, "тесты в ряд", для более наглядной демонстрации и сравнения изменений показателей при изменении количества сеансов. Вот так те же самые данные будут выглядеть при таком расположении: В официальной документации по диагностике проблем производительности есть пример, когда задержка ввода увеличивается из-за возрастающей нагрузки на процессор при подключении новых пользователей. В нашем случае это не объясняет увеличение задержки ввода на три-четыре порядка: счётчик загрузки процессора находится в пределах 60% и даже снизился в случае трёх сеансов. Другие метрики, в том числе и сетевые, тоже остались в норме.   А утилизация виртуального процессора оказалась выше.   В 3D тесте частота кадров ожидаемо зависела от количества пользователей, запустивших бенчмарк. Два других теста показали хорошую производительность для двух терминальных сессий, а в случае трёх сеансов уже не хватало производительности процессора. В первой части исследования при проигрывании ролика "Flying Through Forest 1" мы видели провалы до 20-15 fps, но тогда виртуальная машина использовала только два ядра. После увеличения vCPU до 6 ядер показатель fps явно стал лучше для одного-двух сеансов и только для трёх сеансов он снова просел. Youtube-тест также показывал отличные результаты, пока не подключился третий пользователь, что вызвало почти 100% нагрузку на процессор, а fps при этом просел на 10 кадров. Счётчики показали вполне ожидаемый результат: с ростом числа сеансов свободной памяти становилось меньше, а использовалась она чаще. В среднем, один тест "стоил" одному пользователю около 1 ГБ. Здесь также замеры не показали ничего необычного: самым тяжёлым для процессора/памяти видеокарты был 3D тест. Больше пользователей -> меньше кадров в секунду -> ниже использование фреймбуфера. Видеотест. Первый ролик, "Ants carrying dead spider", нагружал видеопроцессор, а третий, "Low Angle Of Pedestrians Walking In Busy Street, Daytime", декодер и, как следствие, видеопамять. Основную нагрузку при включении RemoteFX составляет UDP трафик, а по TCP передаются, например, нажатия клавиатуры. Соответственно, TCP-трафик на несколько порядков меньше, колеблется в пределах от сотен до тысяч бит в секунду. Здесь приведены общие счётчики, графики в разрезе протоколов вынес в приложение. Помечены как UDP трафик и TCP трафик Основные всплески в графиках вызывало проигрывание локального видеофайла "Flying Through Forest 1". Видимо, в эти моменты поток данных упирался в ограничение скорости канала связи со стороны сервера, 50 Мбит/с. NVIDIA GRID M60 позиционируется (1, 2) как производительное решение виртуализации рабочих мест, столов и приложений для дизайнеров, разработчиков, офисных и прочих сотрудников. Эту видеокарту можно использовать на 32 виртуальных машинах максимум, выделив по 512 МБ видеопамяти на каждую ВМ. В нашем случае профиль 'M60-1Q' был шире, на 1 ГБ. Как показывают тесты, масштабирование виртуального сервера с этим видеопрофилем на несколько пользователей упирается, в первую очередь, в общие ресурсы виртуальной машины - vCPU и vRAM. Для оценки влияния именно количества пользователей на производительность, любой тест запускался у всех пользователей одновременно. Поэтому пики тестовой нагрузки складывались друг с другом и требовали больше ресурсов для комфортной работы: 2 ядра vCPU и 1 ГБ vRAM на пользователя. При таких настройках видеокарта "вытягивала" 2-3 одновременных сеанса, в зависимости от теста. В реальности, конечно же, ресурсы подбирают исходя из конкретных задач, средней и максимальной нагрузки на сервер. Например, если основная часть работы пары десятков сотрудников носит "офисный" характер — документы, почта, браузер, 1С — вполне можно использовать один терминальный сервер с таким vGPU, подстраивая ресурсы ЦПУ и RAM по мере необходимости под число пользователей.  Если же речь идёт об обработке 3D графики, то вряд ли нагрузка на vGPU будет такая же постоянная и интенсивная, как в 3D тесте. Скорее всего, с учётом увеличения ресурсов по сравнению с "офисной" конфигурацией, этот видеопрофиль позволит нормально работать 3-5 пользователям. Впрочем, для действительно сложных 3D задач, виртуальный сервер можно отдать в монопольное использование одному сотруднику, масштабируясь по количеству серверов. ось Y одинаково масштабирована внутри одной метрики Для понимания масштабирования vGPU на несколько терминальных сеансов были проведены следующие замеры: три теста (см. 1ю часть): 3D тест, проигрывание локального плейлиста, проигрывание youtube-ролика три случая: каждый тест воспроизводился в одном, двух и трёх терминальных сеансах одновременно Таким образом по одной метрике будет построено 9 графиков: в колонках показаны результаты тестов в рядах - количество одновременных RDP-сеансов ось Y одинаково масштабирована внутри одной метрики Для понимания масштабирования vGPU на несколько терминальных сеансов были проведены следующие замеры: три теста (см. 1ю часть): 3D тест, проигрывание локального плейлиста, проигрывание youtube-ролика три случая: каждый тест воспроизводился в одном, двух и трёх терминальных сеансах одновременно Таким образом по одной метрике будет построено 9 графиков: в колонках находятся результаты для разного количества одновременных RDP-сеансов в рядах - тесты Спасибо за внимание! Что ещё интересного есть в блоге Cloud4Y → Частые ошибки в настройках Nginx, из-за которых веб-сервер становится уязвимым → Пароль как крестраж: ещё один способ защитить свои учётные данные → Тим Бернерс-Ли предлагает хранить персональные данные в подах → Подготовка шаблона vApp тестовой среды VMware vCenter + ESXi → Создание группы доступности AlwaysON на основе кластера Failover Подписывайтесь на наш Telegram-канал, чтобы не пропустить очередную статью. Пишем не чаще двух раз в неделю и только по делу. Корпоративный облачный провайдер