Как стать автором
Обновить

Как проходят архитектурные секции собеседования в Яндексе: практика дизайна распределённых систем

Блог компании ЯндексВысокая производительностьАнализ и проектирование системПромышленное программированиеРаспределённые системы
Всего голосов 94: ↑92 и ↓2+90
Просмотры28K
Комментарии 33

Комментарии 33

Здесь нет ничего сложного — поскольку в этой части системы ожидаются единицы

Нет ничего сложного и затем текста в пол )

Спасибо за статью

:) Тут я хотел сказать что в данной подсистеме нет ничего необычного — про устройство систем такого класса уже есть 100500 статей.

Просто восхитительно. Отдельное спасибо за ресурсы в конце статьи!

Отличная статья, системно затрагивает целый комплекс вопросов. Прочитал с удовольствием и даже с некоторым азартом.


Позволю себе высказать несколько замечаний.


А какую конкретно базу данных выбрать, если вам достаточно KVS? Aerospike? Redis? Couchbase? Memcached? Может быть, вам нужно рассмотреть еще и HBase в этом классе?

Из популярного я бы добавил Cassandra, Scylla, FoundationDB, Tarantool. Последний так вообще, судя по публикациям, создан для таких задач.


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

Замечу, что далее в статье идет список требований типа:


  • Объем переходов по ссылкам?
  • Используем протокол HTTP или HTTPS?
  • Требования на согласованность данных?

каковые являются Non-functional requirements.


Hitachi Solutions высказывает даже такое мнение, что: "The Architect focuses on non-functional requirements".


— Каковы требования к отказоустойчивости?
— Четыре девятки на чтение.

"Четыре девятки" относятся к доступности (availability). Отказоустойчивость (fault tolerance) — это про способность системы свойство технической системы сохранять свою работоспособность после отказа одной или нескольких её составных частей.


  • Порядок нагрузки на изменение данных в СУБД предполагается достаточно небольшой (порядка 1-2 RPS), чтобы с этим мог справиться один сервер, а вот нагрузка на чтение будет настолько высокой, что будет заведомо превосходить возможности одного сервера.
  • Предлагается дополнить контур для чтения данных проксирующим KV-хранилищем, способным быстро обрабатывать большое количество запросов преимущественно из памяти.
  • Для самой базы потребуется достаточно много дискового места и порядка десяти CPU на обслуживание запросов — здесь доминантным ресурсом будет дисковое пространство, такой инстанс скорее всего займет полноценный сервер. Считаем, что выбранное нами managed-решение для СУБД имеет встроенные механизмы по автоматическому переключению primary-инстанса на основе алгоритмов распределенного консенсуса
  • Поэтому нам потребуется три таких сервера для отказоустойчивости.
  • Данные должны быть строго согласованы для новых ссылок; при модификации существующих ссылок допускается чтение неактуальных данных в течение нескольких секунд после обновления.

Если взять шесть серверов по 10 процессоров в каждом можно попытаться напрямую взять планочку 500.000 RPS на БД типа Scylla или Tarantool. Тут многое еще зависит от того, сколько RAM можно использовать.


Можно взять 12 серверов по 10 процессоров, тогда планочка точно возьмется. При этом вся система существенно упростится.


Здесь можно упростить решение — коммитить транзакцию в основную СУБД после подтверждения записи от большинства реплик (majority) со стороны KV store.

Звучит сурово, с учетом того, что серверов в KV store: 9 * 4 ДЦ = 36. Непонятно, как будет высокая согласованность достигаться в таком случае. Читаем из KV — там запись уже есть, но вся операция записи еще не завершилась.

В первую очередь хочется сказать спасибо за подробный анализ и развернутый комментарий.

Из популярного я бы добавил Cassandra, Scylla, FoundationDB, Tarantool. Последний так вообще, судя по публикациям, создан для таких задач.

Я не ставил перед собой целью составить тут список наиболее популярных key-value-хранилищ, хотя, без сомнения, перечисленные выше решения — отличные кандидаты для него. Просто список получился бы слишком длинным ) В целом, я хотел показать, что название конкретного решения не так важно, как понимание того, на каких принципах оно реализовано и для решения какого класса задач разрабатывается.

