Я описывал ранее типичное кодинг-интервью. Помимо кодинга почти всегда есть вопрос на проектирование систем. (Large) System Design. В случае собеседований на SRE, это еще более интересный (как по мне) зверь — NALSD. Non-abstract large system design. Главное отличие между SWE и SRE именно в этих буковках “NA”.

В чем же отличие, и как подготовиться к нему? Давайте разберём на примере. В качестве примера возьмём что-то весьма материальное, что-то такое, что точно никто никогда не спросит на реальном собеседовании (в гугл) :)

Например — давайте спроектируем библиотеку. Для бумажных книг, обычную такую. Весь текст ниже был написан в один присест за примерно час, чтобы примерно показать что можно успеть, и что важно успеть. Так что уж простите за сумбурность, но я так мыслю (а значит, так существую).

NALSD вопрос: Спроектируйте публичную библиотеку.


Сперва, интересуемся о характеристиках нагрузки, либо делаем разумное предположение сами. Раз уж это вопрос о масштабируемой системе, это минимум город миллионник. Стоит подумать о вариантах — одно большое здание, или районные библиотеки плюс хранилище. Как мне кажется, последнее разумнее. Особенно, если не город, а города.

Итак, сфокусируемся на текущий момент на системе одного города (с некоторыми оговорками, мы сможем применить аналогичный механизм уровнем выше для масштабирования на много городов). Итак, город миллионник. Округлим цифры для удобств прикидок — пусть будет 1млн вероятных читателей. Читатели собираются почитать в произвольный момент времени независимо друг от друга. Так что можем прикинуть как простой пуассоновский процесс. Но “на бегу” считать нормально будет сложно, так что сделаем еще один шаг упрощения и возьмём просто, что 1% читателей захотят взять книжку в день. Итого, для дальнейших расчетов примем 10000 взятий книжек в день.

Наша задача — обеспечить возможность выдачи 10000 книг в день (плюс возврата тех же 10000 в какой-либо другой день в будущем, кстати) в городе миллионнике. В этот момент вопрос моно-библиотеки или районных уже отпадает (кстати, чтоб весь миллион был потенциальными читателями, надо чтоб они могли добраться до библиотеки за разумное время, иначе желание взять книгу точно отвалится по таймауту). Итак, нам нужно оценить ёмкость каждой локальной библиотеки. Правильно это делать с учетом плотности населения и достижимости, но поскольку это не сильно влияет на саму систему, для простоты расчетов представим, что мы их размещаем равномерно. Но это всё равно не говорит о том, как мы можем их делить. Очевидно, что поставить 10000 библиотек с одной книгой равномерно по городу не имеет смысла, поэтому надо понять а что же имеет смысл. Уходим на уровень ниже.

Итак, одна библиотека. Чтобы она имела смысл, большая часть пришедших должна найти нужную им книгу. Это означает, что нам потребуется вести учет и прогноз самых популярных запросов и держать эти книги наготове. Затем, нам надо держать в принципе ассортимент. Навскидку, я бы сказал что локальная библиотека должна иметь не меньше 1000 наименований, самые топы из них во множестве экземпляров, топовых больше, хвостовых меньше. Средняя книжка в нашей библиотеке читается от 3 дней до 2 недель (на самом деле, характеристика зависит от книги, потребуется тут отдельный анализ), примем равным в неделе в среднем и двигаемся дальше. То есть взятая книга отсутствует примерно неделю, так что топовых книг надо с запасом на неделю (потом они начнут восстанавливаться от возвратов).

Примем средний коэффициент раздувания в 6. Так что ёмкость хранилища начинается от 6000 книг. Меньше означает что это только маленький топ, который всё равно может в некоторых случаях помочь (например, островок с “сумерками” в супермаркете возле детской игровой комнаты), но мы оставим пока это за пределами.

В “равновесном” состоянии, в день возвращают и берут примерно поровну, плюс-минус разброс, но нам нужна еще возможность принять повышенное число пиковое число возвратов (например, из-за внешней синхронизации типа отпусков или смены моды). Правильно — моделировать. Но здесь и сейчас прикинем как буфер в треть. Итого, поддерживаем 6000 книг доступных к выдаче, плюс место еще на 2000 про запас.

