Если игровой поток на каждой строке лога ждёт, пока диск завершит запись, то при занятом диске останавливается и игра.
Почему Боевые логи и логи обменов пишутся в файл прямо из игрового потока → Следствие Если требуется гарантированная запись (fsync) или буфер записи ОС (страничный кэш) заполнен до предела, при занятом диске одна запись длится десятки ms → На экране Подвисания в боях, где пишется много логов
Основной ответственный Команда разработки · Разработка сервера · Совместно Команда инфраструктуры · Серверная инфраструктура
Команда разработки: задачи
Перейти на асинхронное логирование (буфер в памяти и отдельный поток), сократить объём логов, не вызывать fsync в игровом потоке.
Команда инфраструктуры: задачи
Запускать ротацию и сжатие логов с пониженным приоритетом ввода-вывода, держать логи на отдельном от данных диске, отслеживать задержку записи на диск.
На графике
Случайные всплески · время тика сервера, задержка записи на диск
Где смотреть
Накладывать w_await и aqu-sz из iostat -x 1 на время тика и через perf trace -p PID --duration 10 искать в игровом сервере вызовы write и fsync дольше 10 ms и потоки, которые их сделали
Подтверждает
В моменты всплесков тика вызовы write и fsync в игровом потоке длятся десятки ms, и в тот же момент подскакивает задержка записи на диск. Часто это совпадает со временем ротации или сжатия логов
Опровергает
Если в игровом потоке нет долгих системных вызовов, а тик скачет, причина другая: GC, блокировки, превышение бюджета тика. Если долгие вызовы только в отдельном потоке логирования, на игру это не влияет
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)
Подробнее
Обычно ОС сначала принимает запись в память (страничный кэш) и сбрасывает её на диск позже, поэтому строка лога, как правило, записывается мгновенно. Остановки бывают, когда fsync требует гарантированной записи, когда накопившиеся записи превышают лимит и ОС блокирует вызов записи, а также во время ротации или сжатия файлов логов. Поэтому обычно всё в порядке, а всплески появляются только в моменты, когда диск занят.
Источники
fsync(2) — Linux manual pageLinux man-pages fsync сбрасывает изменённые данные на диск (включая кэш диска) и блокирует вызов, пока устройство не сообщит о завершении
Documentation for /proc/sys/vm/Linux kernel Когда накопленные несброшенные данные (dirty) достигают dirty_ratio, процесс, который пишет, сам берёт на себя запись на диск
ionice(1) — Linux manual pageutil-linux Задача с приоритетом ввода-вывода idle получает время диска, только когда диском не пользуются другие программы
iostat(1) — Linux manual pagesysstat -x: w_await (среднее время обработки запроса на запись, включая ожидание в очереди), aqu-sz (средняя длина очереди, прежнее название avgqu-sz)
perf-trace(1) — Linux manual pageperf -p трассирует системные вызовы работающего процесса, --duration показывает только вызовы дольше заданного числа ms