Мы побеседовали с руководителем направления системного программирования в «Криптоните» Александром Авраменко о карьерном пути Rust-разработчика, особенностях языка Rust и его применении к моделям машинного обучения в высоконагруженных системах.
— Александр, расскажи о своём карьерном пути.
— Я учился в МАИ, получил диплом с отличием по специальности «бортовые системы». Всегда любил вычислительную технику и программирование. Уже в те времена был язык С, на котором я помогал писать пользовательские интерфейсы, заготовки для лабораторного САПРа и т.д.
Затем работал в ОКБ Сухого, делал ПО лётного тренажёра. В «живой» кабине с вмонтированными экранами подключался наш софт. Мы визуализировали облака, землю, аэродромы, рисовали карты, план полёта, индикаторы...
Потом я перешёл работать в блокчейн как в очень перспективную и технологически интересную область. Этот проект тоже был доведён до продакшена — мы запустили главную сеть. Как раз тогда, примерно в 2019 году, я обратил внимание, что некоторые новые блокчейны пишутся на языке Rust. Я им заинтересовался, изучил книгу и понял, насколько это интереснее, чем С++.
После этого в 2020 году поступило предложение от «Криптонита». Я принял его, так как мне как раз хотелось погрузиться в новый масштабный проект.
— Чем ты занимаешься в «Криптоните»?
— Я возглавляю группу системного программирования на Rust. Мы создаём сетевые сервисы и конвейеры обработки потоков больших данных с применением моделей машинного обучения (ML) в реальном времени.
Ранее Александр поделился с нами лайфхаками по управлению группой разработчиков: он рассказал о «подводных камнях» на собеседовании, мотивации команды и ситуации на рынке труда «растистов».
Это могут быть разные данные: картинки, видео- и аудиозаписи… любые файлы, которые наш пользователь хочет как-то обрабатывать. Обычно такие большие объёмы данных обрабатываются моделями машинного обучения. И здесь возникает технически сложная задача: написать такой софт, который, с одной стороны, обеспечит непрерывный поток входных данных, а с другой — подаст их на вход моделям. А ещё он будет накапливать результаты, которые эти модели формируют, складывать их в хранилище, систематизировать и делать это в режиме 24/7 в течение месяцев без перезагрузки.
— То есть должна быть сбалансированная система с буферизацией, классификацией, сортировкой данных…
— Да, и не в последнюю очередь — высокопроизводительная, потому что все эти этапы требуют больших вычислительных ресурсов. Если мы не будем использовать ресурсы эффективно, то сильно увеличим затраты на аппаратное обеспечение.
— Насколько представляю, основная задача здесь — быстрее освобождать память? Высоконагруженные системы страдают любовью «отжирать» её.
— Всё верно. Ещё, когда приступаешь к такой задаче, слегка обескураживает обилие процессорных ядер и вычислительных потоков, которые нужно балансировать динамически. Поток данных то увеличивается, то уменьшается, когда-то необходимо отправлять результаты на сохранение, поскольку они постоянно накапливаются. В зависимости от текущих потребностей необходимо перераспределять общие вычислительные ресурсы между внутренними заданиями. Эти и похожие частные задачи в комплексе решаются в нашем программном обеспечении. Однако, обработка потока данных в реальном времени — не единственное применение наших приложений.
Второй вид программ, которые мы создаём, — это сервисы. Например, получив от нашей лаборатории больших данных и статистики модель, мы обеспечиваем вокруг неё сервис, который отвечает на клиентские запросы. Например, они присылают нам записанный звук, а в ответ получают распознанную речь в виде текста. Таких клиентов могут быть десятки, сотни и тысячи одновременно. С распределением их запросов между разными экземплярами модели и возвратом результатов обработки, собственно, и справляется наш софт. То есть это мощный backend, балансирующий внешнюю нагрузку между доступными внутренними ресурсами.
— Сейчас вы используете для облачных вычислений графические процессоры?
— Конечно! В половине наших разработок приходится использовать CUDA-библиотеки, чтобы передавать пакеты подготовленных специальным образом данных для моделей и забирать оттуда результаты.
— Вы на OpenCL пробовали что-то делать?
— Сейчас мы работаем только с инфраструктурой Nvidia. В дальнейшем планируем диверсифицироваться по разным технологиям, включая OpenCL.
— Какими программами вы пользуетесь для совместной работы, какой стек технологий используете?
— Для совместной работы в компании используется GitLab — в разработке, Confluence — в более общих областях. Мы пользуемся общим инструментарием: так удобнее взаимодействовать с другими командами и руководством.
Технологический стек также определяется для отдела разработки в целом, с учётом общих задач: OpenShift, Kafka, Clickhouse, Scylla и т.д.
Что касается инструментов собственно разработки, то в Rust есть де-факто стандарт: cargo + rust-analyzer + некоторый выбор IDE, например, VSCode, IntelliJ, CLion, Neovim, Emacs.
— Что ещё должен знать Rust-разработчик для эффективной работы над реальными проектами?
— Мы создаём довольно сложный софт, работающий в условиях:
высоких нагрузок по потоку данных;
недопустимости потерь при обработке данных;
длительной работы во времени, месяцами без перезапуска;
использования всех доступных вычислительных мощностей;
задействования и обмена данными с GPU;
отсутствия интерфейса пользователя.
Поэтому мы используем проверенные временем сторонние решения отдельных задач, например, для буферизации данных, хранения результатов, мониторинга состояния.
С нашими сервисами взаимодействует другой софт на общей платформе, поэтому нужно понимание принципов и технологий такого взаимодействия.
Чем шире у разработчика знания в использовании принятого у нас технологического стека, тем более эффективно он работает.
С точки зрения программирования, помимо знания самого языка, создание качественного софта требует навыков профилировки и написания бенчмарков, опыта в использовании CI, развёртывания в Openshift, работы с докером и пр.
— Почему твой выбор пал на Rust? Каковы особенности разработки на этом языке?
— Я пропагандирую коллегам переход на Rust:)
он превосходит С++ по выразительности: код с одинаковой функциональностью в разы короче на Rust;
не уступает C++ по производительности итогового приложения;
компилятор даёт существенные гарантии надёжности кода и безопасности работы с памятью, одной из основных проблем в системном и серверном софте;
цикл разработки существенно короче (написать код — примерно 80% готовности, оставшиеся 20% — отладка приложения, как правило, логики);
огромное количество библиотек и фреймворков для любых областей написано на Rust;
совместим с наследием на С++.
— Какие языки программирования являются лучшей базой для перехода на Rust?
— Компилируемые языки без среды исполнения и механизмов сборки мусора с поддержкой шаблонного программирования и полиморфизма. Получается, это С++.
— У тебя в команде все бывшие «сишники»?
— Нет, не все. Есть те, кто писал на Go, Haskell и Java.
Почему «Rust – не Си на стероидах» читайте в интервью с ведущим системным программистом департамента разработки компании «Криптонит» Михаилом Дорониным.
— То есть с Haskell вполне можно перейти на Rust?
— Да. На самом деле Rust не Си-подобный. Когда вижу конструкции на Scala/Haskell или программу на Go, мне кажется, что команда, которая проектировала Rust, старалась взять лучшее из разных языков. Соответственно, программист, знающий Scala, Haskell или Go, увидит что-то близкое, понятное ему. Но программисту с опытом работы на С++ меньше других придётся подстраиваться под ограничения, которые другим на начальном этапе кажутся непривычными.
В общем, на Rust можно перейти хоть с C#. Но надо понимать, что меняется концепция: отсутствует среда исполнения, автоматическое управление памятью. И тебе придётся заботиться о том, о чём ты заботиться не привык.
— Думать, как код внутри исполняется?
— Да. И понимать, к чему каждая твоя строчка кода приводит на машинном уровне.
— То есть отвыкать от мысли, что компилятор всю внутреннюю кухню сделает за тебя.
— На других языках — да. А для разработчика на С++, наоборот. Компилятор какие-то вещи, о которых ты раньше должен был думать сам, берёт на себя и запрещает тебе сделать то, что потенциально может привести к созданию ненадёжной или аварийной программы.
— Как началось твоё знакомство с Rust?
— С книги «Программирование на языке Rust». Мы её называли «книга с крабиком» :) Она вышла в издательстве O'Reilly, была переведена у нас, и, по-моему, была такая первая и единственная. Удачной эта книга была потому, что её авторы как будто, также, как и я, до Rust работали на C++. Их аналогии и поясняющие примеры построены на сравнении этих языков. Разработчику на С++ она очень подходит.
— Ты учился только по книге?
— Да. Мне сперва надо понять правила игры, а потом их на чём-то попробовать. На проекте по выпуску блокчейна я написал наше программное обеспечение на Rust, и в процессе самостоятельно проходил все привычные для программиста пути: и пользовался советами Stack Overflow, и возвращался к учебнику, и смотрел каталоги библиотек, которые есть на Rust, и экспериментировал. Но, чтобы никого не напугать, напоминаю, что есть и обучающие курсы.
— Поделись полезными материалами и ресурсами для Rust-разработчиков.
— Могу рекомендовать серию видео с погружением в отдельные темы от Jon Gjengset https://www.youtube.com/@jonhoo. В них вполне понятный английский, глубокий уровень погружения в выбранную тему и увлекательный стиль изложения.
Есть ещё интересный ресурс https://cheats.rs. Этот ресурс больше всего похож на удобный набор «шпаргалок» по Rust, очень наглядных, с полезными советами и готовыми примерами.
P.S. Дополнительные полезные материалы смотрите также в нашем полном обзоре языка программирования Rust. В статье рассказываем о его особенностях, применении, плюсах и минусах.
Комментарии (15)
igumnov
29.08.2023 08:43+5Спасибо за статью! Отдельное спасибо за ссылку на Читы по Rust! Раньше не попадался такой сайт хороший где собрано все в одном месте! Есть еще сайт на котором все шаблоны проектирования с примерами кодов на основных языках программирования и в том числе на Rust. Рекомендую!
syrus_the_virus
29.08.2023 08:43+2Работал человек в авиации, перешёл в блокчейн, топит нам за преимущества rust над с++ - после первого пункта уже можно не читать.
khv2online
по выразительности руст сосет по всем фронтам. По статистике код на русте в среднем не "в разы короче" а на 30% длиннее чем c++
руст уступает по производительности cpp примерно на 5-20% (что gcc, что clang)
компилятор руста не дает никаких гарантий, от слова "совсем"
бред, на русте пилить дольше даже "хелловорд", про большие системы с сотнями классов - ну там руст вообще как-бы забуксует вплоть до полной стагнации проекта.
Для c++ написано в разы больше всего
Точно также как c++ совместим со всем что написано на русте.
gekh
Конечно забуксует, ведь в расте нет классов )
А так конечно совсем неубедительно. Перейти с раста на плюсы? Хмм, таких людей я еще не встречал.
KanuTaH
Это просто показатель вашего кругозора. Вот я, например, могу писать на Rust. Но я много на чем могу писать - за последний год я писал... дай бог памяти... на C, C++, Java, JavaScript, Python, Tcl (у MacPorts на нем скрипты, и вообще это моя первая любовь из всех скриптовых языков которые я знаю), на Pascal (да-да, на нем родимом, у Inno Setup используется Object Pascal как scripting language), наверняка еще что-то забыл, ну всякие там разнообразные шеллы и повершеллы даже считать не будем. А на Rust - нет. Почему? Да потому что всегда находилась более удобная для меня/производительная/переносимая/быстрая в плане скорости разработки/etc альтернатива. Вот как-то так. Можно ли сказать, что я "перешел с раста", скажем, на те же плюсы? Фактически да :)
DarkEld3r
Не согласен. Любой разработчик с достаточным опытом (при отсутствии зашоренности) неизбежно пощупает кучу языков и технологий. Если я прочитал несколько книг по хаскелю и худо-бедно могу на нём что-то писать, но не делаю этого, не значит, что я "перешёл с хаскеля". Не нашёл применения или предпочитаю другие языки — да. Аналогично, если я стараюсь по возможности избегать динамически типизированных языков, это не значит, что я перешёл, скажем, с питона.
Gordon01
Почему вы так не любите роботов?
hrls
Пожалуйста, не нужно только про выразительность C++. При всем уважении, но с каждым годом код на плюсах все больше похож заклинание, которое никто, кроме его автора, прочитать не в силах.
ReadOnlySadUser
Может у меня когнитивное искажение, т.к. на плюсах я уже лет 10 пишу, но как по мне код на современных стандартах - это просто детская сказочка, на фоне того, что было раньше.
С появлением constexpr/consteval, structured bindings и fold expressions большая часть страшной магии под именем SFINAE просто стала не нужна.
Появилась новая магия - концепты, но она нужна не так, чтобы очень много кому.
В остальном, прикладной код на С++ на мой взгляд похож на внебрачного страшного сына С# и Rust
При этом код на Rust - очень часто вообще нечитабелен из-за переизбытка Rc/Box и времён жизни
AnthonyMikh
Очень странное заявление. Rc — это потоконебезопасный счётчик ссылок. У него есть свои области применения, но всё же он обладает меньшей универсальностью, чем Arc — атомарный счётчик ссылок. Arc используется в реальных программах куда чаще.
Ну а Box — это аналог std::unique_ptr, который используется примерно тогда же, когда unique_ptr используется в C++. И что-то мне подсказывает, что про код на C++ вы не скажете "переизбыток уникальных указателей".
hugga
Ну вот, человек!
Про статистику и производительность в точку. Тоже вот так думаю.
Компилятор гарантий не даёт - ни прибавить ни отнять.
Пробуксовка в больших проектах это вообще, да.
Сказал - как песню спел!
Внемлите этим глаголам. Видно, человек толковый пишет.
AnthonyMikh
Столько громких заявлений — и ни одного аргумента, кроме ятаксказал