Итак, нам нужен юнит, способный хранить 8000 книг. Ежедневное пополнение очень дорого, значит это на неделю или две. Две недели, 6000 книг, с перекосом в возвратах это примерно на 300 в день. В момент открытия мы можем забить все 8000 книг, чтоб создать начальные 2000 в обороте до первых возвратов. 2000 за 3 дня = около 600 книг в день, плюс буфер = 800 книг в день.

Прикинем пропускную способность и ограничения хранилища. Одна книга занимает в среднем 2 сантиметра линейного пространства, 8000 книг — 160 метров. сворачиваем в 4 раза по вертикали, 40 метров. Разбиваем на ровные 5-метровые стеллажи, получаем 8 стеллажей по 4 полки 5 метров длиной. Один библиотекарь (или робо-библиотекарь) сможет работать с двумя стеллажами, извлечение одной книги потребует до 5 секунд дойти до неё, 5 секунд достать или поставить книгу, 5 секунд обратный ход, итого 15 секунд. 4 библиотекаря обеспечат нас приблизительно 15 книгами в минуту максимум, то есть 900 книг в час из хранилища приблизительно.

Добавляем время на обработку запроса (10с), поиск (5с), внесение в систему приема и выдачи(2с) => 400 книг в час. Значит хранилище в пике может выдавать-принимать 400 книг в час, следовательно 800 книг в день достижимы за 2 рабочих часа.

Теперь считаем другие характеристики: чтобы выдавать 400 книг в час 4 людьми, надо вместить 100 человек в зал ожидания в очередь перед окошком обработки, и чтобы эти люди не создавали толпы на входе-выходе. То есть входная группа должна пропускать 400 человек в час в обе стороны. Выходит, что главным ограничителем будет даже не хранилище, а емкость зала и входной группы.

Значит, можно будет найти оптимальное соотношение хранилища и зала при более точных расчетах.

Итак, с юнитом разобрались, возвращаемся на уровень выше. Мы прикиниули общую нагрузку на библиотеку примерно на 10000 книг в день, один юнит мы посчитали на 800 книг в день, то есть нам надо 12.5 юнитов. При геораспределении по городу, до каждого читателя будут достижимы один-два альтернативных юнита (на границах города) а то и 3-4 (внутри), что позволяет немного сглаживать пики трафика и/или повышенного спроса на конкретные позиции.

Так же мы знаем, что в любой момент любая библиотека может быть закрыта (пожар, сан.инспекция, покраска ручек холодильников или еще что), с ростом числа их, вероятность совпадения выпадения двух из жизни растёт, так что нам надо по запасному юниту на каждые 5-6 юнитов. Итого, 15 юнитов должны обеспечить требуемую производительность, при условии поддержания у них на складах расчетного запаса.

Для поддержания расчетного запаса, нам потребуется обновлять раз в неделю или две (мы выше считали что две) примерно пол-ассортимента для следования за тенденциями и проч. Значит, надо к каждому юниту подвоз и вывоз 4000 книг каждые две недели. При каждом завозе и вывозе, эти самые 4000 книг должны быть извлечены из хранилища и потом положены туда другие. При 400 книг в час, обновление ассортимента будет занимать 10 часов под максимальной нагрузкой. Что, вроде бы, всё еще не так плохо, опять же, при массовой загрузке многие вещи будут проходить быстрее, тем не менее, поддержание ассортимента занимает в 5 раз больше, чем работа с населением.

Средняя книга (2см*20см*30см) это примерно 1.5л, то есть 4000 книг = 6 кубометров. Легко влезет в одну газель. Вес кубометра бумаги 600кг, то есть 6 кубометров это 3.6 тонны. Грузоподъемность газели полторы тонны, так что потребуется три газели. Плюс одна резервная. У нас 15 юнитов, обновление раз в 2 недели, при равномерном распределении мы на пределе, придётся добавить еще газельку.

