UncategorizedгаджетыНовостиразработчиктехнология

Существенная сложность в системной архитектуре

Стенограмма

Нолан: Добро пожаловать в существенную сложность системной архитектуры. Я Лаура Нолан. В чем вообще суть сложности? Думаю, многие из вас, вероятно, читали оригинальную статью Фреда Брукса «Нет серебряной пули». Он очень ориентирован на сложность реализации программной логики. По словам Брукса, существенная сложность – это все, что напрямую вызвано проблемой, которую вы пытаетесь решить. А случайная сложность – это все, что связано с деталями реализации. Если вы создаете веб-приложение, актуальные функции и проблемы, которые вы пытаетесь решить, бизнес-логика, это ваша основная сложность. Ваша случайная сложность – это все, что связано с деталями, так что все, что связано с вашей базой данных, или с вашими языками программирования, или с вашими фреймворками, или с самим HTTP, или с вашими сертификатами. Все это мелочи, случайные сложности.

Однако Брукс писал в то время, когда вычисления были немного больше похожи на это. Я думаю, что это, вероятно, значительно старше 80-х годов. Однако найти в Интернете хорошую фотографию мэйнфрейма на удивление сложно. Пожалуйста, примите это за большое железо. В 1980-х годах, если вы хотели решить более серьезную проблему, вы масштабировались по вертикали. Вы бы купили компьютер побольше или могли бы просто дольше бегать самостоятельно. Вещи были больше ориентированы на пакетную обработку и менее ориентированы на режим реального времени. Масштаб выглядел так. Теперь масштабирование похоже на запуск вашей системы на нескольких относительно небольших серверах. Для этого есть множество веских причин. Масштаб, в котором вы хотите работать, довольно часто больше, чем самая большая отдельная коробка, доступная нам. Мы хотим реального времени. Мы не хотим партии. В наши дни даже множество приложений типа конвейера данных, если не совсем в реальном времени, им тоже не нужны вещи в одночасье, им нужны вещи в течение нескольких минут, особенно если это какие-то связанные числа, которые могут увидеть клиенты. Все, что связано с оптимизацией рекомендаций или сокращением мошенничества, все эти вещи. Нам нужно иметь возможность разделять работу и запускать ее на множестве небольших серверов, а это добавляет кучу сложности. Это существенная сложность, потому что это нефункциональные требования. Мы не можем просто выбросить руку и уйти, это не проблема бизнеса, которую мы пытаемся решить. Это настоящие вещи, с которыми нам приходится иметь дело. Это важно. Это важно для архитектур, которые мы создаем.

Постановка проблемы

Вот, пожалуй, самая простая из возможных постановок проблемы для распределенной системы. Однако на самом деле это настоящая проблема. Это проблема, над которой я работал, когда работал в Google несколько лет назад. Я работал в инфраструктуре данных рекламы. У нас была эта проблема, когда нам нужно было объединить два потока структурированных журналов на основе общего идентификатора. У вас есть журнал A, журнал B, общий идентификатор, общий для обоих, и вы хотите получить вывод журнала, в котором есть поля из журнала A, поля из журнала B и общий идентификатор. У нас также было дополнительное ограничение, которое заключалось в том, что мы могли присоединиться к любой записи журнала только один раз. В результате из этого простого утверждения мы получили довольно сложную систему. Причина в том, что в комнате есть слон, а этот слон в комнате – весы, потому что один из этих структурированных входов журнала был почти всеми красными результатами, которые, например, обслуживал поиск Google. Также в комнате есть гепард. Мы хотели этого не в одночасье, не на следующей неделе, мы хотели сделать это в течение нескольких минут. Для этого были веские бизнес-причины. В комнате осел. Осел – это надежность. Мы хотели, чтобы это пережило не только гибель какой-либо отдельной машины, мы также хотели, чтобы он пережил потерю центра обработки данных, что он действительно мог сделать. Наконец-то в комнате появился ястреб. Это комната, которая становится очень заполненной разными животными, и именно так работает практическая архитектура распределенных систем. Ястреб – это возможность наблюдать, понимать и отлаживать вашу систему. Это то, о чем мы не обязательно думаем при проектировании наших систем. Я думаю, что мы подумаем об этом позже, когда перейдем к этапу запуска и проверки готовности. Я думаю, это то, о чем нам следует подумать на раннем этапе. Я думаю, что наши системы лучше подходят для этого, когда мы это делаем.

