Масштабирование приложений ASP.NET

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

Далее вы развертываете приложение, вводите его в эксплуатацию и оно работает замечательно в течение нескольких первых недель, но с увеличением количества пользователей увеличивается и количество запросов, которые требуется обработать вашему серверу, и вдруг, ваш сервер начинает захлебываться. Сначала это может проявляться в увеличении времени обработки запросов, затем рабочий процесс начинает использовать все больше памяти и вычислительных ресурсов и в конечном итоге веб сервер просто перестает успевать обрабатывать все запросы и в файлах журналов начинают все чаще появляться сообщения HTTP 500 («Internal Server Error»).

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

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

Горизонтальное масштабирование

С архитектурной точки зрения, выполнить масштабирование совсем не сложно: достаточно приобрести еще один-два компьютера (или десять), разместить серверы за компьютером, выполняющим распределение нагрузки, и все! Но проблема в том, что обычно все не так просто.

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

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

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

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

Механизмы масштабирования в ASP.NET

Горизонтальное масштабирование требует хранения информации о состоянии за пределами процессов. В ASP.NET имеется два механизма, обеспечивающих такой способ хранения данных:

Служба управления состоянием (State Service)

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

SQL Server

ASP.NET поддерживает возможность хранения информации о состоянии в базе данных SQL Server. Этот механизм не только поддерживает те же возможности, что и служба управления состоянием, но также обеспечивает долговременное хранение данных, поэтому, даже если на веб-серверах и на сервере с базой данных SQL Server случится аварийная ситуация, информация о состоянии сохранится.

Для нужд кеширования в большинстве случаев можно с успехом использовать один из механизмов распределенного кеширования, таких как Microsoft AppFabric Cache , NCache или Memcached , последний из которых является открытой реализацией распределенного кеша.

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

Некоторые распределенные кеши, такие как AppFabric Cache и Memcached, также имеют собственные реализации службы управления состоянием и провайдеров кеша для ASP.NET.

Ловушки горизонтального масштабирования

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

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

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

Управлять генерацией этих ключей в ASP.NET можно путем настройки параметров в разделе machineKey, в файле web.config. Когда веб-приложение выполняется на нескольких серверах, вам необходимо настроить все серверы так, чтобы они использовали один и тот же предварительно сгенерированный ключ.

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

Более полную информацию о создании уникальных ключей и включения их в настройки приложений можно получить в базе знаний Microsoft Knowledge Base . За дополнительной информацией о создании RSA-контейнера ключей обращайтесь к статье «Импорт и экспорт защищенных контейнеров ключей RSA для конфигурации» на сайте MSDN.

) Здравствуйте! Я Александр Макаров, и вы можете меня знать по фреймворку «Yii» — я один из его разработчиков. У меня также есть full-time работа — и это уже не стартап — Stay.com, который занимается путешествиями.

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

Что такое масштабирование, вообще? Это возможность увеличить производительность проекта за минимальное время путем добавления ресурсов.

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

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

Самый классный вопрос, который задают, — а зачем оно надо, если у меня все и на одном сервере прекрасно работает? На самом-то деле, надо проверить, что будет. Т.е., сейчас оно работает, но что будет потом? Есть две замечательные утилиты — ab и siege, которые как бы нагоняют тучу пользователей конкурента, которые начинают долбить сервер, пытаются запросить странички, послать какие-то запросы. Вы должны указать, что им делать, а утилиты формируют такие вот отчеты:

Главные два параметра: n — количество запросов, которые надо сделать, с — количество одновременных запросов. Таким образом они проверяют конкурентность.

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

Есть еще один параметр — Response time — время ответа, за которое в среднем сервер отдал страничку. Оно бывает разное, но известно, что около 300 мс — это норма, а что выше — уже не очень хорошо, потому что эти 300 мс отрабатывает сервер, к этому прибавляются еще 300-600 мс, которые отрабатывает клиент, т.е. пока все загрузится — стили, картинки и остальное — тоже проходит время.

