Хостинг

индекс
165,70

Как сделать облачный (кластерный) хостинг за пару копеек*

Три года назад у меня была интересная задача. Необходимо было собрать платформу, объединявшую несколько стоек с серверами в единое целое, для динамического распределения ресурсов между сайтами написанным для LAMP платформы. Причем так, чтоб вмешательство в код сайтов было минимальным, а еще лучше — вообще отсутствовало.
При этом никаких дорогих решений вроде Cisco Content Switch или дисковой полки с оптоволокном использовать нельзя — не хватало бюджета.
А кроме того, разумеется, в случае выхода одного из серверов из строя — это не должно было влиять на работу платформы.

Голь на выдумки хитра


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

Начнем с начала, да прибудет со мной КО


У меня был выбор, на чем организовать платформу. Это OpenVZ и XEN. У каждого есть свои плюсы и минусы. OpenVZ имеет меньший оверхед, работает с файлами а не блочными устройствами, но не умеет запускать что-то кроме Linux'овых дистрибутивов. XEN позволяет запустить и Windows, но более сложен в работе. Я использовал OpenVZ, так как это более подходило для решения задачи, но вас-то никто не ограничивает в выборе.

Затем я разделил сервера на места под VDS, по одной на каждое ядро. Сервера были разные, по этому у меня был набор от 2-х до 16-и виртуалок на каждом из серверов. В «среднем по палате» вышло ~150 виртуалок на стойку.

Как синхронизацировать данные


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

База и API


Если с целостностью файлов было все просто, то вот с синхронизацией базы дело обстояло хуже. С начала я попробовал классический пример — master-slave, и столкнулся с классической проблемой: slave отставал от master (да, и спасибо за репликацию в один поток, очень большое спасибо).
Следующим шагом был Mysql-Proxy. Как сисадмину, мне подобное решение было очень удобным — поставил и забыл, только конфиг обновлять надо при добавлении/удалении новых VDS. Но у разработчиков было свое мнение. В частности, то, что проще написать некий класс PHP для синхронизации INSERT/UPDATE/DELETE запросов, чем изучать Lua, без которого Mysql-Proxy бесполезен.
Результатом их работы стал так называемый API, который умел находить соседей широковещательным запросом, синхронизироваться до актуального состояния и информировать соседей о всех изменениях с базой.
Но все же стоит изучить Lua и сделать нативный режим работы, когда все запросы будут синхронизированы с соседями.

Слава FreeBSD


Балансер — это можно сказать ключевой аспект платформы. Если упадет балансирующий сервер, то вся работа не будет иметь никакого смысла.
Именно по этому я использовал CARP для создания отказоустойчивого балансера, выбрав FreeBSD в качестве ОС и Nginx в качестве балансера.
Да-да, дорогущий NLB был заменен двумя слабыми машинками с FreeBSD (маркетологи в ярости).

И самое главное — как это работало


При старте платформы для каждого сайта запускалось по одной копии и monit на баланесере следил, за тем, чтобы первичная копия всегда работала.
Кроме того на балансере был установлен анализатор статистики Awstats, который предоставлял все логи в удобном формате, а главное — там был скрипт, опрашивающий каждую VDS по SNMP на предмет ее нагрузки.
Как мы помним, я выделял на каждую VDS по одному ядру, следовательно Load Average в 1 — это будет нормальной нагрузкой для VDS. Если LA становился 2 или выше — запускался скрипт, создающий копию VDS на случайном сервере и прописывал ее в апстрим nginx'а. А когда нагрузка на дополнительной VDS падала меньше 1 — соответственно, все удалялось.

Резюмирую


Если взять стойку с серверами и свитчем поддерживающим CARP протокол, то для создания облачного хостинга будет необходимо:
  • Изучить Lua и настроить прозрачную синхронизацию через Mysql-Proxy
  • Прикрутить биллинг для учета дополнительных копий VDS и трафика
  • Написать веб-интерфейс для управления VDS

*На заполнение стойки хватит суммы с четырьмя нулями. По сравнению с решениями от брендов, где цена одной стойки — сумма с шестью нулями, это действительно пару копеек.
+44
24 августа 2010, 15:26
95

комментарии (64)