каковые являются Non-functional requirements.

Hitachi Solutions высказывает даже такое мнение, что: "The Architect focuses on non-functional requirements".

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

"Четыре девятки" относятся к доступности (availability). Отказоустойчивость (fault tolerance) — это про способность системы свойство технической системы сохранять свою работоспособность после отказа одной или нескольких её составных частей.

Все так, исправлюсь.

Если взять шесть серверов по 10 процессоров в каждом можно попытаться напрямую взять планочку 500.000 RPS на БД типа Scylla или Tarantool. Тут многое еще зависит от того, сколько RAM можно использовать.

Можно взять 12 серверов по 10 процессоров, тогда планочка точно возьмется. При этом вся система существенно упростится.

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

Звучит сурово, с учетом того, что серверов в KV store: 9 * 4 ДЦ = 36. Непонятно, как будет высокая согласованность достигаться в таком случае. Читаем из KV — там запись уже есть, но вся операция записи еще не завершилась.

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

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

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

Да, это красивое решение

> Она будет применяться во всех продуктах компании масштаба Facebook

Архитектура и технические решения в компаниях где я работал существенно отличались. Конкретные решения ни когда не создаются с нуля. Всегда есть ограничения в виде внутренних традиций, организационной структуры и бюджетов. В качестве примера вы приводите Facebook. Интересно, в какой мере инженеры Яндекса осведомлены о подходах к разработке в других компаниях?

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

Ну, когда-то же они были кем-то созданы ) Я бы хотел чтобы в проектах периодически появлялись люди, способные критически оценить существующую систему, и, если она требует модернизации, могли ее предложить, в том числе аргументируя в терминах бюджетов и затрат на эксплуатацию.

Интересно, в какой мере инженеры Яндекса осведомлены о подходах к разработке в других компаниях?

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

Можете привезти какие-нибудь примеры решений или подходов, которые вы успешно заимствовали? Я не про технический шпионаж, а преодоление внутреннего сопротивления со стороны сложившейся культуры разработки в компании.

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

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

Хорошая статья, редкость последнее время, поставил бы плюсик, если бы мог.

Мне всегда было интересно, какого опыта надо набираться, чтобы брать цифры максимальной нагрузки для таких расчетов? То есть, например:

То есть мы можем рассчитывать максимум на обслуживание ~20 тысяч запросов на сервер. Это значительно ниже предела обслуживания запросов в KV store, который составляет порядка 100 тысяч RPS


Вот почему именно 20 тысяч, и разве это не должно зависеть от мощности сервера? С KV store не сталкивался, но откуда цифра для него — из документации или тоже из практики?

Или вот там дальше — «40 серверов, с учетом мощности СУБД 43 сервера» — то есть добавляем 3 сервера на базу. Почему именно три, и какими конкретно должны быть все эти 43 сервера (CPU, RAM)?

Но самое интересное — что происходит, если уже при старте проекта выяснится, что конфигурация все же не выдерживает по той или иной причине (хотя ожидаемое число RPS не превышено) и начинает падать? Это иногда может быть равносильно полному провалу проекта, и уж точно является полным провалом ответственного лица.

Просто мне видится какой-то замкнутый круг — для реализации хайлоад-проектов нужен опыт, набраться его, не создавая такие самому, невозможно, а для пет-проекта даже несколько штук серверов выглядит как перебор, не говоря уже о десятках…
для реализации хайлоад-проектов нужен опыт, набраться его, не создавая такие самому, невозможно

Почему невозможно? На одной VPS поднимаете ваш сервис, с другой VPS начинаете спапить на первую запросами. Можно не с одной, а с нескольких, для увеличения масштаба.

