Не спор, а арифметика
Спор о том, что дешевле — свой сервер или облако, — обычно ведут в жанре мнений. У вопроса есть и другой жанр: арифметика. Нагрузка у вас известна, цены известны, остаётся подставить. Мы уже спорили о том, когда локальный инференс дешевле облака; здесь отдаём то, чего спору не хватало, — модель расчёта. Без единого готового числа, и это не кокетство: у вас своя нагрузка и свой тариф на электричество, чужая таблица этого не знает. Переменные — наши, значения — ваши.
Тупик: окупаемость через одно деление
Первое, что пробуют почти все: цену карты делят на месячный счёт за облако и получают срок окупаемости. Расчёт выглядит честным — это же деление, а не ощущение, — и именно поэтому он выживает на планёрках и убивает разговор раньше, чем тот начнётся.
А не работает он по нескольким причинам, каждая из которых способна перевернуть результат.
Деление молча предполагает, что карта загружена круглосуточно. У железа нет почасовой тарификации: оно стоит одинаково и когда считает, и когда ждёт. Если трафик живёт только рабочими часами, полезных часов в месяце будет ровно во столько раз меньше, во сколько рабочий день короче суток, — и «окупаемость» уедет туда, откуда приехала.
Дальше: память не покупается долями. Нужный объём складывается из весов модели, кэша на каждый одновременный запрос и служебного запаса, а карты идут поштучно. Округление вверх способно добавить к смете целый сервер, которого деление не увидело.
К тому же облачный счёт уже содержит электричество, охлаждение, замену умершего железа и чужого дежурного. В цене вашей карты всего этого нет — придётся докупать и вписывать в тот же столбец, иначе вы сравниваете нетто с брутто.
И наконец, деление сравнивает вашу идеальную эксплуатацию с чужим прайсом. Облачная сторона торгуется: за ровную базу даёт цену ниже прайсовой, за рваные пики берёт выше средней. Сравнивать надо то, что вы реально заплатите, с тем, что реально потратите.
Хуже того, результат льстит той стороне, в которую вы и так верили: целое деление выглядит как доказательство и подтверждает любую позицию.
Итог: число из деления — не ответ, а две выдумки, поделённые друг на друга. Хорошая новость в том, что честная модель не сильно сложнее.
Модель расчёта: пять строк
Считайте построчно: каждая строка берёт значения из предыдущей.
-
Профиль нагрузки. Средняя и пиковая скорость запросов — за день и за неделю отдельно — плюс лимит времени ответа. Лимит нужен вот зачем: он ограничивает, сколько запросов можно копить в один батч, потому что пользователь не будет ждать дольше этого лимита. И запомните отношение пика к среднему — главная переменная всей статьи: она скажет, сколько времени железо будет ждать работы.
-
Память и число карт. Нужный объём — это веса модели плюс кэш на один запрос, умноженный на число одновременных запросов, плюс служебный запас. Одновременные запросы = пиковая скорость × время ответа: пока запрос считается, он держит свою порцию памяти, и это арифметика, а не мнение. Число карт = нужный объём ÷ память одной карты, с округлением вверх. Число карт задаёт именно пик — железо не растягивается под нагрузку, как облачный автоскейл. Если простой недопустим — ещё одна карта сверх расчёта, холодная, на полке.
-
Деньги в месяц. Цена всего комплекта ÷ срок, на который вы готовы её списывать. Срок — не срок жизни железа, а срок вашей ставки на то, что нагрузка не изменится; гарантия на карту — разумная точка отсчёта, дальше вы рискуете уже сами. Дальше плюсуйте электричество: мощность под нагрузкой × часы под нагрузкой + мощность в простое × часы простоя, всё × ваш тариф за киловатт-час. Да, в простое тоже течёт — карта не выключается от скуки. Плюс размещение, доля инженера на эксплуатацию и резерв на ремонт: карты умирают, и не по расписанию.
-
Полезные часы. Это часы, когда карты реально считают ваш трафик, а не греют воздух в его ожидании. Стоимость полезного часа = все расходы месяца ÷ полезные часы. Вот эту строку — и только её — сравнивайте с облачной ценой часа.
-
Облачная сторона. Не прайс, а то, что заплатите именно вы: ровная база — по цене с обязательством, пики — по факту. Прежде чем сравнивать, выжмите из облачного счёта всё, что он готов отдать: обязательства, резервации, скидки за объём. Сравнивать надо с оптимизированным облаком, иначе вы посчитаете экономию против счёта, который сам себя не уважает. И учтите: в облачной цене уже сидят резерв, замена и дежурный, которые у вас разложены по строкам выше.
Когда таблица заполнена, решение держится на двух отношениях. Утилизация — полезные часы ÷ календарные — говорит, работает железо или стоит. Горизонт — на сколько месяцев вперёд вы готовы зафиксировать нагрузку — говорит, успеет ли амортизация состояться.
Из тех же строк выводится порог — точка безубыточности. Собственная стоимость полезного часа падает с каждым полезным часом: месячная сумма почти фиксирована, делитель растёт. Облачная плата от вашей утилизации не зависит вовсе. Значит, порог — это то число полезных часов в месяце, при котором обе стороны сравнялись. Выведите его один раз — и дальше любой месяц проверяется одним взглядом на утилизацию, без пересчёта всей таблицы.
И отдельная строка риска, о которой забывают чаще всего: как часто вы меняете модель. Железо привязано к объёму. Новая модель может не влезть в купленные карты, и «своё железо» станет «старым железом»; облако под новую модель перевыпускается усилием конфига, ваша стойка — нет.
Три сценария
Ровный поток
Продукт с предсказуемым трафиком: пик близок к среднему, утилизация высокая по построению. Знаменатель в стоимости полезного часа почти не усох, и своё железо здесь выигрывает у облачной цены часа само по себе: в облачной цене сидит премия за эластичность, которую ровный трафик не использует. Решающая переменная — горизонт. Если нагрузка переживёт выбранный срок списывания, берите своё, а облако держите под рукой — не ради пиков, а как парашют на случай, когда карта умрёт в час наибольшей нагрузки. И следите за строкой риска: длинный горизонт — это ещё и ставка на то, что модель не поменяется.
Пики и простои
Сервис живёт рабочими часами, или трафик рвётся по кампаниям и сезонам. Число карт по-прежнему задаёт пик — память не станет меньше оттого, что ночью пусто, — а вот полезные часы усохнут, и стоимость часа поползёт вверх. Два честных хода. Первый — поднять утилизацию ночными батчами и фоновыми перерасчётами, всем, что готово ждать до утра. Второй — признать гибрид: своё под базу, облако под всё, что выше. Решающая переменная — доля полезных часов. Чем резче пик, тем выше порог из модели — и тем короче список конфигураций, где чистое железо вообще успевает окупиться. Если после всех ухищрений утилизация до порога не дотягивает, геройствовать не надо: гибрид — это не половинчатость, а прямой ответ арифметики.
Разовая нагрузка
Пилот, переезд, разовая обработка под дедлайн. Горизонт короче любого вменяемого срока списывания: покупка оплачивает всю жизнь железа ради короткого куска его работы. Плюс срок поставки — сам по себе аргумент: измерьте его у своего поставщика и встройте в дедлайн, прежде чем верить любому расчёту. Арифметика почти при любых ценах на стороне облака. Пересчитывайте, только если пилот дожил до продакшна: тогда нагрузка — уже не прогноз, а факт, и вторая итерация расчёта выйдет честнее первой.
Позиция редакции
Мы считаем, что сам вопрос «железо или облако» поставлен неудачно. Это не выбор технологии, а сделка: железо — ставка на то, что нагрузка не изменится ни по объёму, ни по модели до конца амортизации; облако — плата за право передумать завтра. Поэтому решение вытекает не из цен, а из двух переменных вашей таблицы — утилизации и горизонта. Высокая утилизация при длинном горизонте — берите своё, хотя бы как базу, с облаком на пиках и на отказах. Короткий горизонт или рваный профиль — облако или гибрид, и это не «золотая середина», а вывод из формулы.
Отдельный случай, где расчёт не нужен вовсе: данные нельзя отдавать за периметр. Там железо выбирают не бухгалтерией, и наша модель не применяется.
И наша позиция неверна при одном условии: если строка «люди» в вашей таблице сравнима со строкой «железо». Эксплуатация собственной инференс-платформы — дежурства, обновления, разбор отказов — ест рабочие часы инженеров, и если эти часы в сумме приближаются к амортизации, решает не утилизация и не горизонт, а штат. Тогда управляемый облачный сервис выигрывает даже при ровной круглосуточной нагрузке — и наш расчёт это честно покажет, если вы заполните строку про людей, а не только про карты.