+6
Rolex #
Классический пример кластера c аппаратной избыточностью, но никак не облака. :)
+2
Andrey_Rogovsky #
Почему?
При необходимости несколько серверов будут работать как один, когда нагрузка спадет — все вернется как и было раньше.
Это ли не принцип облака?
+3
ikoev #
Five essential characteristics of cloud technology:
On-demand self-service
Broad network access
Resource pooling
Rapid elasticity
Measured service
+2
Andrey_Rogovsky #
Отмечаем по пунктам:
1) Создание/удаление виртуалок происходит автоматом? Да.
2) Это требует дополнительной расшифровки
3) Пул под виртуалки я делал? Делал.
4) Мониторинг по smb есть? Есть, хоть раз в секунду запускай.
5) Опять-же трафик считаем nginx, а дополнительные виртуалки — через скрипт их создания/удаления

Итого 4 из 5, причем один пункт требует расшифровки.
+2
leave #
4 — вы уверены, что правильно понимаете, что такое «Rapid elasticity»?
+2
Andrey_Rogovsky #
Более того, я даже не всегда понимаю, что такое «правильно», так как все относительно.
Так что — больше конкретики.
–1
leave #
Каким боком «мониторинг по smb» до «ресурсы по запросу — здесь и сейчас»?
0
Andrey_Rogovsky #
Очень просто
Если мы видим, что на виртуалке большая нагрузка — делаем ее клон и распределяем нагрузку.
+15
twi #
On-demand self-service
захотелось — подрочил. Да.
0
ikoev #
смешно, да ;)

по всем вышеприведенным терминам найдите определение и поймете, что вы немного другое сделали, а не облако ;)
–1
Andrey_Rogovsky #
Это облачный хостинг, а не просто облако, да.
Ну так я и писал про это в заголовке.
–1
hippoage #
Для пользователей виртуалок вполне облако: 150 виртуалок достаточно большое число, если хотя бы 20 свободны для динамического расширения, то для большинста LAMP-сайтов вполне хватит. Никто же не спорит, что Amazon EC2 — это облако? А тут еще и автоматическое масштабирование (там только ручное без сторонних сервисов или скриптов).
–1
egorF #
На EC2 уже оч. давно есть автоматическое масштабирвание, чуть ли не с самого начала. Это одна из важнейших фич EC2.
+2
braindamaged #
>> Результатом их работы стал так называемый API, который умел находить соседей широковещательным запросом, синхронизироваться до актуального состояния и информировать соседей о всех изменениях с базой.

Это как? Ручная репликация на php, что ли?
0
Andrey_Rogovsky #
Да, именно она самая.
0
mitnlag #
Именно поэтому данное решение стоит намного дешевле брендов. Бренд подходит для большого круга задач, а Ваше — только для конкретно этой.
0
Andrey_Rogovsky #
Вполне, например — компилацию на нем не ускорить, OCR тоже.
Для хостинга — вполне себе решение.
+1
braindamaged #
И сколько у вас инстансов БД? И каждый DML/SML запускается по очереди на каждой БД?
Я чего-то не понял, видимо…
0
Andrey_Rogovsky #
Каждая виртуалка содержит в себе копию БД и всегда синхронизируется с остальными.
Выделенные виртуалки под БД разработчики не захотели использовать.
+1
braindamaged #
А как вы тогда выцепляете запросы, которые внутри выполняются, и отправляете их на другие виртуалки?
0
Andrey_Rogovsky #
Это решали разработчики, правя код. Как я и говорил — надо использовать MySQL-Proxy+Lua, и тогда все это будет работать нативно без правок кода.
+1
Goodkat #
Распишите подробней про синхронизацию данных, от скриптов до БД.
–1
Andrey_Rogovsky #
Синхронизация данных на файловом уровне:
lvcreate -L 10G -s -n instance01 /dev/volgroup/instance01template

Синхронизация БД — скрипт на php, у меня он не сохранился. Логика очень простая: Если идет запрос на изменение данных, то он выполняется на всех клонах виртуалки.

Будут более конкретные вопросы — будут более подробные ответы.
0
Tonik #
Такое решение синхронизации БД конечно говорит не в пользу разработчиков. :) Мне кажется проще было изучить Lua чем городить такой велосипед. Но это явно вопрос не к вам.

Спасибо большое за статью — вы дали пару очень интересных идей. И показали что «облако» это просто :)

