Одним из самых важных событий в карьере автора статьи стало то, что его руководителем оказался Kellan. Автор проработал под его началом достаточно долго, чтобы увидеть, как технические решения Kellan начинают приносить плоды. Из этого опыта было извлечено много уроков — как в процессе наблюдения, так и в качестве результата этих решений. Свободу стать инженером, написавшим Data Driven Products Now!, автор бы не получил, если бы Kellan не так уверенно приземлял выбор технологий.
За год после ухода из Etsy вновь пробудился интерес к технологиям. Мысли выкристаллизовались в форму, которую можно изложить связно. Ниже — дистилляция подхода Kellan, которая, надеюсь, слегка его смутит, но не более того.
Принимай скуку.
Представим, что у каждой компании есть примерно три «токена инноваций». Их можно потратить на что угодно, но запас надолго остаётся фиксированным. Возможно, появится ещё немного токенов после достижения определённого уровня стабильности и зрелости, но обычно люди переоценивают содержимое своего кошелька. Модель, конечно, приблизительная, но она помогает думать.
Если сайт написан на NodeJS — потрачен один токен. Если выбрана MongoDB — потрачен ещё один. Если используется технология service discovery, существующая меньше года — потрачен третий. А если написана собственная база данных — тут дела совсем плохи.
Любой из этих выборов может быть оправдан, если компания — консалтинг по javascript или разработчик баз данных. Но скорее всего, это не так. Скорее всего, компания хотя бы формально занимается тем, что переосмысливает мировую торговлю или заново изобретает платежи в вебе, либо преследует какую-то другую эпическую миссию. В таком контексте тратить ограниченное внимание на изобретение нового ssh — отличный способ провалиться. Или, в лучшем случае, отложить успех [1].
Что считается скучным? Тут не всё так просто. «Скучное» не равно «плохому». Есть технологии, которые скучны и при этом плохи [2]. Их использовать не стоит. Но есть множество вариантов, которые скучны и хороши — или, как минимум, достаточно хороши. MySQL — скучен. Postgres — скучен. PHP — скучен. Python — скучен. Memcached — скучен. Squid — скучен. Cron — скучен.
Приятная особенность скучности (в таком понимании) в том, что возможности этих технологий хорошо изучены. Но важнее другое: их сценарии отказов хорошо изучены. Всем, кто хорошо знает автора, понятно, что призывать призрак Дона Рамсфелда приходится с огромным чувством внутреннего отвращения, но иначе не обойтись.
При выборе технологии есть как известные неизвестные, так и неизвестные неизвестные [3].
- Известное неизвестное — это что-то вроде: мы не знаем, что произойдёт, когда эта база данных упрётся в 100% загрузки CPU.
- Неизвестное неизвестное — это что-то вроде: оказывается, нам даже в голову не приходило, что запись статистики вызовет паузы сборщика мусора.
Оба множества обычно непусты, даже для технологий, существующих десятилетиями. Но для новых блестящих технологий масштаб неизвестных неизвестных значительно больше, и это важно.
Оптимизируй глобально.
Смещение в пользу скучных технологий без извинений считается хорошей идеей, но это не единственный фактор, который стоит учитывать. Выбор технологий не происходит в изоляции. У него есть область влияния, затрагивающая всю команду, всю организацию и систему, которая складывается из суммы всех принятых решений.
Добавление технологии в компанию имеет свою цену. В абстрактном виде это очевидно: если уже используется Ruby, добавление Python в стек кажется бессмысленным, потому что возникающая сложность превысит маргинальную пользу от Python. Но почему-то, когда речь заходит о Python и Scala или MySQL и Redis, люди теряют голову, отбрасывают все ограничения и начинают восторженно говорить о выборе лучшего инструмента для задачи.
Функция инженера в двух словах — отображать бизнес-задачи на пространство решений, состоящее из вариантов программного обеспечения. Если бы выбор программного обеспечения действительно не имел издержек, можно было бы подобрать целый набор локально лучших инструментов для набора задач.
Но издержки, конечно, существуют. Их называют «операционной нагрузкой» и, в меньшей степени, «когнитивной нагрузкой». Технологию нужно мониторить. Нужно разобраться с юнит-тестами. Нужно знать хотя бы основы, чтобы с ней работать. Нужен init-скрипт. Список можно продолжать бесконечно, и всё это быстро накапливается.
Проблема мышления «лучший инструмент для задачи» в том, что оно узко трактует слова «лучший» и «задача». Задача инженера — удерживать компанию на плаву, чёрт возьми. А «лучший» инструмент — тот, который занимает позицию «наименее плохого» для максимально возможного числа задач одновременно.
Практически всегда долгосрочные затраты на поддержание работоспособности системы значительно превышают любые неудобства, возникающие при её создании. Зрелые и продуктивные разработчики это понимают.
Иногда выбирай новые технологии.
Доведя эту логику до reductio ad absurdum, можно прийти к выбору Java и попытке реализовать сайт, вообще не используя ничего другого. Это было бы безумием. Нужен какой-то механизм для добавления новых инструментов в арсенал.
Важный первый шаг — признать, что это процесс и разговор. Новая технология в итоге затрагивает всю компанию, поэтому её добавление требует прозрачности на уровне всей организации. Специфика конкретной компании может вынуждать вести такой разговор, а может, наоборот, позволять разработчикам добавлять новые базы данных и очереди, ни с кем не советуясь. В любом случае нужно сформировать культурное ожидание: это то, что мы обсуждаем все вместе.
Одно из самых полезных упражнений — подумать, как решить текущую задачу, не добавляя ничего нового. Прежде всего, сама постановка этого вопроса помогает выявить ситуацию, когда «проблема» на самом деле — это то, что кто-то просто очень хочет использовать конкретную технологию. Если это так, процесс нужно сразу прервать.
Удивительно, как далеко можно уйти с небольшим набором технологий. Ответ на этот вопрос на практике почти никогда не звучит как «мы не можем это сделать» — обычно это что-то в диапазоне «ну, мы могли бы это сделать, но это было бы слишком сложно» [4]. Если кажется, что цели недостижимы с текущим стеком, скорее всего, просто не хватает креативности в размышлениях.
Полезно записать конкретно, что именно в текущем стеке делает решение задачи непозволительно дорогим и сложным. Это связано с предыдущим упражнением, но немного отличается.
Выбор новой технологии может быть чисто дополняющим (например: «у нас пока нет кэширования, добавим memcached»). Но он может и перекрывать, и заменять то, что уже используется. В этом случае нужно чётко обозначить ожидания по миграции старого функционала на новую систему. Обычно политика должна звучать как «мы обязуемся мигрировать» с предложенными сроками. Цель этого шага — держать масштаб разрушений под контролем и не допускать распространения локально-оптимальных решений.
Этот процесс не пугающий и не требует больших усилий. Это несколько вопросов, на которые нужно ответить как домашнее задание, плюс встреча для обсуждения. Если новая технология (или новый сервис, который предстоит развернуть на инфраструктуре) проходит через это испытание без потерь, добавлять её вполне допустимо.
Просто выпускай продукт.
Полиглотное программирование продаётся с обещанием, что предоставление разработчикам полной свободы выбора инструментов сделает их эффективнее в решении задач. В лучшем случае это наивное определение задач, в худшем — мотивированное рассуждение. Вес ежедневной операционной рутины, которую это создаёт, буквально раздавливает команду.
Осознанный выбор технологий даёт инженерным умам настоящую свободу — свободу размышлять над более крупными вопросами. Технология ради технологии — это змеиное масло.
Обновление от 27 июля 2015 года: на основе этой статьи был подготовлен доклад. Посмотреть его можно здесь.
- Etsy в первые годы серьёзно страдала от этой проблемы. Была нанята группа Python-разработчиков, и компания решила, что нужно найти для них применение на Python — единственное, что пришло в голову, было создание бессмысленного промежуточного слоя, на ампутацию которого потребовались годы усилий. Тем временем 90-й процентиль задержки поиска составлял около двух минут. Etsy не провалилась, но несколько лет вообще ничего не выпускала. Так что путь к успеху занял больше времени, чем требовалось.
- Пересечение скучного и плохого часто в шутку называют «энтерпрайз-софтом», но эта терминология может быть неточной.
- Говоря так, Рамсфелд, намеренно или нет, отсылал к сократовскому парадоксу. Сократ, по всем свидетельствам, был вдумчивым человеком во многих отношениях, в которых Рамсфелд таковым не являлся.
-
Хороший пример из практики автора — лента активности Etsy. При создании этой функции компания активно консолидировала большую часть Etsy на PHP, MySQL, Memcached и Gearman (джоб-сервер на PHP). Реализовать эту функцию на таком стеке было гораздо сложнее, чем могло бы быть с чем-то вроде Redis (или может, и нет). Но построить ленту активности на этом стеке было вполне возможно.
С этим проектом произошла удивительная вещь: внимание команды переключилось на другие задачи на несколько лет. За это время лента активности выросла в масштабе в 20 раз, и за ней никто вообще не следил. Никаких изменений, специально нацеленных на ленту активности, не вносилось, но всё работало прекрасно, несмотря на взрывной рост нагрузки — потому что использовалась общая платформа. В этом и заключается долгосрочная выгода сдержанности в выборе технологий.
Это не абсолютистская позиция — если хранение ленты активности в memcached было признано практичным, то реализация полнотекстового поиска с фасетами на чистом PHP — нет. Поэтому Etsy использовала Solr.