что такое горизонтальное масштабирование системы
Горизонтальное масштабирование: разнесение серверов
При выборе платформы для корпоративной системы у крупных компаний есть как минимум один общий критерий — производительность. Если система может выдержать максимум 5000 одновременных пользовательских сессий, а у компании их 20 000, то вряд ли такой программный продукт подойдёт. В этом случае начинает играть роль масштабируемость системы.
Масштабируемость — возможность системы увеличивать свою производительность при увеличении количества выделяемых ей ресурсов.
Виды масштабирования
Существует два вида масштабирования: вертикальное и горизонтальное.
Вертикальное масштабирование— увеличение производительности приложения при добавлении ресурсов в рамках имеющегося оборудования. Например, увеличение оперативной памяти или замена процессора на более мощный. В этом случае масштабируемость ограничена, очень легко достигнуть потолка.
Горизонтальное масштабирование— увеличение производительности приложения за счёт распределения нагрузки между имеющимся и новым оборудованием. До тех пор, пока есть возможность увеличивать количество серверов, есть возможность увеличивать производительность и обеспечивать комфортную работу большего количества пользователей.
Для того чтобы приложение могло поддержать горизонтальное масштабирование, код приложения должен поддерживать механизм взаимодействия и синхронизации серверов между собой. Мы предусмотрели возможности для горизонтального масштабирования, поэтому платформа SimpleOne может использоваться для реализации проекта практически любого уровня нагруженности.
Горизонтальное масштабирование серверов осуществляется на двух уровнях:
В этой статье мы расскажем про то, как в SimpleOne осуществляется горизонтальное масштабирование на первом уровне, — про разнесение серверов.
Разнесение серверов
Система SimpleOne разделена по функциям на четыре группы: клиентский сервер, сервер приложений, сервер БД и сервер файлового хранилища.
Разбиение системы SimpleOne по функциям
Клиентский сервер
Клиентский сервер отвечает за первичную коммуникацию пользователя с приложением. Этот сервер позволяет запустить приложение, загружая необходимый для работы код: CSS, JS, ReactJS, ConfigJS.
Сервер приложений
После первичного взаимодействия с клиентским сервером все запросы пользователя идут на сервер приложений. Например, пользователь хочет получить лист или список кнопок. Сервер приложений обрабатывает запрос, запрашивает данные и направляет их пользователю.
Сервер баз данных
Сервер БД обслуживает и управляет БД, отвечает за целостность и сохранность данных.
Сервер БД является «узким» местом производительности. Чтобы снизить нагрузку на него, в SimpleOne файлы хранятся на отдельном сервере.
Сервер файлового хранилища
Файлы хранятся в хранилище, доступном по протоколу S3.
Amazon Simple Storage Service (Amazon S3) — это сервис хранения объектов, предлагаемый поставщиками облачных услуг. Основное преимущество решения — возможность хранить файлы любого типа, любого объёма, с высоким уровнем надёжности и доступности.
При запросе файла сервер приложений обращается к файловому хранилищу, которое формирует токен и передаёт его браузеру. Через токен пользователь получает доступ к объекту в файловом хранилище.
В основном компании-разработчики не выносят объёмные файлы (видео, картинки и т. д) на отдельный сервер, а хранят их на сервере баз данных. Разнесение хранения данных и файлов по разным серверам даёт преимущества:
Заключение
Масштабируемость системы играет важную роль для крупных компаний. Горизонтальное масштабирование даёт практически бесконечные возможности для увеличения производительности ESM-платформы SimpleOne, что делает её подходящей для реализации высоконагруженных проектов любого уровня.
Вертикальное и горизонтальное масштабирование, scaling для web
Для примера можно рассмотреть сервера баз данных. Для больших приложений это всегда самый нагруженный компонент системы.
Возможности для масштабирования для серверов баз данных определяются применяемыми программными решениями: чаще всего это реляционные базы данных (MySQL, Postgresql) или NoSQL (MongoDB, Cassandra и др).
Горизонтальное масштабирование для серверов баз данных при больших нагрузках значительно дешевле
Веб-проект обычно начинают на одном сервере, ресурсы которого при росте заканчиваются. В такой ситуации возможны 2 варианта:
MySQL является самой популярной RDBMS и, как и любая из них, требует для работы под нагрузкой много серверных ресурсов. Масштабирование возможно, в основном, вверх. Есть шардинг (для его настройки требуется вносить изменения в код) и репликация, которая может быть сложной в поддержке.
Вертикальное масштабирование
NoSQL масштабируется легко и второй вариант с, например, MongoDB будет значительно выгоднее материально, при этом не потребует трудозатратных настроек и поддержки получившегося решения. Шардинг осуществляется автоматически.
Таким образом с MySQL нужен будет сервер с большим количеством CPU и оперативной памяти, такие сервера имеют значительную стоимость.
Горизонтальное масштабирование
С MongoDB можно добавить еще один средний сервер и полученное решение будет стабильно работать давая дополнительно отказоустойчивость.
Scale-out или горизонтальное масштабирование является закономерным этапом развития инфраструктуры. Любой сервер имеет ограничения и когда они достигнуты или когда стоимость более мощного сервера оказывается неоправданно высокой добавляются новые машины. Нагрузка распределяется между ними. Также это дает отказоустойчивость.
Добавлять средние сервера и настраивать кластеры нужно начинать когда возможности для увеличения ресурсов одной машины исчерпаны или когда приобретение сервера мощнее оказывается невыгодно
Приведенный пример с реляционными базами данных и NoSQL является ситуацией, которая имеет место чаще всего. Масштабируются также фронтэнд и бэкенд сервера.
Горизонтальное масштабирование PHP приложений. Часть 1
Итак вы сделали сайт. Всегда интересно и волнительно наблюдать как счетчик посещений медленно, но верно ползет вверх, с каждым днем показывая все лучшие результаты. Но однажды, когда вы этого не ждете, кто-то запостит ссылку на ваш ресурс на каком-нибудь Reddit или Hacker News (или на Хабре — прим. пер.), и ваш сервер ляжет.
Вместо того, что бы получить новых постоянных пользователей, вы останетесь с пустой страницей. В этот момент, ничего не поможет вам восстановить работоспособность сервера, и трафик будет утерян навсегда. Как же избежать таких проблем? В этой статье мы поговорим об оптимизации и масштабировании.
Немного про оптимизацию
Основные советы всем известны: обновитесь до последней версии PHP (в 5.5 теперь встроен OpCache), разберитесь с индексами в базе данных, кэшируйте статику (редко изменяемые страницы, такие как “О нас”, “FAQ” и т.д.).
Также стоит упомянуть об одном особом аспекте оптимизации — обслуживании статического контента не-Apache сервером, таким как, например, Nginx, Настройте Nginx на обработку всего статического контента (*.jpg, *.png, *.mp4, *.html…), а файлы требующие серверной обработки пусть отсылает тяжелому Apache. Это называется reverse proxy.
Масштабирование
Есть два типа масштабирования — вертикальное и горизонтальное.
В моем понимании, сайт является масштабируемым, если он может справляться с трафиком, без изменений в программном обеспечении.
Вертикальное масштабирование.
Представьте себе сервер, обслуживающий веб-приложение. У него 4ГБ RAM, i5 процессор и 1ТБ HDD. Он отлично выполняет свои функции, но, что бы лучше справляться с более высоким трафиком, вы решаете увеличить RAM до 16ГБ, поставить процессор i7, и раскошелиться на SSD диск. Теперь сервер гораздо мощнее, и справляется с высокими нагрузками. Это и есть вертикальное масштабирование.
Горизонтальное масштабирование.
Горизонтальное масштабирование — создание кластера из связанных между собой (часто не очень мощных) серверов, которые вместе обслуживают сайт. В этом случае, используется балансировщик нагрузки (aka load balancer) — машина или программа, основная функция которой — определить на какой сервер послать запрос. Сервера в кластере делят между собой обслуживание приложения, ничего друг о друге не зная, таким образом значительно увеличивая пропускную способность и отказоустойчивость вашего сайта.
Есть два типа балансировщиков — аппаратные и программные. Программный — устанавливается на обычный сервер и принимает весь трафик, передавая его соответствующим обработчикам. Таким балансировщиком может быть, например, Nginx. В разделе “Оптимизация” он перехватывал все запросы на статические файлы, и обслуживал эти запросы сам, не обременяя Apache. Другое популярное ПО для реализации балансировки нагрузки — Squid. Лично я всегда использую именно его, т.к. он предоставляет отличный дружественный интерфейс, для контроля за самыми глубокими аспектами балансировки.
Аппаратный балансировщик — выделенная машина, единственная цель которой — распределять нагрузку. Обычно на этой машине, никакого ПО, кроме разработанного производителем, больше не стоит. Почитать про аппаратные балансировщики нагрузки можно здесь.
Обратите внимание, что эти два метода не являются взаимоисключающими. Вы можете вертикально масштабировать любую машину (aka Ноду) в вашей системе.
В этой статье мы обсуждаем горизонтальное масштабирование, т.к. оно дешевле и эффективнее, хотя и сложнее в реализации.
Постоянное соединение
При масштабировании PHP приложений, возникает несколько непростых проблем. Одна из них — работа с данными сессии пользователя. Ведь если вы залогинились на сайте, а следующий ваш запрос балансировщик отправил на другую машину, то новая машина не будет знать, что вы уже залогинены. В этом случае, вы можете использовать постоянное соединение. Это значит, что балансировщик запоминает на какую ноду отправил запрос пользователя в прошлый раз, и отправляет следующий запрос туда же. Однако, получается, что балансировщик слишком перегружен функциями, кроме обработки сотни тысяч запросов, ему еще и приходится помнить как именно он их обработал, в результате чего, сам балансировщик становится узким местом в системе.
Обмен локальными данными.
Использование БД для хранения сессий
Используя собственный обработчик сессий, мы можем хранить их в БД. База данных может быть на отдельном сервере (или даже кластере). Обычно этот метод отлично работает, но при действительно большом трафике, БД становится узким местом (а при потере БД мы полностью теряем работоспособность), ибо ей приходится обслуживать все сервера, каждый из которых пытается записать или прочитать данные сессии.
Распределенная файловая система
Возможно вы думаете о том, что неплохо бы было настроить сетевую файловую систему, куда все сервера смогли бы писать данные сессии. Не делайте этого! Это очень медленный подход, приводящий к порче, а то и потере данных. Если же, по какой-то причине, вы все-таки решили использовать этот метод, рекомендую вам GlusterFS
Memcached
Чем больше у вас машин, тем больше вы можете отвести в этот пул памяти. Вам не обязательно объединять всю память машин в пул, но вы можете, и вы можете пожертвовать в пул произвольное количество памяти с каждой машины. Так что, есть возможность оставить большую часть памяти для обычного использования, и выделить кусок для кэша, что позволит кэшировать не только сессии, но другую подходящую информацию. Memcached — отличное и широко распространенное решение.
Для использования этого подхода, нужно немного подредактировать php.ini
Redis кластер
Redis — NoSQL хранилище данных. Хранит базу в оперативной памяти. В отличие от memcached поддерживает постоянное хранение данных, и более сложные типы данных. Redis не поддерживает кластеризацию, так что использовать его для горизонтального масштабирования несколько затруднительно, однако, это временно, и уже вышла альфа версия кластерного решения.
Другие решения
ZSCM неплохая альтернатива от Zend, но требует Zend Server на каждой ноде.
Если вас интересуют другие NoSQL хранилища и системы кэширования — попробуйте Scache, Cassandra или Couchbase.
Итого
Как видите, горизонтальное масштабирование PHP приложений не такое уж простое дело. Существует много трудностей, большинство решений не взаимозаменяемые, так что приходится выбирать одно, и придерживаться его до конца, ведь когда трафик зашкаливает — уже нет возможности плавно перейти на что-то другое.
Надеюсь этот небольшой гайд поможет вам выбрать подход к масштабированию для вашего проекта.
Во второй части статьи мы поговорим о масштабировании базы данных.
Горизонтальное масштабирование PHP-приложений
Постоянно растущее количество посетителей сайта – всегда большое достижение для разработчиков и администраторов. Конечно, за исключением тех ситуаций, когда трафик увеличивается настолько, что выводит из строя веб-сервер или другое ПО. Постоянные перебои работы сайта всегда очень дорого обходятся компании.
Однако это поправимо. И если сейчас вы подумали о масштабировании – вы на правильном пути.
В двух словах, масштабируемость – это способность системы обрабатывать большой объем трафика и приспособляться к его росту, сохраняя при этом необходимый UX. Существует два метода масштабирования:
Что такое горизонтальное масштабирование?
Проще говоря, кластер – это группа серверов. Балансировщик нагрузки – это сервер, распределяющий рабочую нагрузку между серверами в кластере. В любой момент в существующий кластер можно добавить веб-сервер для обработки большего объёма трафика. В этом и есть суть горизонтального масштабирования.
Балансировщик нагрузки отвечает только за то, какой сервер из кластера будет обрабатывать полученный запрос. в основном, он работает как обратный прокси-сервер.
Горизонтальное масштабирование – несомненно, более надёжный метод увеличения производительности приложения, однако оно сложнее в настройке, чем вертикальное масштабирование. Главная и самая сложная задача в этом случае – постоянно поддерживать все ноды приложения обновленными и синхронизированными. Предположим, пользователь А отправляет запрос сайту mydomain.com, после чего балансировщик передаёт запрос на сервер 1. Тогда запрос пользователя Б будет обрабатываться сервером 2.
Что произойдёт, если пользователь А внесёт изменения в приложение (например, выгрузит какой-нибудь файл или обновит содержимое БД)? Как передать это изменение остальным серверам кластера?
Ответ на эти и другие вопросы можно найти в этой статье.
Разделение серверов
Подготовка системы к масштабированию требует разделения серверов; при этом очень важно, чтобы серверы с меньшим объёмом ресурсов имели меньше обязанностей, чем более объёмные серверы. Кроме того, разделение приложения на такие «части» позволит быстро определить его критические элементы.
Предположим, у вас есть PHP-приложение, позволяющее проходить аутентификацию и выкладывать фотографии. Приложение основано на стеке LAMP. Фотографии сохраняются на диске, а ссылки на них – в базе данных. Задача здесь заключается в поддержке синхронизации между несколькими серверами приложений, которые совместно используют эти данные (загруженные файлы и сессии пользователя).
Для масштабирования этого приложения нужно разделить веб-сервер и сервер БД. Таким образом в кластере появятся ноды, которые совместно используют сервер БД. Это увеличит производительность приложения, снизив нагрузку на веб-сервер.
В дальнейшем можно настроить балансировку нагрузки; об этом можно прочесть в руководстве «Балансировка нагрузки MySQL при помощи HAProxy»
Сессионная согласованность
Разделив веб-сервер и базу данных, нужно сосредоточиться на обработке пользовательских сессий.
Реляционные базы данных и сетевые файловые системы
Данные сессий часто хранят в реляционных базах данных (таких как MySQL), потому что это такие базы легко настроить.
Однако это решение не самое надёжное, потому что в таком случае увеличивается нагрузка. Сервер должен вносить в БД каждую операцию чтения и записи для каждого отдельного запроса, и в случае резкого увеличения трафика база данных, как правило, отказывает раньше других компонентов.
Сетевые файловые системы – ещё один простой способ хранения данных; при этом не требуется вносить изменения в базу исходных текстов, однако сетевые системы очень медленно обрабатывают I/O операции, а это может оказать негативное влияние на производительность приложения.
Липкие сессии
Липкие сессии реализуются на балансировщике нагрузки и не требуют никаких изменений в нодах приложения. Это наиболее удобный метод обработки пользовательских сессий. Балансировщик нагрузки будет постоянно направлять пользователя на один и тот же сервер, что устраняет необходимость распространять данные о сессии между остальными нодами кластера.
Однако это решение тоже имеет один серьёзный недостаток. Теперь балансировщик не только распределяет нагрузку, у него появляется дополнительная задача. Это может повлиять на его производительность и привести к сбою.
Серверы Memcached и Redis
Также можно настроить один или несколько дополнительных серверов для обработки сессий. Это самый надёжный способ решения проблем, связанных с обработкой сессий.
Memcached и Redis – это чрезвычайно быстрые хранилища «ключ-значение», которые позволяют обрабатывать сессии PHP. Установив один из этих серверов, нужно открыть к ним доступ для остальных серверов кластера, после чего кластер сможет использовать этот сервер в качестве обработчика сессий. Также для этой настройки необходимо установить специальное расширение PHP и изменить параметры php.ini.
Более подробную информацию можно получить в официальной документации и руководстве PHP.
Согласованность файлов
На данном этапе нужно найти средство для поддержки согласованности загруженных файлов, поскольку они могут храниться на любом из нодов кластера.
Эту проблему можно решить несколькими способами. К примеру, можно использовать GlusterFS, инструмент, который создаёт хранилище для совместного использования, дублирующее весь загруженный контент.
Также можно внедрить объектное хранение; это может быть BLOB-хранилище или облачное хранилище. Однако такое решение внесёт множество изменений в базу исходного кода.
Балансировка нагрузки
Стандартным средством для балансировки нагрузки является открытый балансировщик HAProxy. Его используют проекты с очень большой нагрузкой (например, Twitter, Instagram, Imgur). Подробнее об установке и использовании этого инструмента можно узнать в руководстве «Балансировка нагрузки HTTP с помощью HAProxy на сервере Ubuntu».
Заключительные действия
Горизонтальное масштабирование приложения сначала кажется очень сложным и запутанным решением, однако оно помогает устранить серьёзные проблемы с трафиком. Главное – научиться работать с балансировщиком нагрузки, чтобы понимать, какие из компонентов требуют дополнительной настройки.
Масштабирование и производительность приложения очень тесно связаны между собой. Конечно, масштабирование нужно далеко не всем приложениям и сайтам. Однако лучше подумать об этом заранее, желательно ещё на стадии разработки приложения.
Горизонтальное масштабирование сервера приложений
Горизонтальное масштабирование играет большую роль в обеспечении производительности. На первом уровне масштабирования мы делим систему по функциям. Система SimpleOne разделена на четыре группы: клиентский сервер, сервер приложений, сервер баз данных и сервер файлового хранилища.
На следующем уровне осуществляется масштабирование в рамках одной функции. В этой статье мы расскажем, как осуществляется масштабирование сервера приложений в SimpleOne.
Принцип масштабирования
Сервер приложений координирует программу, обрабатывает пользовательские запросы, взаимодействует с БД и файловым хранилищем.
Может возникнуть ситуация, когда не хватает одного сервера приложений. В этом случае систему можно легко масштабировать, просто добавив новые серверы. При этом, так как серверы приложений не хранят данные, а только координируют работу системы, данные останутся консистентными при подключении через любой сервер приложений.
Оптимально распределить ресурсы помогает балансировщик сервера приложений. Задача балансировщика — распределить запросы на отдельные серверы, принять от них ответы и отдать клиенту. Смысл в том, что три сервера могут обработать в три раза больше запросов, чем один, исключая расходы на сеть и на работу балансировщика.
Введение балансировщика позволяет администратору выбирать, на какой сервер пойдут определённые запросы. Например, каждый день в семь утра происходит рассылка отчётов руководителям. По умолчанию система сама распределит нагрузку, но у администраторов есть возможность определить, какие серверы приложений будут использоваться для данных рассылок.
Преимущества горизонтального масштабирования сервера приложений
Масштабируемость
Так как сервер приложений осуществляет только логику приложения, но не хранит информацию, то пользователи, подключаясь к БД через разные серверы приложений, увидят изменения, сделанные друг другом. Можно без проблем увеличивать количество серверов приложений.
Отказоустойчивость
Если один сервер перегрузится или выйдет из строя, то балансировщик это определит и перенаправит запросы на другие серверы.
Заключение
Горизонтальное масштабирование даёт большие возможности для обеспечения производительности приложения. За счёт масштабирования сервера приложений система может поддержать одновременную работу большего количества пользователей. Однако влияние масштабирования сервера приложений на производительность системы ограничено, в данном случае «узким» местом системы становится сервер баз данных.