Скажите, а что делалось если причиной нагрузки был сам код? ну скажем с новым релизом кто в коде делал интенсивную работу с диском. получается что такое приложение забивало все свободные «слоты» под виртуалки?
0
Andrey_Rogovsky #
Как показала практика — дешевле было поставить пару новых серверов, чем делать оптимизацию.
Ну и конечно, если при постоянном значении трафика нагрузка резко шла вверх — разработчики уже делали дебаг и профайлинг у себя на стенде.
+3
Goodkat #
ну вот загружает пользователь фоточку, как она синхронизируется по разным машинам?
или генерирует скрипт pdf-документ, делает запись в БД, кладёт файлик в папку /download, как этот файлик раскидывается по виртуалкам?
0
Andrey_Rogovsky #
С помощью этого, а крутилось все на паре виртуалок и синхронизировалось через rsync
0
pentarh #
Жесть. При определенном количестве контента, дисковое IO уйдет в жэпуа под тяжестью rsync'овых stat()'ов.
0
Andrey_Rogovsky #
I/O всегда есть узкое место
+3
black_crown #
Хорошо, что еще есть люди на этой планете, которые пишут сноски (*) такого же размера шрифта, как и основной текст))
+2
bondbig #
вижу слова «облачный» и «виртуализация» — кастую amarao в тред.
Автору спасибо за статью, полезная, ушла в избранное. После долгого отсутствия, Андрей Роговский вернулся и начал снова писать нормальные технические статьи а не оффтопик про политику и мозг.
+4
zeehond #
занятно, но на cloud не тянет никак

внедрённое и поддерживаемое нами рабочее HA/LB решение для LAMP-хостинга (не претендуя на громкое слово cloud) выглядело так

фронтенд:
2 мастер-хоста веб-фронтенд — DRBD active-active репликация
для избежания split brain, разумеется, fencing
N (в перспективе до бесконечности) вторичных хостов веб-фронтенда — реплицируются с мастеров rsync-ом
все изменения делаются на любом из мастер-хостов, далее сами расползаются по кластеру

DNS-round-robin load balancing — дешёво и сердито
IP адрес внезапно умершей ноды перехватывает соседняя по кластеру нода
пользовательские сессии реплицируются по кластеру через memcache

база данных:
1 активный мастер MySQL
1 спящий мастер, репликация файловой системы DRBD active -> passive на несмонтированный раздел
при умирании активного мастера спящий просыпается, перехватывает IP активного на себя, монтирует раздел, поднимает серверный процесс
ну и N (опять же до бесконечности) слейвов, которые реплицируются с мастеров

доступ PHP-кода через базу работает через класс, который все INSERT/UPDATE/DELETE гонит на мастера, все SELECT — на слейвов (случайно выбирая ноду)

HA выполняется полностью — при отказе _любой_ ноды система работает как ни в чём ни бывало, т.е. no single point of failure
LB выполняется везде, за исключением MySQL-мастера — но он со своими 32 гигами, 4х4 головыми Xeon-ами и SAS-дисками старается вовсю

в дальнейшем были сделаны некоторые улучшения, типа frontend-ноды берут весь контент не с локального диска, а с файлового сервера из двух связанных по infiniband NAS-серверов с DRBD active-active, добавлены сервера для кэширования и отдачи статического контента

в среднем всё это вместе держит нагрузку в 200-300, местами до 1000, запросов страниц в секунду
+1
Tonik #
Тоже интересный вариант. А можно подробней при помощи чего именно перехватывались IP умирающих машин?
0
Andrey_Rogovsky #
Это я тоже делал в свое время, немного иначе правда. Даже презентация на видео есть :)

Тут ведь дело в том, что у меня сайты — не клиентские а корпоративные, и у каждого разработчика свои требования по версиям софта, так что без виртуалок не обойтись.
0
pentarh #
Linux HA эт хорошо. DRBD смущает только. Чето он у меня даже в асинхронном режиме затыкался на запись (iostat drbd device idle 0%), в то время как исходный девайс (raid1 из 2х SASов) был нагружен по IO на 20%.

Уж я ему чего только не делал…
0
Andrey_Rogovsky #
Как давно это было?
0
pentarh #
Не далее как прошлой зимой
+1
AccessD #
А присутствует ли в вашем «облаке» присущая облакам гибкость по распределению ресурсов?
–2
Andrey_Rogovsky #
Смотря что считать за ресурс.
У меня он был один — это трафик, точнее его обработка.
+1
AccessD #
На отечественном хостинге трафик как раз не ресурс. Куда важнее предоставляемые мощности и место. Облако подразумевает, что вы получаете именно столько, сколько вам надо и вы имеете возможность управлять полученными ресурсами, наращивая и снижая их по мере необходимости.
0
Andrey_Rogovsky #
Трафик — это ресурс. Это посетители, которые приносят доход.
Про то, как выделялись ресурсы по необходимости — я уже написал.
+1
AccessD #
Это ресурс с точки зрения бизнес-модели, а сейчас речь о ресурсах этой карусели как платформы. И в данном случае трафик не в счёт, потому что в нормальных местах вы за него не платите при соблюдении определённого отношения отданного к принятому. Так что ваш кластер называть облаком, ИМХО, несколько некорректно, ибо тут нет той гибкости, которая подразумевается облаками.
0
Andrey_Rogovsky #
И какой конкретно гибкости нехватает?
–2
professor_kuvalda #
> На заполнение стойки хватит суммы с четырьмя нулями

