Люблю такие книги-статьи. Коротко. Просто. Понятно. Большинство мыслей известны специалистам (и мне в том числе :)), но будучи собранными в одном месте позволяют посмотреть на тему высоконагруженных приложений в целом. И, конечно, напомнить себе что именно можно сделать в текущей работе.
Ниже, как всегда, сжатый конспект.
[Эпиграф, отсюда же]
...можно вывести правило, которое применимо при разработке любой крупной системы, — решаем проблемы по мере их появления, каждый раз выбирая наиболее простое решение из всех возможных
Вообще...
Условно говоря, существует два подхода к разработке высоконагруженных систем: ремесленный и промышленный.В чем разница? В том, где разрабатываются средства масштабирования — те инструменты, которые гарантируют, что ваша система будет выдерживать огромные нагрузки.
При использовании промышленного подхода эти средства разрабатываются отдельно от бизнес-логики [google,yandex]. При ремесленном подходе средства и бизнес-логика разрабатываются одновременно [вконтакте]. [интересно, что] и там, и там имеются сервисы.
Масштабирование
Именно горизонтальное масштабирование является сейчас фактически стандартом.Однако на самом деле вертикальная компонента присутствует практически всегда, а универсального горизонтального масштабирования как такового не существует. Известен также такой термин, как диагональное масштабирование. Оно подразумевает одновременное использование двух подходов, то есть вы сразу и покупаете новое железо, тем самым выигрывая время, и активно переписываете приложения. Например, такой подход принят в StackOverflow.
И еще один способ масштабирования[масштабирование по времени].Различные данные имеют различные требования по обновлению.Это позволяет отложить часть обработки данных для более удобного случая.
Трёхзвенная структура
Чтобы говорить на одном языке, приведем еще одно определение — определение так называемой трехзвенной структуры системы. Три звена — это фронтенд, бэкенд и хранение данных.
Фронтенд
Обычно фронтенд представляет собой легковесный веб-сервер, разработчики которого сделали все для того, чтобы каждый запрос обрабатывался максимально быстро при минимальных затратах ресурсов. Например, у nginx на 10 тысяч неактивных keep-alive-соединений уходит не более 2,5 мегабайт памяти.
Правило простое: там, где не нужно отправлять запрос на бэкенд, где не нужно что-либо вычислять, все должно отдаваться фронтендом.Наличие фронтендов — это первый признак высоконагруженной системы
Одна из основных функций фронтенда — балансировка нагрузки между бэкендами, точнее, не столько балансировка, сколько проксирование.В настройках фронтендов прописываются так называемые апстримы (upstreams), то есть серверы, куда следует отправлять тот или иной запрос [с учётом антишквала].
Обычный масштаб чаще всего предполагает наличие двух или четырех фронтендов и двадцати бэкендов.
Бэкэнд
Облачные вычисления решают проблему производительности — уверены многие. Однако это верно не до конца:для того чтобы вам действительно могли помочь облачные сервисы, вы должны правильно подготовить ваш программный код. Вы можете поднять сколько угодно серверов, скажем, в Amazon EC2, но какой с них толк, если код не умеет использовать мощности каждого из них
Классическе горизонтальное масштабирование: слоистость кода, минимизация использования запросов сразу к нескольким таблицам, низкая степень связности кода
Кеш — это такое место, куда можно под каким-то ключом положить данные, которые долго вычисляют. Запомните один из ключевых моментов: кэш должен вам по этому ключу отдать данные быстрее, чем вычислить их заново. Мы неоднократно сталкивались с ситуацией, когда это было не так и люди бессмысленно теряли время.
Иногда база данных работает достаточно быстро и проще сходить напрямую к ней. Второй ключевой момент: кэш должен быть единым для всех бэкендов.[И главное:]старайтесь сделать так, чтобы ваша система работала и без кеширования.
Базы данных
Общего решения [для масштабирования] нет.
Подходит тебе синхронная репликация или нет? Подходит mastermaster или нет? Можешь ты поставить много баз данных и разбить данные между большим количеством экземпляров или нет? Все это зависит от конкретного приложения, от вашего пользователя и того, как ты хочешь показывать ему данные.
В реальной разработке (и это правило относится ко всем сложным проектам) предпочтение нужно отдавать тем инструментам, которые знают ваши главные специалисты.
какие запросы можно использовать в высоконагруженной системе, а какие нет? Мы должны использовать все те же подходы, о которых говорили на предыдущих уроках — share nothing и stateless. Подход очень простой — представь сразу, что твои таблицы расположены не на одном, а на десяти серверах...Теперь ответь на такой вопрос — как вы будете выполнять join’ы из таблиц, расположенных на разных физических серверах? Правильный ответ — вручную.Работа с базой данных в высоконагруженном проекте предполагает простые легкие конечные запросы. С заданием границ выборки, максимальным количеством извлекаемых элементов. Минимальное количество индексов, только самое необходимое, ведь индексы ускоряют выборки, но замедляют обновления БД.
Не рекомендуется использовать множество приятных внутренних механизмов СУБД. Объединения, пересечения — все это нужно делать в памяти бекенда. Нужно сделать join для двух таблиц? Сделай два отдельных запроса и перемножь результат в памяти. Не используй хранимые процедуры — как они будут работать, если исходные данные для них окажутся наразных серверах?
Основная техника, которая используется при масштабировании СУБД — это шардинг... - разбиение, нарезка данных по машинам. Шардинг — это некий компромисс между масштабированием и удобством доступа, удобством аналитики.
Виртуальные шарды — это некая прослойка, которая позволяет мне как back-end’у общаться всегда с конкретным шардом, не задумываясь о том, где физически находится этот виртуальный шард [физический и виртуальный шард связаны через определённые таблицы].
Потом начинаем двигаться еще дальше. Мы начинаем использовать особенности наших данных. Мы начинаем хранить, например, новости в реляционной базе данных, а что-то еще — в NoSQL’ной базе данных.
Надёжность
хочешь быть готовыми к выходу из строя некоторых элементов – вводи избыточность этих самых элементов.Это как с денормализацией – хранение дублированныхданных, оптимизированных для выборок – да, придется хранить одни и те же элементы в нескольких экземплярах, зато быстро работает. Это неизбежное зло.
Как в программном обеспечении вы избегаете единых точек отказа, то точно также надо избегать точек отказа и в железе. Старайтесь не использовать никакого уникального оборудования без крайней на то нужды. Вы удивитесь, но поиск Яндекса, обрабатывающий десятки тысяч запросов в секунду и хранящий колоссальное количество информации, построен на самых обычных серверах
Мониторинг
Обычно в мониторинг попадает некий джентельменский набор параметров типа значения load averages, количество чтений/записи с диска, свободное пространство на дисках, количество процессов, трафик. Это важно, но этого недостаточно. Советуем также включить в мониторинг еще два вида параметров: Бизнес-параметры ... и технические параметры, которые описывают работу именно вашего проекта, учитывая его специфику и функциональность
Мониторинг бизнес-показателей, кстати, это основной инструмент и, как это ни странно, прогнозирования нагрузки
Восстановление
Все средства восстановления должны быть автоматизированы. Если ты сталкиваешься с какой-то проблемой более, чем один раз – автоматизируйте ее. Но большую часть автоматизируйте априори.
На количестве машин больше 20-ти стоимость поддержки сильно превышает стоимость внесения изменений. Вы перестаете вносить изменения, вы постоянно исправляете ошибки.
Deployment
Нужно уметь перевыкатывать весь свой сайт на новое голое железо за 20 минут (без учета времени копирования данных).
Выкатывание новой версии на сайт должно производиться максимально легко.Что бы кто ни говорил, но даже в самых больших и крупных проектах иногда бывает редактирование кода на продакшне. В этом просто кто-то признается, а кто-то не признается. В любом крупном проекте такое иногда бывает. Все зависит от того, как именно организован деплой.
Существует большое количество инструментов для деплоймента, изучите и выберете оптимальный для конкретной ситуации. Например, библиотека Capistrano. Ты описываешь в специальном формате процесс выкатки, прописываете списки серверов, библиотеки кода, что и куда выкатывать, что и где перезапускать. И далее процесс выкатки упрощается до запуска управляющей команды.
Процесс отката
что делать, если обновление, которое вы только что выкатили, сломалось в боевых условиях? Нужно оперативно и быстро откатиться назад.Автоматизация процесса отката – это, конечно, чистая магия :)
Но один совет для того, чтобы облегчить процесс отката, приведем. Основная проблема отката это изменения в базе данных. Отсюда вывод – любое изменение в базе данных должно быть оформлено в виде файла с конкретными SQL-командами. Этот файл должен быть положен в репозиторий и именно этот файл выполняет скрипт деплоймента для выкатки новой версии схемы базы данных. Вместе с этим файлом вы также можете класть и файл, содержащий SQL-команды для отката к предыдущему состоянию схемы СУБД.