Photon: отказоустойчивое и масштабируемое объединение непрерывных потоков данных

Это системная архитектура, которая появилась из всего этого. Photon будет работать в двух центрах обработки данных. Он будет координировать свою работу с помощью этой вещи, называемой IdRegistry. Это было строго согласованное хранилище данных, которое обновлялось каждый раз при объединении двух записей журнала, поэтому их нельзя было объединить дважды. По сути, это была транзакция, которую нужно было совершить здесь. Каждый конвейер мог присоединиться к любой паре журналов, но только один мог бы присоединиться к ним, так что нагрузка могла плавно перемещаться между каждым центром обработки данных очень естественно и очень легко. Здесь у нас было четыре основных компонента: диспетчер, который считывал меньший журнал по мере его поступления и пытался найти соответствующую запись в более крупном журнале. EventStore – это в основном хранилище ключей и значений, которое будет индексироваться в журналах запросов, более крупном журнале. Затем соединитель, который сделает всю работу и обновит IdRegistry. Также была пара других более мелких деталей, которые не показаны в этой немного упрощенной версии, но это основная история. Это не самая сложная система, но она довольно сложна для чего-то, у кого есть одна небольшая бизнес-проблема: объединить два набора журналов. Так бывает, когда вы имеете дело с масштабом и когда имеете дело с надежностью. Предшественник этой системы был значительно проще. Это был одинарный трубопровод. Это была всего лишь пара разных заданий, которые нужно было выполнить. Проблема заключалась в том, что у него не было никакой прочности. В случае сбоя или если один из центров обработки данных, в котором вы его запускали, выходил из строя, вам приходилось поднимать его вручную, пытаться привести состояние конвейера в согласованное состояние и переместить его. Это вызывает стресс. Есть большая вероятность того, что что-то пойдет не так. Это вполне ручная операция. Если вам нужно это сделать, кто-то должен прийти и вручную выполнить это действие. Этому человеку понадобится несколько минут, чтобы прийти и сделать то, что необходимо, особенно если вам нужно немного отладить, чтобы понять, что происходит, и действительно ли это правильное действие. Это было очень большое улучшение надежности, но также и увеличение сложности. Стоило ли? Я думаю так. Я хорошо помню, как однажды утром это было в воскресенье днем ​​или в воскресенье утром. Я сидел там и завтракал. Один из моих коллег связался со мной. Он сказал: «Лора, когда Фотон догонит?» Я сказал: «Что ты имеешь в виду, когда Фотон догонит? Нет ничего плохого в Фотоне». Он сказал: «Один из центров обработки данных не работает». Я пошел и посмотрел, и, конечно же, да, один из центров обработки данных вышел из строя, но вся нагрузка только что переключилась, как было задумано. Мы проводили мониторинг на основе SLO. Мы не отвечали за центр обработки данных, за это отвечала другая команда, поэтому мы не получали пейджинговые сообщения только потому, что центр обработки данных был недоступен. Мы получали пейджинг, когда наша система нарушала свои SLO, и это было нормально. Я полагаю, что мораль этой истории в том, чтобы понять свою основную сложность и расслабиться за вкусным завтраком, чтобы вам не пришлось тратить выходные на тушение пожаров. Это вообще была революция по сравнению с предыдущей системой. Бежать было проще и менее напряженно.

Масштабирование работы программных операций

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

Запуск 1-10 копий одного и того же кода

