6 заметок с тегом system-design

System Design

stateless и stateful сервисы

Пример stateful системы
Например наша система хранит в себе сессии пользователей, тем самым ответ на запрос пользователя зависит от состояния (сессии). При масштабировании сервиса, нам прийдется переносить все сессии на новый инстанс. Система стает сложной и не маневренной. Любой stateful сервис можно превратить в stateless, вынеся состояние в отдельный сервис и БД. Так мы можем вынести сессии во внешнее хранилище, сама система осталась stateful, но сам веб сервис stateless, тем самым мы можем просто его реплицировать.

Пример stateless системы
Давайте вместо сессий использовать cookie файлы, таким образом мы передаем серверу не только сам запрос, но и всю необходимую информацию для его выполнения. Серверу больше не надо хранить в себе состояние. Stateless система зависит только от данных которые ей были переданы, а не от внутреннего состояния.

Еще один пример
У нас есть интернет магазин — пока корзина пользователя хранится в памяти сервера, то это stateful. И у нас сразу возникают проблемы с масштабированием. Но когда мы выносим хранения корзины во внешний session storage — наш сервис становится stateless и мы можем спокойно его масштабировать, так как состояние хранится у нас в отдельном хранилище.

Очень советую почитать статью на RSND по данной теме.

Шардинг

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

Вертикальный шардинг

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

  • users — данные пользователей
  • photos — фотографии пользователей
  • albums — альбомы пользователей

Таблицу users Вы оставляете на одном сервере, а таблицы photos и albums переносите на другой. В таком случае в приложении Вам необходимо будет использовать соответствующее соединение для работы с каждой таблицей

Горизонтальный шардинг

Горизонтальный шардинг — это разделение одной таблицы на разные сервера. Это необходимо использовать для огромных таблиц, которые не умещаются на одном сервере. Разделение таблицы на куски делается по такому принципу:

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

Совместное использование

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

Key-value базы данных

Следует отметить, что большинство Key-value баз данных поддерживает шардинг на уровне платформы. Например, Memcache. В таком случае, Вы просто указываете набор серверов для соединения, а платформа сделает все остальное

Итог

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

P.S.

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

Ссылки

  1. Вертикальный шардинг
  2. Шардинг и репликация
 Нет комментариев    217   2019   system-design

Репликация данных

Репликация — одна из техник масштабирования баз данных. Состоит эта техника в том, что данные с одного сервера базы данных постоянно копируются (реплицируются) на один или несколько других. Для приложения появляется возможность использовать не один сервер для обработки всех запросов, а несколько. Таким образом появляется возможность распределить нагрузку с одного сервера на несколько.

Существует два основных подхода при работе с репликацией данных:

  1. Репликация Master-Slave;
  2. Репликация Master-Master.

Master-Slave репликация

В этом подходе выделяется один основной сервер базы данных, который называется Мастером. На нем происходят все изменения в данных (любые запросы INSERT/UPDATE/DELETE). Слейв сервер постоянно копирует все изменения с Мастера. С приложения на Слейв сервер отправляются запросы чтения данных. Таким образом Мастер сервер отвечает за изменения данных, а Слейв за чтение.

Несколько Слейвов

Преимущество этого типа репликации в том, что Вы можете использовать более одного Слейва. Обычно следует использовать не более 20 Слейв серверов при работе с одним Мастером.
Тогда из приложения выбирает случайным образом один из Слейвов для обработки запросов, тем самым распределяя нагрузку на БД.

Выход из строя

При выходе из строя Слейва, достаточно просто переключить все приложение на работу с Мастером. После этого восстановить репликацию на Слейве и снова его запустить.
Если выходит из строя Мастер, нужно переключить все операции (и чтения и записи) на Слейв. Таким образом он станет новым Мастером. После восстановления старого Мастера, настроить на нем реплику, и он станет новым Слейвом.

Master-Master репликация

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

«Ручная» репликация

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

Итог

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

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

 Нет комментариев    220   2019   system-design

Кэширование

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

В любом приложение есть медленные операции (запросы к БД или внешним API), результаты которых можно сохранить на какое-то время. Это позволит выполнять меньше таких операций, а большинству пользователей показывать заранее сохраненные данные.

Что кэшировать?

  1. Страницы целиком или ее частей
  2. Запросы к БД
  3. Медленные операции внутри системы (расчеты, счетчики и т. д.)
  4. Запросы к внешним системам

Повторные запросы

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

Для решения этой проблемы можно разделить кэш на 2 части:

  1. Внутренний (в самом приложении)
  2. Внешний (на отдельном сервере)

