Переписал сервис на Rust и не жалею: где выгода, а где боль

ArtyomBelov

New member
Начну с контекста. Три года назад я был техлидом в команде, которая держала на плечах монолит на Python: обычный веб, API, фоновые задачи. Всё работало, тесты были, релизы шли раз в неделю. Но на графиках задержек регулярно всплывали пики под триста миллисекунд, и это при том, что запросов в секунду было не так уж и много. Тогда мы всей командой честно спросили себя: это язык виноват или мы сами? Спойлер: виноваты были отчасти мы, но частично и язык тоже.

Сначала мы сделали то, что многие пропускают: профилирование. Оказалось, что основное время уходит в один узкий участок: парсинг и валидация входящих данных плюс проверка подписи. Менеджер памяти и глобальная блокировка интерпретатора добавляли свою порцию дрожи, но главной проблемой был не сам язык, а неудачно спроектированное горячее место, которое мы дёргали в цикле. Отсюда вывод номер один: если вы не знаете, где именно у вас узкое место, смена языка вам не поможет. Ни Rust, ни Go, ни что угодно ещё.

Мы не стали переписывать всё, и это решение я до сих пор считаю самым правильным. На Rust ушёл один сервис, тот самый горячий путь обработки, а остальные части монолита спокойно остались на Python. Связь между ними построили через очереди и обычный сетевой вызов. Получился классический приём, когда новое приложение постепенно окружает старое и со временем вытесняет его кусками, а не одним героическим коммитом.

Что реально изменилось: хвостовая задержка упала примерно в семь раз, потребление памяти в четыре, а количество машин под этим сервисом сократилось с шести до двух. Звучит как рекламный буклет, поэтому добавлю ложку дёгтя. Первый релиз занял в три раза больше времени, чем мы оценивали. Правила владения и времена жизни поначалу отнимали нервы. Мы дважды переделывали архитектуру, потому что решение, элегантное на скриптовом языке, на Rust превращалось в борьбу с компилятором. И наняли мы в итоге одного человека, который действительно умеет писать на Rust в бою, остальные учились по ходу. Это дорого, и это надо считать заранее.

Теперь про то, когда переписывать не стоит. Если у вас обычный сервис с созданием и чтением записей, а узкое место в базе данных, Rust вас не спасёт. Если команда из трёх человек и дедлайн через два месяца, не начинайте. Если проблема в забытом индексе, в лишних запросах на страницу или в том, что вы ходите в базу сто раз за один рендер, лечите это, а не язык. И если требования меняются каждую неделю, гибкий динамический язык даст больше скорости итераций, чем строгий компилятор, который заставит вас переписывать модели данных по три раза.

Мой личный список критериев, которым я пользуюсь сейчас, выглядит так. Во-первых, есть честный профиль, показывающий, что время реально уходит в процессор, а не в сеть и диск. Во-вторых, этот код будет жить годами и его будут поддерживать. В-третьих, есть жёсткие требования к задержке или к памяти, либо вы платите за облако ощутимые деньги и экономия на машинах окупает разработку. В-четвёртых, в команде есть хотя бы один человек с боевым опытом на Rust или бюджет на обучение. Если не выполняется хотя бы один пункт, я сначала выжимаю то, что уже есть, и только потом думаю про переезд.

По методам советую три вещи. Не переписывайте с нуля, оборачивайте старое новым по частям и начинайте с самого горячего модуля. Обязательно измеряйте эффект после каждого шага, иначе вы не отличите реальный выигрыш от эффекта плацебо. И держите путь назад открытым: фича флаг, теневой трафик, параллельный прогон на одинаковых данных. Так вы в любой момент можете откатиться, не роняя прод, и это спокойствие стоит дороже, чем кажется.

При этом о нашем решении я не жалею ни минуты. Rust в продакшене даёт то, что обещают: предсказуемую задержку, отсутствие сюрпризов от сборщика мусора, экономию ресурсов и, что стало для меня приятной неожиданностью, спокойные дежурства. Ошибки типов и владения компилятор ловит днём, на ноутбуке разработчика, а не ночью в три часа, когда упал прод. Но это не бесплатно, и платить приходится сроками, людьми и дисциплиной. Переписывать стоит тогда, когда цена бездействия выше цены переписывания, а не тогда, когда на конференции было красивое выступление. Посчитайте деньги за месяц, посмотрите профиль, поговорите с людьми, а не с хайпом. А теперь скажите честно: был ли у вас опыт переезда на Rust и что он вам дал? Очень интересно почитать истории, где всё пошло не по плану и всё равно привело к хорошему результату.
 
Назад
Вверх