Бывает, что на самом деле пока и не надо заботиться о масштабировании — идем на сервер, обновляем PHP, получаем 40% прироста производительности и все круто. Далее настраиваем Opcache, тюним его. Opcache, кстати, тюнится так же, как и APC, скриптом, который можно найти в репозитории у Расмуса Лердорфа и который показывает хиты и мисы, где хиты — это сколько раз PHP пошел в кэш, а мисы — сколько раз он пошел в файловую систему доставать файлики. Если прогнать весь сайт, либо запустить туда какой-то краулер по ссылкам, либо вручную потыкать, то у нас будет статистика по этим хитам и мисам. Если хитов 100%, а мисов — 0%, значит, все нормально, а если есть мисы, то надо выделить больше памяти, чтобы весь наш код влез в Opcache. Это частая ошибка, которую допускают — вроде Opcache есть, но что-то не работает…

Еще часто начинают масштабировать, но не смотрят, вообще, из-за чего все работает медленно. Чаще всего лезем в базу, смотрим — индексов нет, ставим индексы — все сразу залетало, еще на 2 года хватит, красота!

Ну, еще надо включить кэш, заменить apache на nginx и php-fpm, чтобы сэкономить память. Будет все классно.

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

Как, вообще, понять, в чем проблема? Либо у вас уже настал highload, а это не обязательно какое-то бешеное число запросов и т.д., это, когда у вас проект не справляется с нагрузкой, и тривиальными способами это уже не решается. Надо расти либо вширь, либо вверх. Надо что-то делать и, скорее всего, на это мало времени, что-то надо придумывать.

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

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

На что нужно обращать внимание прямо сейчас при мониторинге? Это:

  1. доступность, т.е. жив сервер, вообще, или нет;
  2. нехватка ресурсов диска, процессора и т.д.;
  3. ошибки.
Как это все мониторить?

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

Этот доклад - расшифровка одного из лучших выступлений на обучающей конференции разработчиков высоконагруженных систем за 2015 год.

Старьё! - скажите вы.
- Вечные ценности! - ответим мы. Добавить метки

С ростом популярности web-приложения его поддержка неизбежно начинает требовать всё больших и больших ресурсов. Первое время с нагрузкой можно (и, несомненно, нужно) бороться путём оптимизации алгоритмов и/или архитектуры самого приложения. Однако, что делать, если всё, что можно было оптимизировать, уже оптимизировано, а приложение всё равно не справляется с нагрузкой?

Оптимизация

Первым делом стоит сесть и подумать, а всё ли вам уже удалось оптимизировать:
  • оптимальны ли запросы к БД (анализ EXPLAIN, использование индексов)?
  • правильно ли хранятся данные (SQL vs NoSQL)?
  • используется ли кеширование?
  • нет ли излишних запросов к ФС или БД?
  • оптимальны ли алгоритмы обработки данных?
  • оптимальны ли настройки окружения: Apache/Nginx, MySQL/PostgreSQL, PHP/Python?
О каждом из этих пунктов можно написать отдельную статью, так что детальное их рассмотрение в рамках данной статьи явно избыточно. Важно лишь понимать, что перед тем как приступить к масштабированию приложения, крайне желательно максимально оптимизировать его работу – ведь возможно тогда никакого масштабирования и не потребуется.

Масштабирование

И так, допустим, что оптимизация уже проведена, но приложение всё равно не справляется с нагрузкой. В таком случае решением проблемы, очевидно, может послужить разнесение его по нескольким хостам, с целью увеличения общей производительности приложения за счёт увеличения доступных ресурсов. Такой подход имеет официальное название – «масштабирование» (scale) приложения. Точнее говоря, под «масштабируемостью » (scalability) называется возможность системы увеличивать свою производительность при увеличении количества выделяемых ей ресурсов. Различают два способа масштабирования: вертикальное и горизонтальное. Вертикальное масштабирование подразумевает увеличение производительности приложения при добавлении ресурсов (процессора, памяти, диска) в рамках одного узла (хоста). Горизонтальное масштабирование характерно для распределённых приложений и подразумевает рост производительности приложения при добавлении ещё одного узла (хоста).

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

