Как стать автором
Обновить
Selectel
IT-инфраструктура для бизнеса

Об учёте процессорного времени в облаке

Время на прочтение6 мин
Количество просмотров19K
После запуска я получил много вопросов о том, как именно учитываются ресурсы в облаке. Некоторые интуитивно понимают, что такое «час процессорного времени» но есть и те, кто хочет подробного объяснения. Поскольку в общем анонсе подробные объяснения заняли бы много места, я вынес его в отдельный топик. Заодно, такой формат позволит более подробно описать, как Зен и виртуальные машины взаимодействуют. Уровень этого текста научно-популярный, то есть я не буду вдаваться в дебри кольцевых буферов, маскировки событий, «кредитного планировщика» и т.д., вместо этого я попробую рассказать относительно человеческим языком о том, как гипервизор управляет гостевыми машинами.


Что такое «процессорное время»? Сначала мы его хотели назвать более привычным «машинное время», благо, такой термин использовался во времена мейнфреймов, когда идея разделения машинного времени только-только зародилась, но вовремя остановились. Машинное время тех лет подразумевало все ресурсы, которые использовались машиной, а в нашем случае речь идёт именно о процессоре, так как каждый ограниченный ресурс учитывается раздельно.

Итак, что такое «процессорное время» и как может оказаться, что у одной виртуальной машины его насчитывается 4 часа в сутки, а у другой накручивает 30 «часов» за часов десять?

Облако Селектел работает под управлением Xen, точнее, Xen Cloud Platform, в котором гипервизором выступает Xen.

В Xen есть понятие «планировщик доменов». Оставляя в стороне разницу между доменом и виртуальной машиной (домен — запущенная конкретная виртуальная машина, когда виртуальная машина перезагружается, получается новый домен, когда виртуальная машина выключена, домена нет, а сама машина — есть), можно считать, что этот планировщик виртуальных машин. Те, кто знаком с работой современных ОС, наверное уже догадались, что планировщик доменов подозрительно похож на планировщик процессов в этих самых современных ОС.

Как выглядит работа виртуальной машины?