И это мы не успели продумать, куда и откуда эти газельки возят, так что на схеме появляются склады поставщиков и точки выгрузки потерявших актуальность книг…

Итак, время вышло. Что же такого ненормального в NALSD вопросе? Масштабируемость она обязана быть в любом Large System Design. Главное же — конкретность.

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

Как сейчас помню, на своём интервью при прикидках взял IOPS диска в 600, просто потому, что недавно оптимизировал и маялся с одним массивом, где _массив_ выдавал 600 IOPS… Собеседующий слегка удивлённо спросил меня тогда — 600 IOPS на диск? :D

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

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

Как SRE мы обязаны думать в терминах масштабирования реальных систем в условиях реальных ограничений реального железа. Вполне может существовать прекрасный алгоритм, разменивающий огромные временные затраты на небольшое количество памяти… Но всё равно петабайт оперативки на одно процессорное ядро пока еще не поставишь в реальных условиях. Так что если у нас есть петабайт оперативки, то у нас тысяч десять процессоров как минимум. Или двадцать. Или тридцать. И надо искать оптимум не глобальный, а здесь и сейчас, в данных условиях.

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

А теперь немного откиньтесь в своём кресле, расслабьтесь, и попытайтесь сконструировать систему поставки свежих куриных яиц по подписке.

Если есть желание поделиться с англоязычными коллегами, есть вариант на английском (а так же на англохабре).