Архитектура приложения

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

Каждый их этих слоёв может быть масштабирован. Поэтому если в вашей системе приложение и БД живут на одном хосте – первым шагом, несомненно, должно стать разнесение их по разным хостам.

Узкое место

Приступая к масштабированию системы, первым делом стоит определить, какой из слоёв является «узким местом» - то есть работает медленнее остальной системы. Для начала можно воспользоваться банальными утилитами типа top (htop) для оценки потребления процессора/памяти и df, iostat для оценки потребления диска. Однако, желательно выделить отдельный хост, с эмуляцией боевой нагрузки (c помощью или JMeter), на котором можно будет профилировать работу приложения с помощью таких утилит как xdebug , и так далее. Для выявления узких запросов к БД можно воспользоваться утилитами типа pgFouine (понятно, что делать это лучше на основе логов с боевого сервера).

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

Масштабирование БД

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

Снизить нагрузку на БД можно разнеся её на несколько хостов. При этом остро встаёт проблема синхронизации между ними, решить которую можно путём реализации схемы master/slave с синхронной или асинхронной репликацией. В случае с PostgreSQL реализовать синхронную репликацию можно с помощью Slony-I , асинхронную – PgPool-II или WAL (9.0). Решить проблему разделения запросов чтения и записи, а так же балансировки нагрузку между имеющимися slave’ами, можно с помощью настройки специального слоя доступа к БД (PgPool-II).

Проблему хранения большого объёма данных в случае использования реляционных СУБД можно решить с помощью механизма партицирования (“partitioning” в PostgreSQL), либо разворачивая БД на распределённых ФС типа Hadoop DFS .

Однако, для хранения больших объёмов данных лучшим решением будет «шардинг » (sharding) данных, который является встроенным преимуществом большинства NoSQL БД (например, MongoDB).

Кроме того, NoSQL БД в общем работают быстрее своих SQL-братьев за счёт отсутствия overhead’а на разбор/оптимизацию запроса, проверки целостности структуры данных и т.д. Тема сравнения реляционных и NoSQL БД так же довольно обширна и заслуживает отдельной статьи .

Отдельно стоит отметить опыт Facebook, который используют MySQL без JOIN-выборок. Такая стратегия позволяет им значительно легче масштабировать БД, перенося при этом нагрузку с БД на код, который, как будет описано ниже, масштабируется проще БД.

Масштабирование кода

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

Далее необходимо настроить балансировку нагрузки/запросов между этими хостами. Сделать это можно как на уровне TCP (haproxy), так и на HTTP (nginx) или DNS .

Следующим шагом нужно сделать так, что бы файлы статики, cache и сессии web-приложения были доступны на каждом хосте. Для сессий можно использовать сервер, работающий по сети (например, memcached). В качестве сервера кеша вполне разумно использовать тот же memcached, но, естественно, на другом хосте.

Файлы статики можно смонтировать с некого общего файлового хранилища по NFS /CIFS или использовать распределённую ФС (HDFS , GlusterFS , Ceph).

Так же можно хранить файлы в БД (например, Mongo GridFS), решая тем самым проблемы доступности и масштабируемости (с учётом того, что для NoSQL БД проблема масштабируемости решена за счёт шардинга).

Отдельно стоит отметить проблему деплоймента на несколько хостов. Как сделать так, что бы пользователь, нажимая «Обновить», не видел разные версии приложения? Самым простым решением, на мой взгляд, будет исключение из конфига балансировщика нагрузки (web-сервера) не обновлённых хостов, и последовательного их включения по мере обновления. Так же можно привязать пользователей к конкретным хостам по cookie или IP. Если же обновление требует значимых изменений в БД, проще всего, вообще временно закрыть проект.

Масштабирование ФС