за 100,00 рублей что ли?
–2
Andrey_Rogovsky #
Нет, блин, за 10 000 зимбабвийских фантиков.
0
LIAL #
копейки в нули не считаются
Думаю человек имел ввиду 10к$
+4
FreeLSD #
Роговский — профессиональный IT тролль.
Кластер с избыточностью можно сделать на связке XEN+DRBD+LustreFS используя Live Migration, но у меня эти Xen с Lustre так и не заработал
0
Andrey_Rogovsky #
Как я и писал выше — у меня был выбор OVZ/XEN.

0
phasma #
Во-первых, есть еще kvm. Во-вторых, есть уже готовый дистрибутив Proxmox, очень удобный для разворачивания виртуалок
0
Andrey_Rogovsky #
Значит три года назад этого еще небыло или было в нестабильном состоянии.
+2
schors #
Я только не понял одного — а зачем ты это всё сделал? Практиковался в написании скриптов удалённого вызова команд? Какую задачу ты решил, какую нельзя было бы решить отрезав вот этот лишний слой абстракции с поднятием/опусканием VDS? Где сравнительная характеристика «до» и «после» и резюме «позволило»?
0
sply #
основная задача — меньше работат руками, быстрее стартовать/останавливать инстансы
0
schors #
А прости, зачем их стартовать/запускать? :) Что в данном примере выигранно? Цена этой статьи:
ssh host su root -c 'start/stop'? :)
0
sply #
Вот это я не знаю, из статьи тоже не понятно, мутно как-то. Мне другое еще не понятно — зачем сначала нарезать физическую машину на мелкие вдски и потом запускать много мелких инстансов этих вдс — тут огромная потеря производительности впустую. Ладно бы если продавали каждый инстанс как амазон. Но ведь просто сайты хостились. Может быть и правда, чисто из-за красоты идеи.
0
schors #
Я это собственно и хотел сказать :)
0
Andrey_Rogovsky #
Потому что проектов было больше, чем физических серверов. Это раз.
У проектов были свои требования к софту — кому-то первый апач, кому-то второй, про PHP я вообще молчу. Это два.
0
Andrey_Rogovsky #
Затем, что при большой нагрузке на один сайт работало 2-5 серверов одновременно. Причем полностью автоматически.
До этого один сайт на одном сервере смог обрабатывать 1000 паралельных запросов, после сайт выдерживал 5000 паралельных запросов.
0
happybyte #
Странная цена на стойку с шестью нолями. Бренды как-то в последнее время сильно подешевели. В 4 ноля можно вложиться. Просто первая цифра не 1.
0
Andrey_Rogovsky #
Цены 3-х летней давности. Сколько сейчас стоит набить стойку — не считал.
0
stanly #
Андрей, а каким образом Вы определяли, на какой HN какой VE создавать?
Допустим (исходя из описания задачи), все HN имели одинаковую конфигурацию — CPU/MEM/HDD (если имели разную, мой вопрос усложняется).
Каким образом осуществлялся мониторинг overuse ресурсов на каждой HN, чтобы (не дай Бог) на определённой HN не создалось N к-во VE, которые суммарно превышали бы возможности самой HN? ;)

PS: сокращения HN и VE взяты сугубо согласно документации OpenVZ, чтобы большинство читателей при надобности могли бы вникнуть в суть вопроса.
(если называть их общепринятыми среди админов именами, я бы выразился иначе)
0
Andrey_Rogovsky #
Это определял не я а скрипты, по состоянию наименьшего LA на HN.
Оверюза небыло — в скрипте были забиты лимиты VE на HN.
0
pentarh #
Мне вот интересно, когда запустится две или более «копии сайтов», проблему, например, сессий PHP как решать будем?

Зашел юзер на первую копию, там у него сессия. Пошел, покурил, рефрешнул. И попал на другую копию, а там сессии то нет…
0
Andrey_Rogovsky #
Хранить в mysql
0
pentarh #
Ага. А если скрипты ведут какую то деятельность на файловой системе?

Я к тому что раз уж кластеризируете, то надо кластерную ФС совать.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.