Когда вы запускаете довольно небольшое количество копий одного и того же кода, у вас возникают те же проблемы, которые мы видели на предыдущем слайде. Вы должны знать, правильно ли он работает? Могу я его раскатать? Можно откатить? Могу я понять, что он делает? Могу ли я его масштабировать? Хотя, если вы используете до 10 копий, вам, вероятно, не нужно сильно увеличивать масштаб. Если что-то пойдет не так, он достаточно мал, чтобы вы могли, вероятно, использовать SSH и выяснить это там. Это более или менее пропорционально двоичной системе.

Запуск 100-1000 копий одного и того же кода

Если я запускаю намного больше копий одного и того же кода, все становится немного интереснее. Мне нужно приложить дополнительные усилия, чтобы убедиться, что я не перегружу серверные части, от которых я зависим. Это явление, называемое лазером смерти, при котором я увеличиваю масштабы своей службы, и теперь я избавился от вещей, от которых я зависел. Вы не хотите этого делать. Возможно, вам очень скоро придется начать добавлять кеширование для этого. Возможно, вам придется очень внимательно подумать об автоматических выключателях или убедиться, что вы не перегружаете свои серверные модули. Еще одна вещь, о которой вы должны подумать, когда ваша система станет немного больше, если она станет больше, она, вероятно, будет более загружена. Вам нужно подумать о возможной изоляции между запросами пользователей. Если у вас есть 100 или 1000 копий чего-то, вероятно, это общая служба, поэтому вам нужно подумать об этом. Вам нужно подумать о горячих точках. Независимо от того, что используется для балансировки нагрузки в моей службе, хорошо ли она распределяет эту нагрузку? Если нагрузка, которую получает какая-либо часть системы, основана на данных, которые она обслуживает, есть ли у меня способы разделить ее? Есть ли у меня способы воспроизвести это? Интересно также и то, что если что-то пойдет не так, вы больше не сможете просто использовать SSH в случайном экземпляре, потому что это может быть нормально. Вам нужно значительно лучше видеть, что делает ваша система, где нагрузка, где ошибки, где насыщение. Это становится очень важным.

Запуск от 1000 до 10000 копий одного и того же кода

Если я запускаю от 1000 до 10 000 копий одного и того же кода, оптимизация очень важна. Мы начинаем разбираться в вещах, которые оказывают значительное влияние на окружающую среду с точки зрения энергопотребления и стоимости. Стоимость тоже является частью этого. Вы хотите начать мониторинг регрессий. Вы хотите подумать о том, чтобы на самом деле превысить мощность всего центра обработки данных, в котором вы находитесь. Я видел это раньше. Я видел, как этого не произошло. Если вам нужно сделать резервную копию данных, охватывающих такое количество экземпляров, это также может стать очень сложной задачей с точки зрения пропускной способности. Если что-то пойдет не так, значительно выше вероятность того, что это проблемы с поведением сложных систем или какое-то новое свойство. Здесь у вас есть вещи, которые независимо делают вещи, которые почему-то очень оптимистично настроены синхронизировать это поведение, которое должно быть независимым. Подумайте о таких вещах, когда у вас есть куча служб, которым нужно взаимодействовать с одним и тем же, и оно на некоторое время отключается. Все они повторяют попытку. Затем он возвращается, и все они немедленно запрашивают его. Это одна из тех проблем лазерного типа смерти. Вы можете получить все эти виды каскадного поведения, грохочущего стада, бурю сплетен в одноранговых системах, которые довольно сложно диагностировать сложные проблемы поведения системы. Вы должны понимать систему и то, как информация течет во всей системе, а не только плохое поведение на одном хосте.

Соображения по архитектуре и компромиссы