При необходимости хранения большого объёма статики можно выделить две проблемы: нехватка места и скорость доступа к данным. Как уже было написано выше, проблему с нехваткой места можно решить как минимум тремя путями: распределённая ФС, хранение данных в БД с поддержкой шардинга и организация шардинга «вручную» на уровне кода.

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

Мониторинг

Понятно, что большая и сложная система требует постоянного мониторинга. Решение, на мой взгляд, тут стандартное – zabbix, который следит за нагрузкой/работой узлов системы и monit для демонов для подстраховки.

Заключение

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

Масштабируемость - такое свойство вычислительной системы, которое обеспечивает предсказуемый рост системных характеристик, например, числа поддерживаемых пользователей, быстроты реакции, общей производительности и пр., при добавлении к ней вычислительных ресурсов. В случае сервера СУБД можно рассматривать два способа масштабирования - вертикальный и горизонтальный (рис. 2).

При горизонтальном масштабировании увеличивается число серверов СУБД, возможно, взаимодействующих друг с другом в прозрачном режиме, разделяя таким образом общую загрузку системы. Такое решение, видимо, будет все более популярным с ростом поддержки слабосвязанных архитектур и распределенных баз данных, однако обычно оно характеризуется сложным администрированием.

Вертикальное масштабирование подразумевает увеличение мощности отдельного сервера СУБД и достигается заменой аппаратного обеспечения (процессора, дисков) на более быстродействующее или добавлением дополнительных узлов. Хорошим примером может служить увеличение числа процессоров в симметричных многопроцессорных (SMP) платформах. При этом программное обеспечение сервера не должно изменяться (в частности, нельзя требовать закупки дополнительных модулей), так как это увеличило бы сложность администрирования и ухудшило предсказуемость поведения системы. Независимо от того, какой способ масштабирования использован, выигрыш определяется тем, насколько полно программы сервера используют доступные вычислительные ресурсы. В дальнейших оценках мы будем рассматривать вертикальное масштабирование, испытывающее, по мнению аналитиков, наибольший рост на современном компьютерном рынке.

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

  • поддержка многопроцессорной обработки;
  • гибкость архитектуры.

Многопроцессорные системы

Для вертикального масштабирования все чаще используются симметричные многопроцессорные системы (SMP), поскольку в этом случае не требуется смены платформы, т.е. операционной системы, аппаратного обеспечения, а также навыков администрирования. С этой целью возможно также применение систем с массовым параллелизмом (MPP), но пока их использование ограничивается специальными задачами, например, расчетными. При оценке сервера СУБД с параллельной архитектурой целесообразно обратить внимание на две основные характеристики расширяемости архитектуры: адекватности и прозрачности.

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

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

Качественная поддержка многопроцессорной обработки требует от сервера баз данных способности самостоятельно планировать выполнение множества обслуживаемых запросов, что обеспечило бы наиболее полное разделение доступных вычислительных ресурсов между задачами сервера. Запросы могут обрабатываться последовательно несколькими задачами или разделяться на подзадачи, которые, в свою очередь, могут быть выполнены параллельно (рис. 3). Последнее более оптимально, поскольку правильная реализация этого механизма обеспечивает выгоды, независимые от типов запросов и приложений. На эффективность обработки огромное воздействие оказывает уровень гранулярности рассматриваемых задачей-планировщиком операций. При грубой гранулярности, например, на уровне отдельных SQL-запросов, разделение ресурсов вычислительной системы (процессоров, памяти, дисков) не будет оптимальным - задача будет простаивать, ожидая окончания необходимых для завершения SQL-запроса операций ввода/вывода, хотя бы в очереди к ней стояли другие запросы, требующие значительной вычислительной работы. При более тонкой гранулярности разделение ресурсов происходит даже внутри одного SQL-запроса, что еще нагляднее проявляется при параллельной обработке нескольких запросов. Применение планировщика обеспечивает привлечение больших ресурсов системы к решению собственно задач обслуживания базы данных и минимизирует простои.

Гибкость архитектуры

