Метрики лгут: libvirt
Между неправильными измерениями и неправильными ожиданиями тонкая грань. Люди обвиняют метрики в том, что они не показывают того, чего от них ждут. В этой статье я на практике покажу какие метрики либвирта часто понимают неправильно и почему это происходит.
virtio-blk / virtio-scsi
Существует два популярных драйвера диска для виртуалок. Virtio-blk и virtio-scsi. Первый чуть более быстрый, но второй более фичастый, поддерживает большее количество подключаемых дисков и набор команд SCSI, он проще расширяется. Оба драйвера поддерживают лимит на рейт операций. Но есть нюанс.
С драйвером virtio-blk можно превысить лимит. Последовательно читая или записывая данные можно получить статистику с виртуальной машины, когда операций выполнено больше, чем доступно виртуалке. С драйвером virtio-scsi так не получится.
Дело в том, как написан драйвер virtio-blk. Сначала идёт подсчёт количества операций для вывода статистики. После этого драйвер сливает некоторые операции в одну. И только после этого идёт подсчёт количества операций находящихся в процессе выполнения для сравнения с заданными лимитами, и принимается решение о троттлинге.
Так легко получить ситуацию, которую не ожидаешь увидеть — виртуальная машина создаёт нагрузку выше лимитов, но при этом упирается в невидимый порог. Забавно, потому что на конечный сторадж виртуалка будет создавать нагрузку в пределах лимитов, а вот изнутри машинки количество операций будет выше лимитов.
cpu time / vcpu time
Время работы процессора измеряется по-разному с точки зрения гипервизора и с точки зрения виртуальной машины.
root@somehost:~zaharov# virsh domstats instance-0000306e | grep cpu
cpu.time=714072549406767
cpu.user=133718120000000
cpu.system=316048280000000
cpu.cache.monitor.count=0
vcpu.current=1
vcpu.maximum=1
vcpu.0.state=1
vcpu.0.time=320775790000000
vcpu.0.wait=0
vcpu.0.delay=3384705652616
Хост видит, что у него есть дерево тредов, часть из которых это ядра виртуалки. Другая часть — сопутствующие треды qemu, например, для обработки операций с сетевыми дисками. За представление суммарного времени работы всего домена либвирта на цпу отвечает метрика cpu time
. Это ресурс, который потребляет домен клиента целиком, включая все треды qemu.
Метрика vcpu time
содержит количество времени работы только тредов виртуальных ядер клиента. Она ещё и считается для каждого виртуального ядра отдельно. По этой метрике видно сколько ЦПУ нужно клиенту для своих вычислений. Разницу между этими значениями можно использовать для того, чтобы увидеть какой оверхед возникает при работе виртуальной машины.
Аккуратная работа с этими метриками поможет ожиданиям приблизиться к реальности и правильно раскладывать яйца в корзины виртуалки по хостам.
cpu system / cpu user
Ещё один нюанс измерений утилизации ЦПУ в том, что либвирт разделяет метрики утилизации цпу в юзерспейсе и кернельспейсе.
root@somehost:~zaharov# virsh domstats instance-0000306e | grep cpu
cpu.time=714072549406767
cpu.user=133718120000000
cpu.system=316048280000000
...
Речь идёт о контексте работы гипервизора. Т.е. о пространстве пользователя и ядра на гипервизоре для процесса qemu. Гипервизор не знает, какой код выполняется внутри виртуалки.
Кроме того, эти данные берутся из сигрупп процесса qemu. А внутри сигрупп они считаются своеобразно:
val[CPUACCT_STAT_USER] += cpustat[CPUTIME_USER];
val[CPUACCT_STAT_USER] += cpustat[CPUTIME_NICE];
val[CPUACCT_STAT_SYSTEM] += cpustat[CPUTIME_SYSTEM];
val[CPUACCT_STAT_SYSTEM] += cpustat[CPUTIME_IRQ];
val[CPUACCT_STAT_SYSTEM] += cpustat[CPUTIME_SOFTIRQ];
То есть, то, что мы видим как cpu.user
на самом деле сумма nice
и user
. А cpu.system
– сумма времени работы всех прерываний, плюс время работы в ядре. При этом время работы виртуального цпу здесь не учитывается.
delay time (steal time)
Стилтайм. О нём ходят слухи, его обсуждают менеджеры, его боятся инженеры поддержки. Ему придают мифические свойства и о нём слагают легенды.
root@somehost:~zaharov# virsh domstats instance-00003283 | grep delay
vcpu.0.delay=870022833907
vcpu.1.delay=863970297346
vcpu.2.delay=993270276029
vcpu.3.delay=776720292635
Нужно просто запомнить, что стилтайм — это показатель конкуренции ядер виртуального проца за ядра реального с другими процессами в системе. Не больше и не меньше. Он возникает только в тот момент, когда виртуалке нужен процессор для выполнения, но планировщик отложил её в очередь и поставил на исполнение другой процесс.
Изменение частоты работы реальных ядер не приводит к стилтайму. Доступ к памяти на удаленной нума-ноде не приводит к стилтайму. Да, производительность деградирует в результате этих событий, но стилтайм не возникает.
Подробнее о том, как он считается можно прочитать здесь.
Вывод
Не дайте метрикам себя обмануть! Если решили на что-то положиться, то всегда проверяйте соответствуют ли ожидания реальности.
Мы работаем с кодом, а код пишут люди. Всегда можно обратиться к нему, чтобы понять что на самом деле происходит в программе. Ранее я уже писал о некоторых методах работы с исходниками.
Изучать код проще, чем изучать законы природы, по крайней мере мы можем найти ответ за конечное время:) хоть это не всегда даётся легко.