Все это говорит о том, что если вы хотите построить небоскреб, вам нужны методы строительства небоскреба. Вы не просто возьмете коттедж с соломенной крышей и построите его очень высоким. Есть золотая середина. Вы не можете бесконечно масштабировать маломасштабные системные методы. Вы должны начать распространять эту архитектуру так же, как мы видели с конвейером Photon. Соображения, компромиссы и задачи, которые у вас есть, когда вам нужно масштабировать распределенную систему, подобную этой, или построить распределенную систему, как мне разделить мою работу и мои данные? Все распределенные системы должны делать это тем или иным образом. Может все очень просто. Может быть, это система без сохранения состояния, и все, что мне нужно сделать, это запустить n ее копий и сбалансировать нагрузку между ними. Когда вы начинаете разбираться в системах с интенсивным использованием данных, все становится еще сложнее. Как координировать состояние? Даже если это так просто, сколько из моих узлов в рабочем состоянии и какие они? Как управлять отказом или переключением при отказе? Как мне увеличить масштаб? С каким следующим узким местом я столкнусь с точки зрения общей емкости моей системы? Я работоспособен? Я видел случаи, когда большой парк инстансов мог сэкономить 50% используемой оперативной памяти, потому что у них была какая-то гигантская хеш-таблица, которую они даже не использовали. Вам нужно начать думать об этом. Тогда есть вопросы понятности и предсказуемости. Спроектирована ли система с предсказуемыми, управляемыми, понятными потоками и поведением между компонентами, или это что-то, что делает ее более эмерджентными свойствами типа?

Два конкурирующих стиля системной архитектуры

Я считаю, что есть два основных конкурирующих стиля архитектуры распределенных систем. Я называю первое командование и контроль. Второй – одноранговый. Ваша архитектура командования и контроля, у вас есть особый элемент управления. Вы масштабируете, добавляя иерархию, возможно, кешируя прокси. Примером этого является хранилище ключей и значений Bigtable от Google. Затем одноранговый. У вас есть координация, выполняемая рабочими узлами, у вас нет какого-либо красивого специального узла контроллера. Вы делаете случайное разделение диапазонов, например, используете такие методы, как системное хеширование. Вы можете координировать свои действия, используя одноранговые протоколы. Примером этого является хранилище ключей и значений Dynamo от Amazon. У вас есть два хранилища ключей и значений, оба из которых созданы в 90-х годах. Я думаю, что обе статьи вышли примерно в 2006, 2007 годах и делали что-то похожее, хотя Dynamo в конечном итоге последовательна, тогда как Bigtable более последовательна. Это все еще довольно похожие проблемы с радикально разными решениями.

Обзор Bigtable и Dynamo

У Bigtable есть контроллер, он называется Bigtable controller. Он назначает планшеты на серверы планшетов. Планшетные серверы – это те, кто фактически выполняет запросы и управляет данными. Они хранят данные в другой системе под названием GFS, которая позже стала Colossus. Контроллеры выполняют проверку работоспособности. Они используют службу блокировки для управления отказоустойчивым контроллером. В исходной статье Bigtable использовался другой термин, но я использую контроллер, потому что старый термин больше не считается приемлемым. На самом деле контроллер более наглядный. У Dynamo нет контроллера или какого-либо выделенного узла. Он сплетничает между узлами для обнаружения сбоев. Он использует последовательное хеширование, что является действительно хорошей техникой, позволяющей постепенно увеличивать емкость системы без необходимости перемещать все остальное. Это действительно полезно в распределенных системах, так как оно отлично подходит для этого. Он использует децентрализованный протокол синхронизации, чтобы попытаться синхронизировать все с течением времени.

Эксплуатационные характеристики Bigtable и Dynamo