Независимо от степени мобильности, поддержки стандартов, параллелизма и других полезных качеств, производительность СУБД, имеющей ощутимые встроенные архитектурные ограничения, не может наращиваться свободно. Наличие документированных или практических ограничений на число и размеры объектов базы данных и буферов памяти, количество одновременных подключений, на глубину рекурсии вызова процедур и подчиненных запросов (subqueries) или срабатывания триггеров базы данных является таким же ограничением применимости СУБД как, например, невозможность переноса на несколько вычислительных платформ. Параметры, ограничивающие сложность запросов к базе данных, в особенности размеры динамических буферов и стека для рекурсивных вызовов, должны настраиваться в динамике и не требовать остановки системы для реконфигурации. Нет смысла покупать новый мощный сервер, если ожидания не могут быть удовлетворены из-за внутренних ограничений СУБД.

Обычно узким местом является невозможность динамической подстройки характеристик программ сервера баз данных. Способность на ходу определять такие параметры, как объем потребляемой памяти, число занятых процессоров, количество параллельных потоков выполнения заданий (будь то настоящие потоки (threads), процессы операционной системы или виртуальные процессоры) и количество фрагментов таблиц и индексов баз данных, а также их распределение по физическим дискам БЕЗ останова и перезапуска системы является требованием, вытекающим из сути современных приложений. В идеальном варианте каждый из этих параметров можно было бы изменить динамически в заданных для конкретного пользователя пределах.

9 июля 2015 в 09:10

Горизонтальное масштабирование серверов баз данных для OLTP-систем, или что есть на рынке

  • Администрирование баз данных ,
  • Серверная оптимизация

Как правило, в крупных и средних компаниях существуют высоконагруженные транзакционные информационные системы, которые являются важнейшей составляющей бизнеса, их называют OLTP-системами. С ростом бизнеса нагрузка увеличивается очень быстро, поэтому задача увеличения производительности имеющихся ресурсов под серверы баз данных, стоит очень остро. Зачастую для решения задачи увеличения производительности серверов баз данных приобретается более мощное оборудования (так называемое «вертикальное» масштабирование), но этот способ имеет очень существенный минус: компания рано или поздно купит сервер баз данных максимальной производительности по приемлемой цене, и что делать дальше? Дальше перспективы для бизнеса могут быть не такие радужные – во многих случаях речь идет об ухудшении репутации компании, невозможности обслужить клиентов в моменты повышенного спроса, значительной потере прибыли.

Для исключения подобных ситуаций и обеспечения работоспособности OLTP-систем многие компании идут по пути «горизонтального» масштабирования серверов баз данных. В отличие от наращивания производительности основного сервера («вертикальное» масштабирование) при «горизонтальном» масштабировании серверы объединяются в кластер (набор), и нагрузка на серверы БД распределяется между ними. Этот подход более технологичный, так как кроме очевидных преимуществ в виде возможности увеличения производительности путем добавления новых серверов, решается задача достижения отказо- и катастрофоустойчивости.

Многие ИТ-компании в России и мире занимаются разработкой подобных решений, ниже я попытаюсь рассказать о них более подробно.