Происходит какое-то событие: приходит сетевой пакет, срабатывает таймер, сигнал о перезагрузке и т.д. Xen отдаёт процессору команду начать выполнять виртуальную машину (точнее, домен, но в пределах этого объяснения будем считать эти понятия эквивалентными). Ядро виртуальной машины обрабатывает событие, из-за которого его разбудили. Если надо, то оно вызывает пользовательские процессы. Процессы делают свою работу и говорят ядру «всё, закончили». Ядро разбирается со своими вопросами и так же говорят гипервизору (Xen'у) — «всё, я закончило». После этого Xen останавливает выполнение машины. Она просто ничего не делает в буквальном смысле слова. Машина пребывает в таком состоянии до момента, пока не наступает новое событие.

В современных машинах эти события наступают с огромной скоростью — например, если вы загружаете файл со скоростью 5Мб/с, то это (при размере пакета в 1500 байт) — это больше 3000 пакетов в секунду. Каждый пакет — это отдельное прерывание (точнее, в Xen'е всё хитрее, там несколько вызовов объединяются в один, так что иногда виртуальная машина оказывается чуть-чуть быстрее, чем даже на голом железе). И каждое такое событие — это пробуждение машины. Но скорость современных процессоров такова, что после каждого такого вызова ядро виртуальной машины и процессы (например, апач или nginx) успевают отработать и заснуть. Отдача статики на 5Мб/с — это очень низкая нагрузка, примерно 1-2% одного ядра процессора, так что, не смотря на то, что события происходят с интервалом в 300 микросекунд, виртуальная машина отрабатывает за 3-6 микросекунд и оставшиеся 294-296 микросекунд успевает сказать гипервизору «я всё» и заснуть. А через микросекунды снова проснуться, отработать и снова заснуть. Так и получается, что виртуальная машина большую часть времени просто спит.

Вот именно моменты времени, когда виртуальная машина работает и являются «процессорным временем».

Вдумчивый читатель может спросить — а что, если виртуальная машина не скажет «я всё»? Если бы у нас была Windows 3.11, где была кооперативная многозадачность, то это бы привело к тому, что остальные не получили бы полагающееся им время. Но в Xen'е используется вытесняющая многозадачность — и виртуальная машина, которая слишком жадно работает, будет просто приостановлена. Принудительно. А потом снова продолжена.

Обычно такая ситуация происходит в условиях нехватки процессорного времени, и авторы Xen'а потратили тысячи часов, разрабатывая справедливые планировщики, которые в условиях перегруженности процессора решают задачу распределения времени так, чтобы все продолжили работать более-менее равномерно.

Однако, в реальных условиях современного хостинга, скорость работы процессора так высока, что процессор — наименее востребованный и самый простаивающий ресурс и в 99% случаев конкуренции за ресурсы вообще не возникает.

Процессорным временем является время, в течение которого работает виртуальная машина. Если она работала 2с за час, то это так и есть. Если 40 минут — значит, сорок минут. Процессорное время никак не связано с «реальным» временем на часах. Так как Xen командует виртуальными машинами, то Xen с точностью до наносекунды знает, сколько времени отработала каждая машина. Мы это значение округляем до микросекунд (чтобы избежать проблемы с int64), а в биллинге фиксируются лишь целые секунды (дробная часть копится, пока не набежит на секунду). Деньги же за процессорное время списываются как только набежит хотя бы на 1 копейку (в настоящий момент это 36 секунд). Для сравнения — загрузка виртуальной машины съедает примерно 3-6 секунд машинного времени, а это самая «дорогостоящая» операция в жизненном цикле домена.

Ещё одна важная деталь — это многопроцессорность. Несколько ядер процессора на самом деле это независимые процессоры. И они могут работать параллельно. Допустим, мы отдаём по 5Мб/с нескольким пользователям. В какой-то момент времени мы должны отправить новый пакет, до того, как отправили старый (например, прошёл интервал в 0.5 микросекунды). Если бы у нас был один процессор, этот запрос встал бы в очередь и был отработан после первого. Но если процессоров несколько, то запрос будет обработан первым свободным ядром независимо от уже занятых.

Если нагрузка высокая, то оказывается так, что работает несколько процессоров одновременно. В этом случае каждый из них работает, и процессорное время суммируется. Два одновременно загруженных ядра — 2с машинного времени в секунду. Восемь — значит восемь. Хотя в реальности обычно оказывается, что заняты несколько ядер, но не полностью, то есть в какой-то момент работает 2 ядра, в какой-то 3, а в какой-то момент — ни одно из них. Так что вполне можно увидеть 10 минут процессорного времени за час на 8-ядерной машине, обслуживающей десятки тысяч клиентов.

Если загрузка машины меньше 100% (то есть она потребляет меньше часа процессорного времени в час), то, формально, можно было бы ограничиться одним ядром.

Но, помните, что я выше сказал про одновременное обслуживание клиентов? Несколько ядер обеспечивают большую «отзывчивость» на запросы, хотя, возможно, одно ядро вполне бы справилось, пусть и ценой увеличения времени ответа на запрос.

Кстати, это ответ и ещё на один вопрос: влияет ли количество ядер на затрачиваемое процессорное время? Ответ — нет, если эти ядра простаивают, то процессорное время не используется. А большое число ядер лишь уменьшает задержку при обслуживании одновременных запросов от нескольких клиентов.

Ну и вдогонку немного о том, как нужно понимать понятия «отдаёт время», «выделяет время». Процессор — железка кремниевая и бестолковая. Всё, что может делать процессор — это выполнять код (ну и реагировать на прерывания). И процессор не особо разбирается «домен виртуальной машины» это, или запущенная копия angry birds. Таким образом, понятие «домен», «гипервизор» — это в каком-то смысле условности. Когда мы говорим «виртуальная машина работала 10 мс», мы на самом деле подразумеваем фразу «процессор исполнял код виртуальной машины 10 мс». Когда мы говорим «гипервизор вытеснил виртуальную машину», мы на самом деле подразумеваем «по прерыванию таймера процессор обновил счётчик времени, сохранил контекст процесса и передал управление в другое место, отличное от места, где его прервал таймер». Подобный перевод объекта (код) в субъект, обладающий способностью к действию, сильно упрощает объяснение — у каждой программы есть алгоритм поведения, и проще сказать, что «программа ведёт себя так-то», вместо того, чтобы говорить «процессор, исполняя программу, делает то-то и то-то».

Теперь немного о том, что сколько кушает. В начале статьи — график весьма нагруженного сервера, который держит на себе asterisk с звонками целой компании, веб-сервер, сбор статистики с машрутизаторов и т.д. Внизу — сайт с примерно 5000 уникальных посетителей в день. Это к вопросу о том, сильно ли используют процессор современные серверные приложения (циан на графиках — простаивающий процессор).
Теги:
Хабы:
Всего голосов 74: ↑67 и ↓7+60
Комментарии45

Публикации

Информация

Сайт
slc.tl
Дата регистрации
Дата основания
Численность
1 001–5 000 человек
Местоположение
Россия
Представитель
Влад Ефименко