Внимание! Такой подход может привести к утечкам памяти. Так что стоит с умом использовать внутренний кэш приложения.

Ключевые понятия

Время жизни (ttl) — это время после которого данные из кэша будут удалены. Никогда не устанавливайте время в 0 (бесконечная жизнь). Это может привести ко многим проблемам.

LRU (Least recently used) — алгоритм, который определяет какие ключи удалять в случае если не хватает места в кэше и нужно вытеснить какие-то данные.

Кэширование очень медленных запросов

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

Для решения данной проблемы можно использовать технику дублирования ключей с разным временем жизни.
Она еще называется «методика дублирования».

Проблемы при работе с кэшем

  1. Деление данных между кэширующими серверами
  2. Параллельные запросы на обновление данных
  3. «Холодный» старт и «прогревание» кэша

Деление данных между кэширующими серверами
Причины для разделения кэша между несколькими серверами:

  1. Данных может быть очень много, и они физически не поместятся в память одного сервера
  2. Данные могут запрашиваться очень часто, и один сервер не в состоянии обработать все эти запросы
  3. Сделать кэширование более надёжным.

Способы разбивки данных между серверами

  1. Вычисление номера сервера псевдослучайным образом в зависимости от ключа кэширования.
    Проблема такого подхода заключается в том, что в случае падения одного из сервером, мы теряем больше 80% кэша. Так как местоположение ключей поменяется.
  2. Использование алгоритма согласованного хеширования. Основная идея этого механизма очень простая: здесь добавляется дополнительное отображение ключей на слоты, количество которых заметно превышает количество серверов.
  3. Логическое разделение данных. Например данные могут распределятся по некоему UserId. Так мы будем понимать что все данные, которые ему принадлежат — лежат на одном сервере.

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

Какую проблему еще называют: cache stampede, hit miss storm или dog-pile effect.
Есть несколько способов решения данной проблемы:

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

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

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

«Холодный» старт и «прогревание» кэша

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

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

Частично решить эту проблему можно решить следующими способами:

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

Достоинства

Существенно разгружается система и ее составляющие, что позволит значительно ее ускорить.

Недостатки

  1. Сложность реализации
  2. Множество проблем, которые необходимо решить

Ссылки

  1. Кэширование данных
  2. Обзор кэширования от amazon
  3. Кэширование и производительность веб-приложений
  4. 11 видов кэширования для современного сайта
  5. Тяжелое кэширование
  6. Проблемы при работе с кэшем и способы их решения
  7. Проблема одновременного перестроения кэшей
 1 комментарий    183   2019   system-design

Кластеризация

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

Виды кластеров

  1. Отказоустойчивые кластеры (High-availability clusters, HA)
  2. Кластеры с балансировкой нагрузки (Load balancing clusters)
  3. Вычислительные кластеры (High performance computing clusters, HPC)
  4. Системы распределенных вычислений

Отказоустойчивые кластеры

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

Подтипы отказоустойчивых кластеров

  1. С холодным резервом
  2. С горячим резервом
  3. С модульной избыточностью

Холодный резерв
Один сервер находится в пассивном режиме и ждет падения основного сервера

Горячий резерв
Два сервера обрабатывают запросы, в случае падения одного, вся нагрузка направляется на живой.

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

Кластеры распределения нагрузки

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

Вычислительные кластеры

Кластеры используются в вычислительных целях, в частности в научных исследованиях. Для вычислительных кластеров существенными показателями являются высокая производительность процессора в операциях над числами с плавающей точкой (flops) и низкая латентность объединяющей сети, и менее существенными — скорость операций ввода-вывода, которая в большей степени важна для баз данных и web-сервисов. Вычислительные кластеры позволяют уменьшить время расчетов, по сравнению с одиночным компьютером, разбивая задание на параллельно выполняющиеся ветки, которые обмениваются данными по связывающей сети.

Типовые задачи для расчетных кластеров

  1. решение задач механики жидкости и газа, теплопередачи и теплообмена, электродинамики, акустики;
  2. моделирование аэрогазодинамических процессов;
  3. моделирование физико-химических процессов и реакций;
  4. моделирование сложного динамического поведения различных механических систем;
  5. решение задач цифровой обработки сигналов, финансового анализа, разнообразных математических задач, визуализации и представления данных
  6. анализ и расчет статической и динамической прочности;
  7. газодинамика, термодинамика, теплопроводность и радиочастотный анализ;
  8. моделирование задач любой степени геометрической сложности;
  9. рендеринг анимации и фотореалистичных VFX эффектов

Системы распределенных вычислений