С 99.99% вероятностью ваш сервис упадет — вот и просторы для творчества и практики.
Это не совсем то, это будет просто задачка на оптимизацию одного конкретного сервиса. Нужно как минимум несколько штук для самого сервиса, и как минимум с дублированием всего — то есть пара инстансов базы данных, пара веб-серверов, пара чего-нибудь для кэша, балансировщик нагрузки — и еще сколько-нибудь для тестирования, ну тоже хотя бы парочку. Уже не так чтобы копейки, а далее возникают вопросы типа — «а если мы вот тут возьмем сервер не на четыре, а на восемь процессоров, это поможет?» — которые опять же проверять только экспериментально, будет еще недешевле. Плюс мне кажется, что навыки не масштабируются так просто и системы из пяти и пятидесяти серверов будут отличаться не только количеством.

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

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

Уже не так чтобы копейки

Самый дешевый VPS у моего хостера — 157 рублей. 10 штук на месяц обойдется в 1570р. — на мой взгляд это не критичная сумма для it-специалиста.

а если мы вот тут возьмем сервер не на четыре, а на восемь процессоров, это поможет?

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

Плюс мне кажется, что навыки не масштабируются так просто

Начнем с того, что ~80% программистов в принципе не привыкли заменять Memory Cost и Runtime своего кода. И ~99% в принципе не пробовали настроить nginx balancer и сделать несколько кластеров под бек и несколько шардов базы, что делается локально, на докере.

попасть в контору, которая с такими работает

Да даже если попадешь — кто человека, который «не шарит» — допустит к важным бизнес процессам? Так, только если со стороны посмотреть.

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

Мне всегда было интересно, какого опыта надо набираться, чтобы брать цифры максимальной нагрузки для таких расчетов? То есть, например:

То есть мы можем рассчитывать максимум на обслуживание ~20 тысяч запросов на сервер. Это значительно ниже предела обслуживания запросов в KV store, который составляет порядка 100 тысяч RPS

Вот почему именно 20 тысяч, и разве это не должно зависеть от мощности сервера? С KV store не сталкивался, но откуда цифра для него — из документации или тоже из практики?

Я вел расчеты под среднестатистический сервер, сейчас это порядка 64 вычислительных потоков, ≈2Gb RAM на ядро — похожие конфигурации используются для проведения бенчмарков, вот например бенчмарк от ngnix, в нем используется 2x Intel(R) Xeon(R) CPU E5‑2699 v3 @ 2.30 GHz, 36 real (or 72 HT) cores

Или вот там дальше — «40 серверов, с учетом мощности СУБД 43 сервера» — то есть добавляем 3 сервера на базу. Почему именно три, и какими конкретно должны быть все эти 43 сервера (CPU, RAM)?

Это минимальная конфигурация для обеспечения консенсуса. В целом рассуждения по этому поводу есть в статье:

Для самой базы потребуется достаточно много дискового места и порядка десяти CPU на обслуживание запросов — здесь доминантным ресурсом будет дисковое пространство, такой инстанс скорее всего займет полноценный сервер. Считаем, что выбранное нами managed-решение для СУБД имеет встроенные механизмы по автоматическому переключению primary-инстанса на основе алгоритмов распределенного консенсуса. Поэтому нам потребуется три таких сервера для отказоустойчивости.

Далее,

Но самое интересное — что происходит, если уже при старте проекта выяснится, что конфигурация все же не выдерживает по той или иной причине (хотя ожидаемое число RPS не превышено) и начинает падать? Это иногда может быть равносильно полному провалу проекта, и уж точно является полным провалом ответственного лица.

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

Просто мне видится какой-то замкнутый круг — для реализации хайлоад-проектов нужен опыт, набраться его, не создавая такие самому, невозможно, а для пет-проекта даже несколько штук серверов выглядит как перебор, не говоря уже о десятках…

Не обязательно получать опыт только на основе собственных ошибок — извлекайте его из докладов на профильных конференциях и тематических ресурсах. Для этого и существует Хабр в том числе )

И все же все еще остается непонятным, как вы насчитали обслуживание 20 тысяч запросов, из каких соображений?

Ну, у нас в компании есть некоторый опыт работы с трафиком, в том числе с обработкой SSL handshake'ов. Это цифры взяты по усредненным показателям производительности наших серверов. А в комментарии выше есть ссылка на бенчмарк от ngnix.

