Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Масштабировать легко. Часть третья — стратегии

Anna | 3.06.2014 | нет комментариев
В предыдущих частях (здесь и здесь) мы говорили об основных архитектурных тезисах построения масштабируемых порталов. Сегодня продолжим разговор об оптимизации верно построенного портала. Выходит, стратегии масштабирования.

Потенциал локальной оптимизации дюже лимитирован.

Кэши — отличная штука, Дабы усилить ударную силу отдельно взятого компонента либо обслуживания. Но всякой оптимизации когда-то приходит конец. Это — самый поздний момент, когда стоит задуматься, как поддерживать несколько экземпляров (instances) своих сервисов, другими словами — как масштабировать свою архитектуру. Различные типы узлов по-различному поддаются масштабированию. Всеобщее правило при этом таково: чем ближе компонент к пользователю — тем легче его масштабировать.

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

Масштабировать презентационный ярус традиционно легко. Это ярус, к которому относятся веб-приложения, бегающие в веб-сервере либо сервлет-контейнере (скажем, tomcat либо jetty), и отвечающие за генерацию markup, то есть HTML, XML либо JSON.

Дозволено легко добавлять и убирать новые сервера по необходимости — до тех пор, пока одиночный веб-сервер:

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

Потруднее масштабировать ярус приложения (application tier) — тот ярус, где бегают сервисы. Но раньше чем перейти к ярусу приложения, давайте посмотрим на ярус позади него — базы данных.
Трагическая правда о масштабировании через базу заключается в том, что оно не работает. И правда время от времени представители разных изготовителей баз данных пытаются вновь уговорить нас в том, что вот в данный раз они верно могут масштабироваться — в самый ответственный момент они нас оставлен. Небольшой disclaimer: я не говорю, что не нужно делать кластеры баз данных либо репликации а-ля master/slave. Есть много причин для применения кластеров и реплик, но эффективность в их число не входит.

Вот основная повод того, что приложения так нехорошо масштабируются через базы данных: основная задача базы данных — лишь верное сохранение данных (ACID и всё такое). Чтение данных им даётся значительно тяжелее (раньше чем орать «как же» и «отчего же», подумайте: для чего необходимо такое число индексаторов типа lucene/solar/elastic search?). Раз мы не можем масштабировать через базу, нам нужно масштабировать через application tier. Есть много причин, отчего это восхитительно работает, назову две:

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

Существуют различные стратегии для масштабирования сервисов.

Стратегии масштабирования.

Для начала нужно определить, что такое состояние обслуживания (state). Состояние одного экземпляра обслуживания — это та информация, которая вестима только ему и которая, соответственно, отличает его от других экземпляров.
Экземпляр обслуживания — это, как правило, JavaVM, в которой бегает одна копия этого обслуживания. Информация, которая определяет его состояние — это традиционно данные, попадающие в кэш. Если у обслуживания нет вообще никаких собственных данных, он — stateless (не имеющий состояния). Для того, Дабы уменьшить нагрузку на какой-либо сервис, дозволено запустить несколько экземпляров этого обслуживания. Стратегии разделения траффика на эти инстанции, в всеобщем-то, и есть стратегиимасштабирования.

Самая простая тактика — Round-Robin. При этом всякий заказчик «разговаривает» с всяким экземпляром обслуживания, которые применяются по-очереди, то есть друг за ином, по кругу. Эта тактика работает отлично до тех пор, пока сервисы не имеют состояния (stateless) и исполняют примитивные задачи, скажем, посылают мейлы через внешний интерфейс.

Распределяем обращения к сервисам по принципу Round-Robin.
Схема 5: Распределяем обращения к сервисам по тезису Round-Robin

Когда у экземпляров сервисов есть состояния, они обязаны быть синхронизированы между собой, скажем, путем анонсирования изменений в состоянии через EventChannel либо иной вариант Publish/Subscriber:

Round-Robin с синхронизацией состояния
Схема 6: Round-Robin с синхронизацией состояния

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

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

Для борьбы с этим применяется маршрутизация. При этом маршрутизация обозначает, что экземпляр обслуживания выбирается в зависимости от контекста. Контекстом может быть заказчик, операция либо данные. Маршрутизация по данным, шардинг (sharding), — самый сильный инструмент маршрутизации: под ним подразумевается алгорифм маршрутизации, тот, что выбирает целевой экземпляр обслуживания на основании параметров операции (то есть данных).

В идеале, у нас есть однозначный параметр, скажем UserId, тот, что дозволено легко перевести в числовую форму и провести деление с остатком. Разделяя на число рабочих экземпляров, остаток указывает на целевой экземпляр запроса: все запросы с остатком 0 идут на 1-й экземпляр, с остатком 1 — на 2-й, и т.д.

Шардинг (sharding) по остатку
Схема 7: Шардинг (sharding) по остатку

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

При присутствие соответствующего middleware дозволено шагнуть на шаг дальше и комбинировать разные стратегии. Скажем, дозволено сгруппировать несколько экземпляров в группы, по которым распределять запросы шардингом, а внутри групп применять Round-Robin для гибкости. число таких составных стратегий слишком огромно (ещё один пример), Дабы описать их все в одном посте, и зависит от определенной задачи.

Не неизменно и не всякие данные дозволено сегментировать, исключительно когда одна операция изменяет единовременно два комплекта данных в различных контекстах. Типичный пример — доставка сообщения от пользователя А к пользователю Б, при котором единовременно изменяются оба ящика (mailbox). Немыслимо обнаружить алгорифм разделения данных по экземплярам (шардинг), тот, что гарантирует нахождение ящиков пользователя А и Б в одном экземпляре обслуживания. Но и на старуху бывает проруха и для этой обстановки есть решения. Самое примитивное: имплицитно поделить сервис (в идеале — через middleware) так,Дабы заказчик об этом ничего не знал. Скажем:

Прокси-сервисы
Схема 8: Прокси-сервисы

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

Эпилог

В рамках этой серии (здесьздесь и, собственно, здесь) мы говорили о том, как обнаружить положительную архитектуру и при помощи каких инструментов её масштабировать. Верю, я уговорил читателя, что время, потраченное на поиск и следование архитектурным парадигмам — инвестиция, неоднократно окупающаяся в тяжёлые моменты. Slave-Proxies, маршрутизация по Round-Robin либо нуль-кэши — не то, о чем мы думаем в первую очередь, начиная трудиться над новым порталом. Да и не нужно встраивать их «на каждый случай» — значимо знать, как ими пользоваться и иметь архитектуру, которая разрешает применение сходственных инструментов.

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

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

Везения!

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB