Почти весь хостинг - общий. Одна физическая машина, несколько клиентов, у каждого своя квота и планировщик, решающий, чья очередь. Сама по себе это не проблема: именно так устроена экономика, и поэтому игровой сервер стоит шесть долларов в месяц, а не шестьдесят. Проблемой это становится, когда ваша квота - доля того, что осталось, а не резерв, потому что тогда ваша производительность зависит от чужого вечера. Всё умение сводится к тому, чтобы отличить эти два устройства друг от друга до покупки, измерить изнутри собственного сервера, какое из них у вас, и распознать небольшое число случаев, когда выделенное ядро - правильное решение, а не дорогое суеверие.
Что на самом деле означает «общий»#
Машину делят двумя способами, и под нагрузкой они ведут себя по-разному.
Полная виртуализация (KVM, VMware, Hyper-V) выдаёт каждому клиенту виртуальную машину с виртуальными процессорами. vCPU - это поток, который гипервизор ставит на реальное ядро, когда ему удобно. Если у гипервизора 32 потока, а продано 96 vCPU, это овербукинг 3:1, и он работает, потому что большинство клиентов большую часть времени простаивают. Когда они не простаивают, ваш vCPU стоит в очереди и ждёт реального ядра, а ядро гостя записывает это ожидание как steal time.
Контейнеры (Docker, LXC и всё, что на них построено, включая Pterodactyl и Wings) обходятся без виртуальной машины. Каждый контейнер - это группа процессов на ядре самого хоста, отгороженная пространствами имён и ограниченная cgroups. Виртуального процессора, у которого можно что-то украсть, нет: ваши процессы стоят в общей очереди выполнения хоста вместе со всеми остальными, а планировщик ядра напрямую обеспечивает ваш лимит.
Это различие важно для диагностики. В виртуальной машине конкуренцию можно измерить одним столбцом vmstat. В контейнере steal time почти всегда равен нулю, а конкуренция проявляется как задержка планирования, чего по умолчанию вам никто не показывает. Большая часть хостинга игр и приложений, включая всё на панелях типа Pterodactyl, - это случай контейнера.
Сам лимит живёт в двух файлах. В cgroup v2, которую используют современные ядра:
$ cat /sys/fs/cgroup/cpu.max250000 100000$ cat /sys/fs/cgroup/cpu.weight100cpu.max - это квота и период в микросекундах: 250 000 микросекунд процессорного времени в каждом окне в 100 000 микросекунд, то есть 2.5 ядра. cpu.weight - пропорциональная доля, которая применяется, когда несколько cgroup хотят машину одновременно, по шкале от 1 до 10 000, по умолчанию 100. В cgroup v1 они называются cpu.cfs_quota_us, cpu.cfs_period_us и cpu.shares (по умолчанию 1024), и вы всё ещё встретите их на старых хостах.
Три способа, которыми хостер делит процессор#
Любой хостинговый продукт - это один из трёх, как бы ни назвала его страница с продажами.
| Метод | Механизм | Что происходит, когда соседи заняты |
|---|---|---|
| Вес или доли | Пропорционально, без потолка | Вы можете выходить за свою номинальную долю, а излишек теряете первым |
| Квота или троттлинг | Жёсткий лимит на период | Вы получаете ровно то, что купили, ни больше ни меньше |
| Закрепление или выделенное | Назначены конкретные ядра | На этих ядрах никто другой не работает вообще |
Продажа по весам - источник формулировок «до 4 vCPU» и «с бёрстом». Она щедра, когда машина свободна, и именно такое устройство порождает жалобы на шумных соседей, потому что при конкуренции вы теряете как раз то, что вам показали на странице продаж.
Жёсткая квота менее лестна и более предсказуема. Бесплатного всплеска вы никогда не получаете, но и никогда не теряете его. Тариф со значением 250 означает 250% одного ядра, всегда, а сервер, упёршийся в этот потолок, медленный, но не сломанный. Так распределяет ресурсы RE:NODE: один контейнер на сервер, CPU как жёсткий троттлинг до купленной доли, и сервер, упирающийся в 100%, за это не приостанавливают. Обмен явный: потолок настоящий, но и пол тоже.
Как шумный сосед выглядит изнутри#
Ваши собственные графики в порядке. Память спокойна, ваш процесс не делает ничего необычного, в конфигурации ничего не менялось, а частота тиков в непонятные моменты дрожит. Этот образ - необъяснимый разброс при чистых внутренних метриках - и есть признак. Три эмпирических правила покрывают большинство случаев:
- Стабильно низкая скорость - это обычно вы. Сервер, одинаково плохой в 04:00 и в 21:00, делает слишком много работы, и машина тут ни при чём.
- Переменная скорость при тихих внутренних метриках - это обычно машина. Час хорошо, двадцать минут плохо, снова хорошо, и никакой связи с числом игроков.
- Просадки в одно и то же время каждый день - это обычно расписание - ваше, хостера или соседа. Резервные копии, ротация логов, обновления пакетов и сохранения мира группируются на круглых часах.
Измерение, которое их различает, - это разброс, а не среднее. Среднее скрывает то, что игроки ощущают на самом деле. Если игра отдаёт время каждого тика, смотрите максимум и 99-й перцентиль: /mspt в Minecraft выводит средние значения и пики за последние пять секунд, минуту и пять минут, и именно в столбце пиков конкуренция проявляется первой. Почему хорошее среднее при ужасном пике ощущается хуже, чем посредственное, но стабильное среднее, рассказано в статье что на самом деле означает частота тиков.
Измерения: steal, троттлинг и pressure#
Четыре числа говорят почти обо всём. Снимайте их, пока сервер ощущается плохо, а не потом.
Steal time, если вы находитесь в виртуальной машине. Столбец st в vmstat, столбец %steal в mpstat и восьмое поле строки cpu в /proc/stat:
$ vmstat 1 10 # last column: st$ mpstat -P ALL 1 5 # %steal, per core, needs the sysstat package$ grep '^cpu ' /proc/statВсё, что стабильно выше примерно 5%, означает, что гипервизор отдаёт ваше время другому, и никакая настройка с вашей стороны этого не вернёт. Редкие всплески в одну цифру нормальны.
Троттлинг, то есть применение вашей собственной квоты:
$ cat /sys/fs/cgroup/cpu.statusage_usec 8012345678user_usec 6902110004system_usec 1110235674nr_periods 940213nr_throttled 7311throttled_usec 41233905Разделите nr_throttled на nr_periods. Если меньше процента, игнорируйте. Если 5% и больше, ваш контейнер раз за разом останавливают посреди работы, и это вы упираетесь в собственный потолок, а не сосед что-то отбирает. Исправление - делать меньше работы или купить долю побольше; какое из двух, разобрано в статье CPU или RAM.
Pressure stall information - то, что ловит конкуренцию в контейнерах. На ядрах с включённым PSI:
$ cat /proc/pressure/cpusome avg10=12.44 avg60=9.81 avg300=4.02 total=88213445$ cat /sys/fs/cgroup/cpu.pressuresome avg10=11.90 avg60=9.02 avg300=3.88 total=71004112some avg10 - это процент времени за последние десять секунд, в течение которого хотя бы одна задача в этой группе была готова к выполнению, но ждала CPU. Высокое давление при том, что вы с запасом в пределах квоты, а nr_throttled не растёт, - самое близкое к доказательству того, что ограничение создаёт машина, а не ваш сервер.
Задержка планирования для одного процесса, если нужна такая точность. Второе поле /proc/<pid>/schedstat - это наносекунды, проведённые в ожидании в очереди выполнения, накопленные с момента запуска процесса. Снимите значение дважды с интервалом в минуту и разделите на интервал.
Если у вас есть доступ к оболочке и нужно число, которое можно сравнивать между днями, запускайте по расписанию фиксированный однопоточный бенчмарк и следите за разбросом, а не за значением:
$ sysbench cpu --cpu-max-prime=20000 --time=10 --threads=1 run | grep 'events per second'Достаточно раз в час в течение двух суток. На тихой машине результаты между запусками различаются на несколько процентов. На загруженной - на десятки, и плохие запуски совпадают с часами, когда жалуются игроки.
Отличаем свою проблему от проблемы машины#
| Что вы наблюдаете | Почти наверняка | Не |
|---|---|---|
На квоте, nr_throttled растёт | Вы, делаете слишком много работы | Сосед |
| Далеко под квотой, пики тиков рваные | Машина или ваш собственный GC | Нехватка памяти |
%steal выше 5% стабильно, в виртуальной машине | Машина | Что-либо из подконтрольного вам |
cpu.pressure высокий, троттлинг не растёт | Машина | Ваша конфигурация |
| Плохо в один и тот же час каждый день | Расписание где-то | Случайная конкуренция |
| Плохо с того дня, как вы что-то изменили | То, что вы изменили | Хост |
| Все клиенты на узле жалуются одновременно | Машина, и поддержка об этом знает | Ваш сервер |
| У одного игрока плохой пинг, у остальных нормальный | Сетевой маршрут | CPU вообще |
Последняя строка постоянно сбивает людей. Один игрок, которому плохо, - это проблема маршрутизации или соединения, а не CPU, и ему нужна статья задержка, джиттер и потеря пакетов, а не тариф побольше.
Соседи по диску, сети и кэшу#
На CPU валят вину потому, что это ресурс с числом на странице продаж, но делится не только он.
Диск. У NVMe огромная пропускная способность и всё же конечное число IOPS, а очередь общая. Сосед, восстанавливающий большой backup, может добавить миллисекунды к вашим записям на всё время восстановления. На пуле ZFS - а именно его использует RE:NODE, и везде NVMe - адаптивный кэш чтения тоже является общей памятью хоста, так что сосед, читающий очень большой рабочий набор, может холодно перезапустить кэш всем остальным. Симптом: короткое зависание в момент, когда вы ничего не планировали, обычно пока идёт ваше собственное сохранение. Что хранилище исправляет и чего не исправляет, описано в статье что на самом деле меняет NVMe.
Сеть. Безлимитный означает не тарифицируемый за гигабайт, а не право забить общий канал. Сосед, стабильно гоняющий гигабит, обычно не влияет на игровой сервер, потому что игры передают очень мало данных - от нескольких десятков до нескольких сотен килобайт в секунду на игрока. Влияет объёмная атака, направленная на машину, а не на вас, и это отдельный разговор: что мы делаем с атаками и пропускная способность и добросовестное использование.
Пропускная способность памяти и кэш последнего уровня. Действительно невидимый. Ваш лимит памяти принадлежит вам, но путь к памяти и общий кэш L3 - нет, и сосед с большим рабочим набором вытесняет ваши горячие данные из кэша. Счётчика, который можно прочитать изнутри контейнера, для этого нет. Это проявляется как та же нагрузка, которая занимает на 10-20% больше времени по причине, которую вы не можете назвать, и это одна из причин, по которым разброс бенчмарков на общем оборудовании никогда не доходит до нуля.
Что с этим можно сделать#
По порядку, сначала самое дешёвое.
- Докажите, прежде чем спорить. Два измерения с интервалом в неделю тем же методом, снятые во время проблемы. «Лагает» никто не сможет обработать, включая вас.
- Сначала уберите собственный разброс. Пауза сборщика мусора, синхронное сохранение мира, плагин, выполняющий запрос к базе в главном потоке, и backup в пиковое время дают ту же дрожь, что и сосед. Исправьте это, и то, что останется, действительно внешнее. Первый проход - как читать график нагрузки сервера.
- Уберите свои расписания с круглого часа. Все выбирают
0 0 * * *. Выберите0 4 * * *или17 3 * * *, и вы будете конкурировать с гораздо меньшим числом людей, включая обслуживание самого хостера. Синтаксис описан в статье выражения cron простыми словами, а список - в статье задачи по расписанию, которые стоит иметь. - Откройте тикет с цифрами. Хостер может перенести контейнер на более тихий узел, и хостер, который видит данные по steal или pressure с вашей стороны, обычно делает это без лишних споров. В RE:NODE тикет из панели попадает ко всему персоналу и принимает приватные вложения, и это правильное место для скриншота графика.
- Покупайте жёсткую квоту, а не долю с бёрстом. Если выбор между «до 4 vCPU» и «2 vCPU, гарантированно», второе - лучший продукт для всего, у чего есть бюджет задержки, даже если на пустой машине он показывает худший результат в бенчмарке.
- Покупайте машину. Об этом ниже, и это действительно последнее средство, а не первое.
Что не помогает: nice и renice (они переупорядочивают ваши собственные процессы между собой, а не относительно процессов другого клиента), закрепление за ядрами изнутри контейнера, который вам не принадлежит, и покупка дополнительной памяти. Добавление памяти на сервер с проблемой CPU меняет график, на который вы смотрите, и ничего из того, что чувствуют игроки.
Когда выделенное ядро оправдано#
Для большинства серверов - никогда. Выживание на двадцать игроков, бот для Discord, небольшое веб-приложение и база данных с несколькими запросами в секунду далеко ниже той точки, где конкуренция становится ограничивающим фактором, и деньги лучше потратить на более быстрое ядро или на то, чтобы делать меньше работы.
Есть три случая, где это правильное решение:
- Стабильность тиков - это и есть продукт. Соревновательный шутер, гоночный сервер, всё, где просадка на 40 мс означает проигранный раунд. Среднее никогда не было метрикой; запоминают и уходят из-за худшего случая.
- Вы пообещали кому-то бюджет задержки. API с опубликованным p99, платёжный поток, всё, к чему привязан договор. Нельзя брать обязательство по числу, которое вы не контролируете.
- Нагрузка действительно постоянно использует несколько ядер. Компиляция, кодирование видео, база данных с параллельными сканированиями. Большинство игровых серверов таковыми не являются - симуляция идёт в одном потоке, так что выделенное восьмое ядро не даёт ничего такого, что более быстрое первое ядро не дало бы дешевле.
Будьте честны в том, что меняется. Выделенное ядро убирает разброс, вносимый другими клиентами. Оно не делает однопоточную симуляцию быстрее тактовой частоты ядра, на котором она стоит, не исправляет плагин, блокирующий главный поток, и передаёт вам обслуживание, за которое раньше платили кому-то другому. Если ваши тики плохи стабильно и воспроизводимо, выделенная машина воспроизведёт их идеально. Остальные стороны компромисса, включая те, что представляют собой работу, а не деньги, разобраны в статьях VDS или игровая панель и VPS, VDS и выделенный сервер.
Один практический тест перед тем, как тратить деньги: арендуйте машину поменьше на месяц и запустите на ней ту же нагрузку рядом с общим сервером, с одним и тем же бенчмарком по расписанию на обоих. Если плохие часы на общем сервере исчезли, а среднее почти не изменилось, конкуренция была настоящей и вы купили нужное. Если оба графика выглядят одинаково, вы просто заплатили больше за ту же проблему, а ответ всё время был в вашей конфигурации.
FAQ#
Что такое CPU steal time?
Время, когда ваш виртуальный процессор был готов выполняться, а гипервизор отдал физическое ядро другому гостю. Его сообщает ядро гостя в vmstat, mpstat и /proc/stat. Оно существует только при полной виртуализации - в контейнере гипервизора нет, поэтому steal равен нулю, даже когда машина сильно загружена, и смотреть нужно на pressure stall information.
Означает ли 2 vCPU, что для меня зарезервированы два ядра?
Почти никогда. В контейнере это означает 200% одного ядра в виде троттлинга: суммарное время, которое могут использовать ваши процессы за период планирования. В виртуальной машине - два планируемых потока, которые гипервизор ставит на реальные ядра, когда те свободны. Ни то ни другое не является резервом, пока хостер отдельно не заявляет, что ядра закреплены.
Мой сервер стоит на 100% CPU. Меня скоро приостановят?
Не в RE:NODE. Контейнер ограничен купленной долей, поэтому работает медленнее и ничего не портит, а 100% никогда не основание для приостановки. Это сигнал, что потолок - это потолок: проверьте, укладывается ли время тика в бюджет, и если да, то график на пределе - это просто эффективный сервер.
Может ли шумный сосед действительно уронить мой сервер?
Не напрямую. Конкуренция делает всё медленным, а не мёртвым. Она может продавить таймаут за его предел: сторожевой таймер, убивающий сервер, если он не отвечает 60 секунд, проверка работоспособности, падающая три раза подряд, соединение с базой, которое сдаётся. Если вы видите падения, а не медлительность, сначала прочитайте статью почему ваш игровой сервер постоянно перезапускается; конкуренция редко объясняет всё.
Как доказать это своему хостеру?
Отправьте временные метки и числа: образцы cpu.pressure или %steal из плохого окна, ваш собственный cpu.stat, показывающий, что троттлинга не было, и график времени тика или времени ответа за тот же период. С такой комбинацией трудно спорить, и по ней легко действовать. Прилагательные - нет.
Всегда ли выделенная машина быстрее?
Нет. Она стабильнее. Общий сервер на современном ядре с высокой частотой вполне может обойти выделенную старую машину в однопоточной игровой симуляции, и часто так и делает. Сравнивайте модель процессора и частоту, прежде чем что-то предполагать, а это возможно только тогда, когда хостер называет модель.




Комментарии
Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.