Комментарии (8)


  1. Flip89
    14.01.2019 12:51
    +1

    Забавно, в пятницу как раз договорился на очное собеседование в гугл Цюрих, и тут сразу же наткнулся на это статью. Пишите еще :)


    1. datacompboy
      14.01.2019 13:05

      Удачи! Буду рад напоить кофе и послушать как все прошло


  1. Milfgard
    14.01.2019 14:50

    Если к этому добавить набор гипотез и экспериментов практической проверки чисел (без построения всей системы) — будет финмодель от бизнес-плана.


    1. datacompboy
      14.01.2019 14:56

      Практически, но это дао я еще не постиг.


  1. romangoward
    15.01.2019 18:06

    Как-то тихо в комментариях, к прошлой статье за день кучу насыпали :-}


    Лучше расскажите, как через терни к звёздам в SRE прорываются прикладные python/java разработчики с академическими знаниями в алгоритмах? И как с ними работать?
    US офисы страдают (по-крайней мере, они об этом пишу) от непрофильного найма и последующейго онбординга длинной в полгода-год.


    1. datacompboy Автор
      15.01.2019 22:03

      да и просмотров всего ничего — вероятно, народ всё еще в отпусках :)
      ну или нема неинтересная, раз уж не так широко нужная. или просто я что-то не то пишу.

      не знаю про US офисы ничего — меня там нет и не было, я не в теме :)

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


      1. romangoward
        16.01.2019 01:46
        +1

        ну или нема неинтересная, раз уж не так широко нужная. или просто я что-то не то пишу.

        Тема на самом деле скользкая, потому что если вы забыли, то совет ваших рекрутеров по подготовке к этому интервью — изучение соответствующей главы в "Cracking the coding interview".
        То есть, вы сами закладываете возможность пройти интервью с синтетическими знаниями. Плохого в этом ничего нет, но из этого вытекает занимательный артефакт: человека без релевантного опыта на интервью гоняют по синтетике, потому что он глубже не может, и в итоге он успешно решает верхнеуровневую задачу, а человека с реальным опытом, который первичную задачу решает быстно, начинают возить по деталям, которые он наизусть не помнит и не хочет помнить. Ну, дальше вы знаете: отсутствие softskills и щит-шторм постфактум в бложиках.


        Занимательно другое: все, кто хотели пройти интервью — прошли его с n-раза.


        Но вопрос то был не про это.
        Вы говорите про технический онбординг, а в us жалуются, что после всех компанейских тимбилдингов, тренингов и прочих митингов, люди не хотят принимать специфику конкретных команд и просят трансфер. И так целый год по кругу, пока тонкая творческая личность не найдет себя, ну или до performace review. (тут показания разделяются, но почти все говорят о том, что тех, кто ходит в офис, в первый год не увольняют). Но это про совсем клинических персон.


        В более общем же поле зрения — люди с математичекой базой, алгоритмами и одним GC языком.
        То есть: там ноль по сетям, ноль по кишкам, ноль по system design. И это беда-печаль в SRE.


        и это никак не связано с наймом, это специфика и уровень ответственности.

        Со стороны судить тяжело, но вот по SRE book и псто на medium создаётся впечатление, что Google работает по схеме, схожей с AWS, где есть сервисы со своим SLA, которые можно использовать для построения конечного продукта, — это простой и понятный подход с многоуровневой архитектурой, где явно разделены уровни ответственности, а сложности скрыты за реализацией API.


        Не очень-то и сложно, учитывая handbooks :-P


        1. datacompboy Автор
          16.01.2019 03:01

          Тема на самом деле скользкая, потому что если вы забыли, то совет ваших рекрутеров по подготовке к этому интервью — изучение соответствующей главы в «Cracking the coding interview».

          Я не забыл. Я не знал :) Мне ссылки какие-то для подготовки давали, я их мельком глянул, понятнее не стало, забил.

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

          Мы все еще про систем дизайн? Для SRE конкретность очень важна, и чисто высокоуровневое решение — только для невысокого уровня SRE :)

          засыпаться нельзя если просто забыл детали, это норма — подскажут. но и ошибаться на три порядка тоже не стоит. это тоже часть навыка. не уверен — спроси. делаешь предположение — уточни где взял и т.д.

          Ну, дальше вы знаете: отсутствие softskills и щит-шторм постфактум в бложиках.

          ну… ортогональные вещи. больше всего меня расстраивает отсутсвие полноценной обратной связи — именно на это больше всего жалуются те, с кем я разговаривал после собеседований. :( я понимаю почему так получается, но тем не менее — как по мне, это первичная причина шторма и обидок.

          Занимательно другое: все, кто хотели пройти интервью — прошли его с n-раза.

          это так кажется :) те кто прошли — научились. вопрос-то каждый раз разный…

          Вы говорите про технический онбординг, а в us жалуются, что после всех компанейских тимбилдингов, тренингов и прочих митингов, люди не хотят принимать специфику конкретных команд и просят трансфер.

          ничего не смогу сказать — я даже не слышал о таком.

          В более общем же поле зрения — люди с математичекой базой, алгоритмами и одним GC языком.
          То есть: там ноль по сетям, ноль по кишкам, ноль по system design. И это беда-печаль в SRE.


          SRE довольно большая организация, и место есть всем, кто умеет и хочет копать глубже в специфику. Если ноль сейчас — научится же, есть тех онбординг и команда поддержит. В конце концов, после универа сразу приходят люди — и весьма эффективны, и быстро растут. То есть опять же — извне это выглядеть может странно, но контроль есть, менеджеры работают, люди растут. Или уходят в SWE если им некомфортно. Свобода она такая :)

          есть сервисы со своим SLA, которые можно использовать для построения конечного продукта

          ага, вот вам кирпичи в четыре девятки, сложите из них «счастье» в 6 девяток.
          это не всегда тривиально, учитывая сколько зависимостей и дополнительных осложнений.
          плюс, коогда ты SRE и у тебя сыпется что-то: не всегда эффективно ждать кого-то, часто быстрее дебажить самому :) плюс, знание специфики часто помогает в интерпретации доступной дебаг информации.

          Не очень-то и сложно, учитывая handbooks :-P

          А мы покупаем или продаём? :D
          Так-то можно свести до «был релиз? откатить; не было? кластер в дрейн и там пусть разработчики думают». Вот только не всё и не всегда так просто.

          Короче — заходите на огонёк! Посмотрим как оно после реального ощупывания ;)
          Про вкус устриц, так сказать, надо не по напеву соседа судить.