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

    Три года назад у меня была интересная задача. Необходимо было собрать платформу, объединявшую несколько стоек с серверами в единое целое, для динамического распределения ресурсов между сайтами написанным для 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

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

    Комментарии 64

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

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

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

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

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

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

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

                      Скажите, а что делалось если причиной нагрузки был сам код? ну скажем с новым релизом кто в коде делал интенсивную работу с диском. получается что такое приложение забивало все свободные «слоты» под виртуалки?
                        0
                        Как показала практика — дешевле было поставить пару новых серверов, чем делать оптимизацию.
                        Ну и конечно, если при постоянном значении трафика нагрузка резко шла вверх — разработчики уже делали дебаг и профайлинг у себя на стенде.
                        +3
                        ну вот загружает пользователь фоточку, как она синхронизируется по разным машинам?
                        или генерирует скрипт pdf-документ, делает запись в БД, кладёт файлик в папку /download, как этот файлик раскидывается по виртуалкам?
                          0
                          С помощью этого, а крутилось все на паре виртуалок и синхронизировалось через rsync
                          • НЛО прилетело и опубликовало эту надпись здесь
                              0
                              I/O всегда есть узкое место
                      +3
                      Хорошо, что еще есть люди на этой планете, которые пишут сноски (*) такого же размера шрифта, как и основной текст))
                        +2
                        вижу слова «облачный» и «виртуализация» — кастую amarao в тред.
                        Автору спасибо за статью, полезная, ушла в избранное. После долгого отсутствия, Андрей Роговский вернулся и начал снова писать нормальные технические статьи а не оффтопик про политику и мозг.
                          +4
                          занятно, но на 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
                            Тоже интересный вариант. А можно подробней при помощи чего именно перехватывались IP умирающих машин?
                              0
                              Это я тоже делал в свое время, немного иначе правда. Даже презентация на видео есть :)

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

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

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

                                                  PS: сокращения HN и VE взяты сугубо согласно документации OpenVZ, чтобы большинство читателей при надобности могли бы вникнуть в суть вопроса.
                                                  (если называть их общепринятыми среди админов именами, я бы выразился иначе)
                                                    0
                                                    Это определял не я а скрипты, по состоянию наименьшего LA на HN.
                                                    Оверюза небыло — в скрипте были забиты лимиты VE на HN.
                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                      0
                                                      Хранить в mysql
                                                      • НЛО прилетело и опубликовало эту надпись здесь

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

                                                    Самое читаемое