Такие системы не принято считать кластерами, но их принципы в значительной степени сходны с кластерной технологией. Их также называют grid-системами. Главное отличие — низкая доступность каждого узла, то есть невозможность гарантировать его работу в заданный момент времени, поэтому задача должна быть разбита на ряд независимых друг от друга процессов. Такая система, в отличие от кластеров, не похожа на единый компьютер, а служит упрощенным средством распределения вычислений. Состоит из множества ресурсов разных типов.

Пример
Кластер в CERN представляет из себя иерархический грид, который имеет 3 слоя:

  • Нулевой — собирает информацию с датчиков и осуществляет первичное хранение информации
  • Tier 1 — хранит копии данных в разных точках мира
  • Tier 2 — преимущественно обладают высокой вычислительной мощностью — обрабатывают информацию.

Достоинства

  1. Эффективная утилизация ресурсов.
  2. Обновления без остановки
  3. Увеличение производительности
  4. Отказоустойчивость (круглосуточная работа)
  5. Абсолютная масштабируемость

Недостатки

  1. Синхронизация между приложениями — необходимо обеспечить синхронизацию данных между серверами в кластере.
  2. Цена
  3. Сложность в управлении
  4. Необходимость адаптации приложения для работы в кластере (веб-ферме).

Ссылки

  1. Википедия: Кластер (группа компьютеров)
  2. Кластеризация
  3. Кластерные вычислительные системы
  4. Кластерные архитектуры
  5. Википедия: Серверная ферма
  6. Отказоустойчивые кластеры (кластеры высокой доступности)
 Нет комментариев    202   2019   system-design

Pipeline архитектура

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

Составляющие

  1. Фильтр — преобразует или фильтрует данные, которые он получает через каналы, с которыми он связан. Фильтр может иметь любое количество входных каналов и любое количество выходных каналов.
  2. Канал — это соединитель, который передает данные от одного фильтра к другому. Это направленный поток данных, который обычно реализуется буфером данных для хранения всех данных до тех пор, пока следующий фильтр не успеет их обработать.
  3. Продюсер — является источником данных. Это может быть статический текстовый файл или устройство ввода с клавиатуры, постоянно создающее новые данные.
  4. Приемник или потребитель является целью данных. Это может быть другой файл, база данных или экран компьютера.

Примеры

UNIX приложения, выход одной программы можно передать на вход в другую программу.

$ ps aux | grep [k]de | gawk ’{ print $2}’

выводит на экран список процессов, которые содержат в имени kde


Компиляторы

Когда следует использовать этот шаблон

  1. Процесс обработки, требуемый приложением, можно легко разделить на ряд независимых этапов.
  2. У этапов обработки, которые выполняются приложением, разные требования к масштабируемости.
  3. Требуется определенная гибкость, чтобы изменять порядок шагов обработки, выполняемых приложением, или добавлять и удалять шаги.
  4. Система будет работать эффективнее, если распределить шаги обработки между несколькими серверами.
  5. Чтобы свести к минимуму последствия сбоя на шаге при обработке данных, требуется надежное решение

Проблемы и рекомендации

При выборе схемы реализации этого шаблона следует учитывать следующие моменты.

  1. Сложность — повышенная гибкость, которую обеспечивает этот шаблон, может также вызвать сложности, особенно если фильтры в конвейере распределяются между разными серверами.
  2. Надежность — используйте инфраструктуру, которая гарантирует сохранность данных, передаваемых между фильтрами в конвейере.
  3. Идемпотентность — свойство объекта или операции при повторном применении операции к объекту давать тот же результат, что и при первом. Если после получения сообщения происходит сбой фильтра в конвейере и операция переносится на другой экземпляр фильтра, часть операции может быть уже выполнена. Тем самым продолжение выполнения должно вернуть нам такой же результат.
  4. Повторяющиеся сообщения — если сбой фильтра в конвейере происходит после публикации сообщения для следующего этапа конвейера, может запуститься другой экземпляр фильтра и опубликовать копию этого сообщения в конвейере. Это может привести к передаче следующему фильтру двух экземпляров одного сообщения.

Достоинства

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

Недостатки

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

Ссылки

  1. Pipeline Architecture
  2. YouTube: 101 способ приготовления RabbitMQ и о pipeline-архитектуре
  3. Текст: 101 способ приготовления RabbitMQ и о pipeline-архитектуре
  4. Принципы и приёмы обработки очередей
  5. Pipes and Filters pattern
  6. Pipe-And-Filter
  7. Pipes and Filters
 Нет комментариев    919   2019   system-design