Первое решение - Oracle RAC (Real Application Cluster - появилось еще в далеком 2001 году в версии 9i для повышения доступности и производительности в высоконагруженных системах на базе СУБД Oracle. Оно позволяет распределить нагрузку на высоконагруженную базу данных между серверами БД и тем самым увеличить возможности OLTP-системы по беспроблемному росту информационных потоков. Для получения более подробной информации можно обратиться к документации или книгам издательства Oracle Press. Поэтому остановлюсь на некоторых моментах, интересных с точки зрения принципа работы.

Т.к. в Oracle RAC реализована архитектура Shared-everything (со всеми присущими ей преимуществами и недостатками), то для каждого сервера в Oracle RAC существует свой кэш, в который попадают данные SQL запросов, выполненных на нём. Также существует глобальный кэш кластера, реализованный с помощью технологи Cache Fusion, который синхронизируется с локальными кэшами серверов по данным. Особую роль в координации ресурсов кластера и объединения кэша играет структура данных Global Resource Directory, в которой фиксируется на каком сервере, какие данные и по каким объектам актуальны; какой режим блокировок для объекта на экземпляре. Вся эта информация помогает принять решение, на какой сервер с точки зрения производительности лучше отправить запрос SQL, так как в случае неправильного решения время запроса SQL увеличится за счет времени на синхронизацию данных между кэшами.

Важная особенность такого подхода к распределению нагрузки между серверами БД - необходимость учета «разнообразия» траффика SQL от OLTP-системы. В случаях, когда запросы SQL извлекают данные из многих таблиц одновременно, и интенсивность изменения в этих таблицах большая, возможна потеря времени на синхронизацию данных кэша между различными серверами кластера (именно по этой причине нужен быстрый и надежный interconnect между серверами). Это, в свою очередь, может привести к ухудшению отклика OLTP-системы, и преимущества от использования Oracle RAC могут быть полностью нивелированы.

Плюсы:

  • Active/Active кластер
  • Балансировка нагрузки
  • Масштабирование с увеличением производительности, но и увеличением доступности
  • Практически линейное увеличение производительности при добавлении новых узлов в кластер
  • «Прозрачное» для приложений масштабирование

Минусы:

  • Работает только с СУБД Oracle
  • Для работы желателен высокопроизводительный interconnect с низкими задержками
  • СХД может быть единой точкой отказа. Для обеспечения высокого уровня отказоустойчивости RAC нужно комбинировать со standby или зеркалированием СХД.

Второе решение - Citrix NetScaler – реализует горизонтальное масштабирование серверов БД для OLTP-систем на базе MS SQL Server и MySQL иначе, чем Oracle RAC. С техническими особенностями можно ознакомиться, пройдя по ссылке .

Если в Oracle RAC серверы баз данных синхронизируются автоматически, то Citrix NetScaler для синхронизации должен использовать сторонние технологии: AlwaysOn от Microsoft, MySQL replication. Само же решение Citrix NetScaler является прокси-сервером между уровнем приложения (сервер приложения, web-сервер) и серверами баз данных, таким образом все запросы SQL к серверу БД проходят через него.

По спецификации решение умеет распознавать сигнатуру запросов SQL (на чтение или запись данных) и перенаправлять их на нужные (определенные настройками) сервера в кластере. Задержка на обработку запроса SQL прокси-сервером минимальна, поэтому отклик OLTP-системы не должен ухудшиться после внедрения. Несмотря на этот плюс, возможности для балансировки нагрузки от запросов SQL также зависят от особенностей траффика OLTP-системы. Во многих OLTP-системах измененные данные в транзакции сразу считываются следующим запросом SQL для дальнейшей работы. Учитывая особенности такой технологии, как например MS AlwaysOn, данные на дополнительных серверах отстают от основного на некоторое время (в синхронном и асинхронном режиме). Без учета этого факта приложение и пользователь могут получить ситуацию, при которой добавленные данные будут отсутствовать в выборке следующего запроса SQL. Как правило, технологию Citrix NetScaler рекомендуют использовать не в автоматическом режиме, а в ручном, поэтому сфера ее применения ограничивается несложными запросами к БД в веб-приложениях.

Третья технология - Softpoint Data Cluster – российская разработка, которая схожа с двумя предыдущими, при этом в ряде моментов более применима к практическим задачам по «горизонтальному» масштабированию серверов баз данных для OLTP- систем. Более подробную информацию о продукте можно найти на сайте вендора .

Технология на первый взгляд похожа на Citrix NetScaler, так как представляет собой прокси-сервер между уровнем приложения и уровнем базы данных, а также тесно интегрирована с технологиями синхронизации БД (например, MS AlwaysOn), но в отличие от Citrix NetScaler отслеживает рассинхронизации серверов БД в кластере и полностью гарантирует непротиворечивость данных в выборках, где бы на серверах ни выполнялся запрос SQL. Эта особенность позволяет без адаптации к трафику приложения обеспечить автоматическую балансировку нагрузки.

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