Пользователь
0,0
рейтинг
29 января 2014 в 09:41

Разработка → Горизонтальное масштабирование 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 приложений, возникает несколько непростых проблем. Одна из них — работа с данными сессии пользователя. Ведь если вы залогинились на сайте, а следующий ваш запрос балансировщик отправил на другую машину, то новая машина не будет знать, что вы уже залогинены. В этом случае, вы можете использовать постоянное соединение. Это значит, что балансировщик запоминает на какую ноду отправил запрос пользователя в прошлый раз, и отправляет следующий запрос туда же. Однако, получается, что балансировщик слишком перегружен функциями, кроме обработки сотни тысяч запросов, ему еще и приходится помнить как именно он их обработал, в результате чего, сам балансировщик становится узким местом в системе.

Обмен локальными данными.

Разделить данные сессии пользователей между всеми нодами кластера — кажется неплохой идеей. И несмотря на то, что этот подход требует некоторых изменений в архитектуре вашего приложения, оно того стоит — разгружается балансировщик, и весь кластер становится более отказоустойчивым. Смерть одного из серверов совершенно не отражается на работе всей системы.
Как мы знаем, данные сессии хранятся в суперглобальном массиве $_SESSION, который пишет и берет данные с файла на диске. Если этот диск находится на одном сервере, очевидно, что другие сервера не имеют к нему доступа. Как же нам сделать его доступным на нескольких машинах?
Во первых, обратите внимание, что обработчик сессий в PHP можно переопределить. Вы можете реализовать свой собственный класс для работы с сессиями.

Использование БД для хранения сессий

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

Распределенная файловая система

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

Memcached

Вы также можете использовать memcached для хранения данных сессий в RAM. Однако это не безопасно, ибо данные в memcached перезаписываются, если заканчивается свободное место. Вы, наверное, задаетесь вопросом, разве RAM не разделен по машинам? Как он применяется на весь кластер? Memcached имеет возможность объединять доступную на разных машинах RAM в один пул.

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

Для использования этого подхода, нужно немного подредактировать php.ini

session.save_handler = memcache
session.save_path = "tcp://path.to.memcached.server:port"


Redis кластер

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

Другие решения

ZSCM неплохая альтернатива от Zend, но требует Zend Server на каждой ноде.
Если вас интересуют другие NoSQL хранилища и системы кэширования — попробуйте Scache, Cassandra или Couchbase.

Итого


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

Надеюсь этот небольшой гайд поможет вам выбрать подход к масштабированию для вашего проекта.