В Bigtable у вас есть одно состояние системы, которым управляет контроллер Bigtable. Если ваш контроллер Bigtable выйдет из строя, вы потенциально будете немного недоступны в течение нескольких секунд, пока не появится следующий контроллер. Потребуется заблокировать базу данных консенсуса Chubby. Размер вашей ячейки будет ограничен, потому что в конечном итоге вы получите так много планшетов и так много серверов планшетов, что ваш контроллер будет перегружен, поэтому здесь есть ограничение. Dynamo не имеет глобального представления о состоянии системы. Это одна из тех вещей, которые постоянно сходятся, может быть, немного похоже на запуск протокола сетевой маршрутизации, такого как BGP или что-то в этом роде. Вы можете посмотреть на любой узел, и вы увидите его представление о состоянии, но нет ни одного канонического представления. Это также означает, что потеря какого-либо одного узла не окажет непропорционального воздействия на систему, поэтому все данные должны быть реплицированы на вторичные узлы, а мой запрос должен выполняться при отказе. Ограничения на размер системы. Система не становится бесконечно масштабируемой, потому что у вас нет этого узкого места контроллера, потому что каждый узел по-прежнему должен иметь полную таблицу маршрутизации. Насколько я понимаю, маршрутизация работает так: клиенты, они связываются с произвольным Dynamo, а затем могут получить прокси или перенаправить туда, где находится фактический ключ, который они хотят прочитать. Вы можете устранить оба этих ограничения масштабируемости по-разному, сегментируя данные и кластеры, добавляя иерархию. Вы вполне можете это сделать. Следует также сказать, что я работаю над очень старыми версиями этих документов. Думаю, сейчас они совсем другие. Это все еще действительно интересные, достаточно простые иллюстрации этих различных архитектурных стилей.

Ремонтопригодность и работоспособность

Что касается работоспособности, то в Bigtable, если вы наблюдаете какие-либо проблемы с координацией, контроллер – это то, что вам нужно. Это дает вам непрерывный поток, в отличие от авторитетного состояния для системы, и одно место, где происходит это координационное поведение. Если вам нужно что-то изменить, вполне возможно, что вы сможете применить там некоторую конфигурацию, вместо того, чтобы изменять всю систему, чтобы повлиять на нее. В то время как Dynamo – противоположность, здесь нет единой точки для наблюдения или контроля. Для мониторинга вам нужно будет просмотреть свойства по всей системе. Например, в Bigtable, если вы хотите знать о доступности ваших планшетов, вы можете в принципе наблюдать за этим с контроллера. Если вы хотите узнать это от Dynamo, вам придется собирать статистику очень широко. Возможно, вам даже придется полагаться на некоторые исследования, а не на метрики, которые ваша система сама вам предоставит. Bigtable, вам нужно выполнять два типа заданий, а Dynamo – один. Все сложнее. Это будет более сложная кодовая база. Это более сложное поведение. У вас есть эти потоки одноранговой связи, и особенно в перебоях или в периоды, когда что-то ухудшается, вы можете обнаружить, что ваши потоки данных синхронизации могут взорваться. Если вы не будете осторожны, вы можете потратить много времени на подобные фоновые действия. Это то, что также может быть труднее понять и сложнее контролировать, если что-то пойдет не так. Надо сказать, что Bigtable также выполняет меньше работы, потому что использует внешнюю инфраструктуру, то есть поддерживает координацию Chubby с хранилищем ключ-значение, службой блокировки, а также файловой системой GFS. Это действительно интересно, потому что вместо того, чтобы управлять всем, в частности, им не нужно управлять большим количеством вращающейся ржавчины, они просто управляют логикой запросов. Они могут использовать опыт тех команд, которые управляют этой общей инфраструктурой. В то время как «Динамо», насколько я могу судить, в большей степени внутреннее. Ваши стили немного похожи на это. С одной стороны, это очень скоординированная, достаточно иерархическая вещь. У вас есть контроллер, который может влиять на состояние системы и на кого вы, как оператор, можете влиять при необходимости, тогда как в вашем одноранговом стиле у вас есть просто люди, которые приходят, берут пинту, берут музыкальный инструмент и копают in. Это совершенно другой мир, и это совершенно другой стиль управления и эксплуатации.

Соображения по архитектуре и компромиссы

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

Смотрите больше презентаций с расшифровками стенограмм

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button