При этом в статье вы ссылаетесь на "значения летенси, что должен знать каждый программист". Вы действительно ожидаете, что на собеседовании человек вспомнит, что на каком-то там условном процессоре выполняется примерно 20к хендшейков в секунду?

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

Как и TDD, де-факто ставший стандартом в разработке модулей

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

Найти компанию, в которой бы все программисты ответственно относились к авто-тестам, и чтобы команда в целом стремилась к 100% покрытию тестами — это из разряда фантастики.

Многие уверены, что у инженерной должности есть «потолок»: однажды для дальнейшего профессионального роста нужно начинать управлять людьми и становиться руководителем. У нас это не так

Полностью согласен. Более того, подход «рост программиста только через переход в менеджмент» по-сути лишает рынок нормальных кадров.

Видимо картинка зависит от личного вектора развития. Мне в последние лет 8 не попадались проекты, где юнит тесты были бы опциональными. Обычно код покрывается юнит тестами на 80% (оценка снизу). В прочем, делать 100% покрытие - такой цели не было ни где.

Полностью поддерживаю здесь ответ @funca

В целом мне кажется что отношение к тестированию в компании отражает уровень ее зрелости — чем дальше от уровня стартапа, тем больше вниманию уделяется качеству производимого ПО.

Спасибо за статью.

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

Мне это напоминает собеседования с алгоритмами.

Стало интересно - действительно ли собеседования у вас на этом этапе проходят так подробно, с детализацией до таблиц в БД и чуть ли не конфигов сервисов? Сколько же оно длится по времени? Действительно это те вещи, которые хочется услышать от кандидата?

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

Одни эти знания действительно не дадут опыта. А вот опыт, полученный без этих знаний будет значительно менее ценным.

Стало интересно - действительно ли собеседования у вас на этом этапе проходят так подробно, с детализацией до таблиц в БД и чуть ли не конфигов сервисов? Сколько же оно длится по времени? Действительно это те вещи, которые хочется услышать от кандидата?

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

И как успехи мероприятий? Какая доля людей ~~являются подготовленными завсегдатаями собеседований~~ проходит такое интервью?

И ещё важный вопрос - разрешено ли гуглить? Очевидно, что спецификации (например, пропускную способность) можно погуглить, чтобы получить актуальные цифры текущих версий фреймворков и инструментариев.

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

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

Итого 40 серверов, с учетом мощностей для СУБД — 43 сервера

Хм, 43 сервера для сокращения URL? Очень интересный расчет в свете того, что целый StackExchange (Включая StackOverflow) работает на 20 серверах...

У StackExchange заявленное количество запросов на несколько порядков меньше, чем в условиях задачи (500 vs 500000 rps), хоть сами запросы и сложнее.

Спасибо. Интересный опыт построения.

А в чем опасность перебора?

Пройдутся по очереди по всем id, и угонят все данные.

Какие данные? Это же публичные ссылки

После того, как определились что на запись будет работать один сервер БД, почему выбор сделан в пользу URL, сгенерированного случайно? Чем хуже обычный sequence в БД?
Ведь "возможность перебора" у нас отсечется сравнением пользователя, запросившего данные, и создавшего ссылку - я не понимаю, как случайность что-то изменит?

CREATE TABLE Link (
link_id INTEGER NOT NULL PRIMARY KEY,
account_id INTEGER NOT NULL REFERENCES Account,
ttl INTEGER,
created DATETIME NOT NULL,
accessed DATETIME NOT NULL,
url VARCHAR NOT NULL
)

Как я понимаю, URL в данной таблице - это исходный, "длинный URL". А как хранится/кодируется короткий URL? Генерируется из link_id через alphanumeric? Если нет, то почему - ведь это будет делать K-V store, у которых (по вашим словам) нагрузка на процессор минимальна (да и какая там нагрузка - преобразовать int в строку и обратно).
Это развитие предыдущей идеи - не использовать случайное число. Как минимум, мы сэкономим 5-7 байт на каждую запись, что пусть на процент, но сэкономит нам и трафик, и объем БД.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.