Во второй части статьи мы поговорим о масштабировании базы данных.
Перевод: Bruno Skvorc
Владимир Болиев @voff
карма
104,2
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (57)

  • –7
    Возможно это притянуто, но мы вчера наблюдали как лег spark.ru после публикации spark.ru/job/829 вакансии Юрием Лифшиц с очень хорошей зп и опционом 7%. И ко всему прочему информация об этом была опубликована в паблике «Цукерберг позвонит» и т.д. и т.д. В общем сразу в течении минут 5 точно была 500-ая ошибка!
  • 0
    Вообще-то у redis есть master-slave, а так как записи в сессию сравнительно мало, то этого хватит в 90% случаев )
    • 0
      Если сессия используется по назначению, то вроде постоянно там хранится только id залогинившегося пользователя. Использовать её для кэширования не самая лучшая затея. Лучше кэш на том же редисе сделать.
  • +19
    Апач не нужен.
    • –3
      очень холиварненько :)
      • +2
        Вот сразу и минусят :) Я имел ввиду, что слишком категоричное высказывание, и иногда апач все-таки бывает нужен.
        • +2
          Расскажите, пожалуйста, о таких случаях, без сарказма, я действительно до сих пор не могу понять — зачем, кроме пресловутого htaccess?
          • +2
            Ну вот, кажется я таки и влез в заведомо проигрышный холивар, а всего лишь обратил внимание на излишнюю категоричность.
            Просто как по мне nginx и apache — это две очень разные штуки. Nginx быстр, apache умеет в целом больше, ну например так сходу — более подробно можно понять чем сервер в конкретный момент времени занимается например, есть модули которых нет в nginx и т.д. Получается такой логическое разграничение, быстрый фронтенд, не нагруженный лишними настройками и более тяжелый бекенд.

            В 99.9% проектов, это все конечно и не нужно, но когда проект высоконагруженный и к тому же очень сложный, могут разные моменты возникнуть, там и зоопарк технологий появляется и даже маленький процент рукожопия дает о себе знать и странные вещи могут оказаться необходимыми. Тут конечно можно делать из конфига nginx монстра, lua там еще заюзать, но тогда вся его прелесть начнет быстро пропадать. Вообще в таких проектах рецепта «давай те юзать nginx+fpm а дальше просто купим 100 серваков» быть просто не может, все индивидуально.

            Вообщем-то в контексте комментария вот так сходу нереально описать тонкие моменты, нужны примеры, обширные объяснения что и почему. Это тема для поста, наверное как-нибудь попробую написать, пожертвовав кармой :)

            Я никого не призываю юзать Apache, я просто против категоричных «не нужен, выкинуть» :)
            • +2
              Nginx быстр, apache умеет в целом больше

              От веб-сервера надо не так уж много. Тем более, что после создания nginx.inc его разработка серьезно ускорилась. Но уже сейчас его преимущества с лихвой покрывают архитектурные недостатки Apache. Буквально сегодня я собирал для нового сервера ngnix + cache_purge + pagespeed. И при том, что на нем будет работать в том числе и wordpress, мне не пришлось ничего переписывать на php или отказываться от каких-то возможностей.

              более подробно можно понять чем сервер в конкретный момент времени занимается например

              Ну так это не недостаток — это достоинство nginx. Он в рамках одного потока исполняет до десятков тысяч запросов и просто незачем рассматривать что именно в какой момент он делает. Однако статистика у него тоже есть из коробки и я ее использую для мониторинга нагрузки через munin.

              быстрый фронтенд, не нагруженный лишними настройками и более тяжелый бекенд.

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

              Я никого не призываю юзать Apache, я просто против категоричных «не нужен, выкинуть» :)

              Иными словами вы так же катеогично протестуете против субъективного мнения из-за его категоричности. :)
              • +2
                А я вот тоже не понимаю чем так категорично плох апач. Большого опыта работы с альтернативами нет, было 2 варианта:

                1. nginx + apache — довольно неплохо справлялся с нагрузкой, ну работал через чайлдов и имел некоторые огрничения, но такая архитектура может выдержать немало rps

                2. nginx + php-fpm — нагрузка на процах выросла по сравнерию с апачем, прироста в скорости никакого, возможно он сможет держать большую нагрузку, но было прекрасно видно, что время которое пришлось потратить на смену архитектуры ничем не окупилось.
                • 0
                  1. Может, но без апача будет больше свободной памяти. Да и зачем вам два веб-сервера? На фронтенд apache ставить нельзя категорически, ведь его легко заставить исчерпать память даже с мобилки. Если все задачи веб-сервера можно переложить на nginx (который к тому же в памяти не размножается), то это следует сделать хотя бы поэтому. Да и оперативка лишней не бывает — ее лучше использовать для query_cache или apc.

                  2. У php главная проблема производительности не в способе запуска интерпретатора. А в издержках самого интерпретатора. Не так уж важно сэкономить 10 мсек на замене mod_php yf php_fpm, когда движок сайта формирует страницу целую секунду. Если обработка запроса в вашем приложении тормозит, то главным образом не из-за апача, как такового, а из-за того, что код или его подгрузка занимает очень много времени, или работу блокируют операции с базой и фс.
          • 0
            В качестве Forward Proxy.
          • 0
            Модули апача. Например, тот же Flash Media Server является надстройкой над апачем. И из него легко можно выпилавается модуль для раздачи видео под hds.
    • 0
      О гуру! Просвяти, как разрулить AJP соединения без апача?
      • +2
        Напомните пожалуйста, мы всё еще говрим о масштабировании приложений на php?
        • –1
          Апач не нужен.

          Это настолько общее высказывание, что я прямо потерялся весь…
          • +2
            Ищите себя в теме статьи. Я же тоже мог начать рассказывать какая php плохая штука рядом с hadoop/erlang/tornado/nodejs/watever-async для проектов, которые надо масштабировать. Но я сдержусь, поскольку автору хотелось рассказать о проблемах тяжелых приложений на php и о том, о чем надо задуматься владельцам всяких drupal/joomla/wordpress, которые дошли до серьезной посещаемости. Я и сам как-то встрял с популярным сайтом на drupal настолько, что пол движка переписал, чтобы только серверов не докупать. Но и там мог возникнуть предел, за которым только горизонтальное масштабирование.
      • +3
        Ок, исправляю:

        Апач не нужен.¹

        ______________________________

        1. Апач не нужен в данном контексте, а так же во многих других, за исключением каких-либо специфических. И вообще это, на мой взгляд, удачная пародия на цитату из фильма, да еще и в рифму.
  • +1
    Redis… в отличие от memcached поддерживает постоянное хранение данных, и более сложные типы данных. Redis не поддерживает кластеризацию, так что использовать его для горизонтального масштабирования несколько затруднительно

    В этих более сложных структурах и есть профит редиса. Во-вторых, видел бенчи редиса на commodity сервере в 300К RPS.

    Вообще, статья не зачёт. Дальше «а файлы требующие серверной обработки пусть отсылает тяжелому Apache» можно не читать. Где про FastCGI/FPM, HHVM, грамотный тюнинг сервера, бд, правильная архитектура приложений (в которой кэширование по-умолчанию)? — с этого надо начинать.
    • 0
      Когда в короткой статье пытаются объять необъятное, то уже не стоит читать. Каждый момент системы и её создания — это отдельная большая песня со множеством вариантов и нюансов.

      Ну и опять же, разработка исходя из инструментов — бред.
    • 0
      Обо всем этом можно почитать довольно подробно в этой книге :) www.scalingphpbook.com/
      P.S.: кто решится посмотреть чего за книга, прошу, не пугайтесь завидев аббревиатуру LAMP, в книге об Apache ни слова, там говорится о Nginx + PHP-FPM.
      • 0
        Кстати, если есть особо желающие и немогущие по каким-либо обстоятельствам купить, могу поделиться через личку :)
    • +2
      Во-вторых, видел бенчи редиса на commodity сервере в 300К RPS.

      у меня более 20К rps не выходило…
      сколько раз убеждаюсь, что НЕЛЬЗЯ ВЕРИТЬ ЧУЖИМ ТЕСТАМ
      разные методики тестирования, разное железо, разные тараканы в голове тестирующих…
      редис вполне можно использовать для хранения сессий, при том — это вполне нормальное и жизнеспособное решение.
      Только надо помнить, что редис:
      1) держит все данные в оперативной памяти и её может не хватать… тогда он лезет в своп и все начинает тормозить
      2) синкует данные в бэдграундоввском процессе путем форка. Для этого нужно памяти еще ровно столько — сколько занимает сам редис, иначе форк будет неудачным. По этому, на одной машине с большим объемом памяти лучше развернуть кластер из трех и более экземпляров редиса.

      Пример для понятия сути проблемы:
      Пусть физический сервер имеет 16Гиг, тогда мы можем запустить:
      один экземпляр редиса использующего не более 8 Гиг
      два экземпляра редиса, использующего не более по 5.3 Гиг, общая используемая память 10.6 гиг
      три экземпляра редиса, использующего не более по 4 Гиг, общая используемая память 12 гиг

      шардирование редиса происходит на клиенте, это три строчки кода и не является проблемой.
      • +1
      • 0
        Конечно, большинство бенчей — синтетика, имеющая мало общего с продакшном. На оф. сайте Редиса бенч показывает 75K rps. Да даже запас в 20К rps достаточно большинству проектов.

        По остальному, как видно, тюнинг одного только редиса тянет на отдельную тему.
      • 0
        appendonly не пробовали использовать?
      • +1
        у меня более 20К rps не выходило

        На Core i7 при подключении через unix socket (при такой производительности это имеет очень большое значение) Redis выдает стабильные 220K RPS. Проверял лично.
        • 0
          +1, особенно если socket расположить на tempfs ;)
        • 0
          А какой там был объем данных в кэше? Какой размер объекта, который вы доставали? Сколько потоков использовали на клиенте, сколько на сервере?
          Вы доставали по одному и тому же ключу или по разным?

          В общем, расскажите, что и как измеряли?
          • +1
            я же говорил
            разные методики тестирования, разное железо, разные тараканы в голове тестирующих…

            зависит от кучи факторов, и результаты рознятся даже до 50%
            например:
            — выбор последовательного/рандомного чтения/записи (не знаю почему, но влияет)
            — в одном соединении или на каждую команду — своё соединение
            — кол-ва запущеных тестовых клиентов(потоков)
            — длинна блока данных
            — пушим данные в пустой редис или там уже понапихано 10М ключей
            и мн. другое.
            • 0
              Я потому и спрашиваю. Просто с трудом верится, что можно на одном инстансе хранилища получить 200+ К prs, имея наполненные данными кэши, ведь в эти цифра должна влезть и серилизация/десериализация запроса + поиск по ключу + серилизация/десериализация ответа.

              Первое слагаемое зависит от размера ключа
              Второе в общем случае константа, но если мы говорим об операции put, то время выполнения зависит от наполненности данными (при большом объеме данных количество коллизий будет расти)
              Третье зависит от объема ответа
          • 0
            Бенчмарк — стандартный, идущий в комплекте с Редисом. Много информации здесь: redis.io/topics/benchmarks.

            В моем случае не являлось целью определить, насколько быстр Редис в одном или другом случае — я просто хотел увидеть цифры, которые есть по ссылке выше, своими глазами.

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

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

            И если уж пошло про узкие места — поставить на колени реляционную БД кривым приложением или критическими нагрузками намного, намного проще, чем Редис (собственно, в случае РСУБД чуть что не так — и резкая просадка). Так что, на мой взгляд, лучше или сравнивать в идеальных условиях, или не сравнивать вообще.
    • –2
      Дальше «а файлы требующие серверной обработки пусть отсылает тяжелому Apache» можно не читать. Где про FastCGI/FPM, HHVM, грамотный тюнинг сервера

      Для начинающего все упомянутые вами слова — лишняя головная боль и филькина грамота. Apache+mod_php ровно такой-же инструмент как и все упомянутое, но в отличие от них новичком настраивается быстрее и понятнее. Производительности ему хватит. Даже скорее всего в будущем будет так, что, если человек задумается о замене Apache+mod_php на FPM etc, то у него с горизонтальным масштабированием апачей уже полный порядок :-)
      • +5
        Apache+mod_php ровно такой-же инструмент как и все упомянутое, но в отличие от них новичком настраивается быстрее и понятнее
        Нет.
        • –2
          Отличный ответ! Я считаю, что таки ДА!
          • +3
            Таки нет :)
            Главная проблема Apache — многопоточность. Именно в моменты большой популярности он может съесть всю память и залипнуть или выпасть в swap. И самое главное «нет» в том, что новичкам лучше не выбирать что проще, а учиться делать надежные производительные системы или нанимать профессионалов. Не крутить носом и отвергать «правильные» решения в пользу привычных. В конце концов зачем нужна статья, которая утверждает, что поможет повысить устойчивость к нагрузке и при этом содержит самое явное «бутылочное горлышко» в виде Apache. (Кстати в следющей статье таковым будет Mysql, если я правильно понимаю направление мысли автора).

            Мой бы рецепт скорее всего состоял бы из изначального использования высокопроизводительной архитектуры с возможностями для горизонтального масштабирования. Например в случае с php я предложил бы писать приложение на reactphp.org, используя на фронтенде чистый nginx, а на бэкэнде MongoDB с GridFS, который имеет возможность горизонтального масштабирования «из коробки». При этом load balancer реализовал бы на основе dns и nginx.
            • 0
              Тогда цитируйте то, что хотите обсудить, я же видел цитату за простоту настройки :-)
              Чтобы учиться делать производительные системы и становиться профессионалом нужно знать недостатки всех остальных систем, разве нет? Я знаю достаточное количество довольно нагруженных проектов, которые используют Apache+mod_php, без особых проблем просто потому, что прежде, чем использовать тот или иной инструмент люди подумали головой и зная эти недостатки умеют их либо обходить, либо считают, что они несущественны по сравнению со «стоимостью владения» других решений. (Имеется ввиду, что найти на рынке *nix-админа, который сможет тупо развернуть «из коробки» LAMP гораздо проще и дешевле, чем гуру, способного собрать из некоторого количества true-on-the-edge решений что-то работоспособное, да и с разработчиками, четко понимающими суть этих технологий есть определенные проблемы).
              Кстати, dns балансер по-моему самое не очень хорошее решение балансирования, с моей точки зрения удобнее более управляемые решения, в зависимости от предпочтений это могут быть NGINX, HAProxy, Cisco CSS и т.п.
              • +1
                Тогда цитируйте то, что хотите обсудить, я же видел цитату за простоту настройки :-)

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

                Чтобы учиться делать производительные системы и становиться профессионалом нужно знать недостатки всех остальных систем, разве нет?

                Абсолютно не означает, что надо игнорировать хорошие советы, чтобы самому набить шишки.

                Я знаю достаточное количество довольно нагруженных проектов, которые используют Apache+mod_php, без особых проблем просто потому, что прежде, чем использовать тот или иной инструмент люди подумали головой и зная эти недостатки умеют их либо обходить, либо считают, что они несущественны по сравнению со «стоимостью владения» других решений.

                Я уверен, что под «достаточно нагруженными проектами» мы с вами понимаем несколько разные вещи. Разумеется никто не мешает ограничить настройками число форков apache, но именно с точки зрения горизонтального масштабирования Apache + mod_php представляет собой проблему. Впрочем это лишь при определенных условиях. Но при прочих архитектурных правильностях связка nginx + php-fpm ничем не уступает связке nginx + apache + mod_php по производительности, но выигрывает по нагрузке на процессор и количеству занимаемой памяти. Вопрос: зачем же нужен Apache, кроме нежелания переписать правила для mod_rewrite, если настройку связки нужно сделать всего раз, а недостатки архитектуры хлебать при каждом запросе к динамическому контенту?

                (Имеется ввиду, что найти на рынке *nix-админа, который сможет тупо развернуть «из коробки» LAMP гораздо проще и дешевле, чем гуру, способного собрать из некоторого количества true-on-the-edge решений что-то работоспособное, да и с разработчиками, четко понимающими суть этих технологий есть определенные проблемы)

                На мой взгляд вы очень поверхностно считаете затраты на админа. Никто не мешает обходиться shared-хостингом и пенять на его «нерадивых» админов, из-за которых ваш проект заDDoSили посетители. А можно один раз разобраться самому или заплатить специалисту за настройку связки на своем сервере и больше на это не тратиться. В любом случае тема статьи предполагает что потребность в масштабировании подкреплена возможностями. Хотя бы возможностями разобраться в теме и настроить самостоятельно. Иначе статья состояла бы из одной фразы «вам нужно нанять специалиста, который настроит вам горизонтальное масштабирование».

                Кстати, dns балансер по-моему самое не очень хорошее решение балансирования

                а мужики от и не знают :)

                $ for i in {1..5}; do host google.com | head -n 1; sleep 5; done; 
                google.com has address 74.125.143.113
                google.com has address 74.125.143.100
                google.com has address 74.125.143.101
                google.com has address 74.125.143.129
                google.com has address 74.125.143.131
                
                $ for i in {1..5}; do host yandex.ru | head -n 1; sleep 5; done;
                yandex.ru has address 213.180.193.11
                yandex.ru has address 213.180.204.11
                yandex.ru has address 93.158.134.11
                yandex.ru has address 213.180.193.11
                yandex.ru has address 213.180.204.11
                


                с моей точки зрения удобнее более управляемые решения, в зависимости от предпочтений это могут быть NGINX, HAProxy, Cisco CSS и т.п.

                Без dns-балансировщика они представляют собой единую точку отказа. Причем при горизонтальном масштабировании трафик упрется в производительность и полосу пропускания одного устройства, на котором и стоит load balanсer. Это вообще может лишить смысла горизонтально масштабированную архитектуру вашего сайта.
                • –1
                  Я уверен, что под «достаточно нагруженными проектами» мы с вами понимаем несколько разные вещи

                  Скорее всего разные, с нашей «колокольни» я считаю достаточно нагруженным 10-12 миллионов просмотров динамики в сутки — с этим вполне справляется и Apache+mod_php.
                  Но при прочих архитектурных правильностях связка nginx + php-fpm ничем не уступает связке nginx + apache + mod_php

                  Разве я говорил, что уступает? Конечно нет — вопрос «религии» скорее. Статья явно для «начинающих», у которых софтовую часть можно, скорее всего, «перепилить» так, что оно еще проживет какое-то время не то, что без fpm/hhvm etc, а и без масштабирования вообще.

                  Причем при горизонтальном масштабировании трафик упрется в производительность и полосу пропускания одного устройства, на котором и стоит load balanсer

                  Плохо излагаю свою мысль про dns балансировки, согласен. Объясню — откуда у пресловутых «начинающих», которым и адресована статья, возьмутся «большие» ip-сети хотя бы с десятком реальных ip? Более того! Откуда у них возьмется достаточная полоса на аплинке, чтоб все это законнектить? Да аплинк с реальным гарантированным гигабитом будет стоить часто дороже второго сервера. Про шаред хостинги я вообще молчу, вполне реальны ситуации, когда 1 IP на сотню «сайтов»

                  P.S> я нигде опять же не говорил, что «апач рулит, а fpm отстой», нет. Речь шла о том, что он такой же инструмент, им достаточно много пользуются, и он имеет место быть
                  • +3
                    я считаю достаточно нагруженным 10-12 миллионов просмотров динамики в сутки — с этим вполне справляется и Apache+mod_php

                    Вот почему мне не хотелось приходить к фактическим цифрам. Ведь тогда надо лезть в дебри. Мне в принципе не сложно, но будет ли всем полезен этот разговор, особенно учитывая, что вы «знаете» проекты с 10-12 млн просмотров, а я в таких копаюсь. Ну ладно. Попробую без занудства.

                    Для нагруженного сайта критически важно не суточное число запросов, а мгновенное. Что такое 10 млн суточных хитов (динамики)? Это 116 запросов в секунду при совершенно равномерном распределении за сутки. Так почти не бывает. Более харктерным является 16 нагруженных часов с двумя/тремя пиками нагрузки (развлекаловка вроде фишки.нет) или 50-100-200 рывков по 300-700% хитов на фоне тех же 16 часов среднего трафика (электронные сми). По той нагрузке, что есть у меня, 10 млн хитов должны давать пики в районе 400-500 запросов в секунду, которые по условиям задачи нужно обработать без DoS. Но и это еще не та цифра, которую стоит обсуждать. Нам надо посчитать количество одновременно обрабатываемых запросов и необходимые для этого ресурсы.

                    Берем идеальные условия — никаких тяжелых запросов к СУБД, nginx уберает необходимость держать процесс Apache в памяти пока посетитель не скачает всю сгенерированную страницу. Сколько времени в этих условиях будет занимать обработка одного запроса? Это снова сложный вопрос для абстрактного размышления — если взять за основу работу сложного фреймворка с большим bootstrap, то время работы процесса составит 80-100 мсек. Если это нечто легковесное, написанное без тяжелых абстракций, то 40-50 мсек. Для большей точности возьмем вилку 40 — 100 мсек. При нагрузке 500 запросов в секунду это даст нам от 20 до 50 параллельных процессов. Накладные расходы Apache составляют порядка 10 Мб и не забывайте процессорные затраты на fork. Итого лишних 200-500 Мб RAM и около 5-10 мсек драгоценного времени на процесс только ради того, чтобы отработали директивы из .htaccess.

                    И это, повторяю, в идеальных условиях. На практике же, чем больше параллельных запросов, тем больше времени процессы блокируются базой и другими издержками, вроде дисковых операций, обращения к memcache b/или opcode cache, затрат на переключение процессов в конце концов. А всё ради устаревшей архитектуры CGI и нежелания расставаться с .htaccess. Я вас уверяю — если ваши знакомые найдут в себе силы выбросить apache из цепочки обработки запроса, то они получат для серверов практически бесплатно запас стабильности еще процентов на 10-15, за счет использования сэкономленной памяти и времени. Вообще не меняя ничего в коде своих программ.

                    Разве я говорил, что уступает? Конечно нет — вопрос «религии» скорее.

                    Если в случае php-fpm речь идет исключительно об экономии ресурсов на запуск интерпретатора php, то при использовании настоящего асинхронного fast-cgi, вроде упомянутого выше react, (это не выходя за пределы php) можно вообще избежать в ходе обработки запроса накладных расходов на bootstrap, производя его один раз при старте приложения. Вот где на заметном объеме будет существенный выигрыш и Apache потеряет смысл как класс. И в тех же идеальных условиях такое приложение будет тратить на обработку запроса уже не десятки, а единицы милисекунд (ну или упираться в производительность СУБД и других синхронных компонентов).

                    Статья явно для «начинающих», у которых софтовую часть можно, скорее всего, «перепилить» так, что оно еще проживет какое-то время не то, что без fpm/hhvm etc, а и без масштабирования вообще.

                    А вот мне так не показалось. Apache тут упомянут вскользь, как не существенная часть идеи, а рецепта построения кластера вообще нет. Это исключительно обзорная статья для тех, кто хочет понять принципы решения задачи масштабирования, а не побыстрячку и не разбираясь, сделать антиDoS на дешевом vps/vds.

                    софтовую часть можно, скорее всего, «перепилить» так, что оно еще проживет какое-то время не то, что без fpm/hhvm etc, а и без масштабирования вообще.

                    Статья именно о масштабировании, так что вы явно не правы.

                    откуда у пресловутых «начинающих», которым и адресована статья, возьмутся «большие» ip-сети хотя бы с десятком реальных ip?

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

                    Да аплинк с реальным гарантированным гигабитом будет стоить часто дороже второго сервера.

                    Места надо знать. Сервер i7/32G/2T/1gbit стоит всего €41 в месяц у Hezner (без VAT, который жители наших стран не платят). Это копейки для проекта с 10 млн посещений в сутки. И там кстати каналов на 430Gbit, так что хватит на приличный кластер.

                    Про шаред хостинги я вообще молчу, вполне реальны ситуации, когда 1 IP на сотню «сайтов»

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

                    я нигде опять же не говорил, что «апач рулит, а fpm отстой», нет. Речь шла о том, что он такой же инструмент, им достаточно много пользуются, и он имеет место быть

                    Сейчас практически все хостеры прикрыли Apache nginx-ом снаружи, и с удовольствием бы от него избавились совсем, если бы не .htaccess, без которого ни один начинающий не сможет запустить свой сайт. :) Вот он и «имеет место быть».
                  • +1
                    я нигде опять же не говорил, что «апач рулит, а fpm отстой», нет.

                    Кстати php-fpm отлично подключается и к Apache. Я так делаю на серверах, где нужно совмещать сайты с .htaccess с остальными — на одних Работает nginx + apache + php-fpm, а н адругих nginx + php-fpm. И это получается даже стабильнее, чем с mod_php.
                    • 0
                      Ну замечательно. А апачевые переменные из $_SERVER и т.п. передаются ли в него?
                      Я тогда передам кое-каким ребятам, чтоб попробовали. В их случае выбор Apache (ну за ним и mod_php) обусловлен во-многом тем, что они используют свои модули к Apache (типа аутентификации и тому подобное)
                      • +1
                        С какой стати переменные окружения из спецификации CGI стали вдруг Апачевыми? :)
                        Конечно есть. wiki.nginx.org/HttpCoreModule#Variables
                        И с авторизацией всё в порядке. Читайте доки.
            • 0
              а на бэкэнде MongoDB с GridFS
              у Монги свои тараканы. Одна глобальная блокировка чего стоит :(

              и масштабирование из коробки — тоже через одно место сделано… Когда прижмёт — решардинг делать замучаетесь.
              • 0
                Ну так везде производительность достигается компромиссами. Нет никакой серебряной пули. Но и дела у Mongo не так уж и плохи на самом деле. Главное не запускать ее без репликации :) Кстати я не имел в виду шардинг. Простая полная репликация практически не приносит проблем.
      • +2
        но в отличие от них новичком настраивается быстрее и понятнее

        Весьма спорное утверждение
  • 0
    А ещё можно использовать например Google AppEngine — нам очень нравится.

    И с недавних пор PHP поддерживает.
    • –1
      И что на нём делать?
      Нет ни join, ни какого либо приличного поиска.
      Авторизацию для мобильного приложения на нём делать?
      • +1
        Там есть полнотекстовый поиск и индексы тоже есть.

        Если стоят задачи масштабирования то джойны — зло. Например тот же EBay использует MySQL, но не использует join насколько я помню.
        • 0
          | Если стоят задачи масштабирования
          Масштабирование не отменяет задачи целостности. Для масштабирование можно строить для клиента отдельные поисковые индексы(срезы), с разным периодом актуальности.

          Все истории успеха платформы AppEngine, который показывает Google — это самые простые задачи, аля авторизация для мобильного клиента (Angry Birds)

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

          Ну и оперативку AppEngin есть слишком много, вообще не адекватно дорого выходит.
          • 0
            Целостность там как раз гарантирована, правда «eventual» что конечно создаёт проблем. И порог вхождения не маленький — приходится сильно мозги перестраивать.

            Морфологического поиска да, нет. Но ничто же не мешает как внеший сервис прикрутить если очень надо. Полнотекстовый на чтение у нас работает нормально, правда пишем мы не так много.

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

            GAE очень хороший вариант когда в инфрастукртуре не разбирашься и админам не очень доверяешь или на админов денег нет.
            • +1
              Скажем так, нет дешевой целостности, которую можно достичь с помощью 3-тей простой формы представления данных (join в BD) Если нет средств на команду, то убивать кучу времени на создание надстройки для создания целостности информации — совсем плохое решение.
              Опять же, если задача не требует (например, хранение лишь авторизационных данных пользователей мобильного приложения) то AppEngine подходит. Но таких задач не много, что подтверждается самим Google и их «историями успеха».
  • +6
    Хранение сессий — это одна из небольших проблем масштабирования WEB-приложения.

    Надо точнее называть Вашу статью, например: «Решение проблемы сессий при масштабировании РНР прриложений»

    проблема балансировки практически не раскрыта… в основном прописные истины

    в целом, написано не плохо, продолжайте свой цикл, многим будет полезно.

  • +1
    Я бы назвал статью «Обзором основных инструментов», или что-нибудь вроде этого, и годиться она как вводная к большому циклу статей, с подробным описанием каждого инструмента. Иначе — просто ни о чем.
  • 0
    К разговору о редисе — можно ведь его шардировать + использовать в комплекте с относительно новым opensource-продуктом от твиттера — nutcracker (twemproxy). Да и репликация у редиса нормально работает, таким образом читать можно с энного количества слейвов, а писать в мастер.
  • 0
    memcache — 40-42k
    redis — 60-80k
    mysql+hs — 80-120k
    pgsql mode nosql — 40k
    oracle R11 relational cluster — 220k

    О чем вы вообще ребята?
  • 0
    Немного странная статья. Речь вроде о горизонтальном масштабировании, а все методы про создание единых точек отказа за кешем…
    Управление кэшем сама по себе нетривиальная задача, которая переходит и в код, который по условию меняться не должен…
    Надеюсь, часть 2 будет про shared-nothing, anycast/multicast, масштабирование https, избыточности. Ну и целевой SLA системы неплохо бы знать. А то флейм же

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