6 способов убить Ваши сервера — познаем масштабируемость трудным путем

Автор оригинала: Steffen Konerow
  • Перевод
Узнать, как отмасштабировать Ваше приложение, не имея при этом никакого опыта, — это очень нелегко. Сейчас есть много сайтов, посвященных этим вопросам, но, к сожалению, не существует решения, которое подходит для всех случаев. Вам по-прежнему необходимо самому находить решения, которые подойдут под Ваши требования. Так же, как и мне.

Несколько лет назад ко мне пришел мой босс и сказал: «У нас есть новый проект для тебя. Это перенос сайта, который уже имеет 1 миллион посетителей в месяц. Тебенеобходимо его перенести и убедиться, что посещаемость может вырасти в будущем без всяких проблем.» Я уже был опытным программистом, но не имел никакого опыта в области масштабируемости. И мне пришлось познавать масштабируемость трудным путем.

ПО сайта представляло собой CMS на PHP, с применением MySQL и Smarty. Первым делом была найдена хостинговая компания, которая имела опыт высоконагруженных проектов. Мы предоставили им свою требуемую конфигурацию:
  • Балансировка нагрузки (с запасом)
  • 2 веб-сервера
  • MySQL сервер (с запасом)
  • машина для разработки

Что мы получили (хостер сказал, что этого будет достаточно):
  • Балансировка нагрузки — Single core, 1 Гб RAM, Pound
  • 2 веб-сервера — Dual core, 4 Гб RAM, Apache
  • MySQL сервер — Quad core, 8 Гб RAM
  • машина для разработки — Single core, 1 Гб RAM

Для синхронизации файлов хостер установил DRBD в конфигурации active-active.

Наконец, время переноса пришло. Рано утром мы переключили домен на новые IP и начали мониторить наши скрипты. Трафик мы получили практически сразу и казалось, что все работает хорошо. Страницы загружались быстро, MySQL обрабатывал кучу запросов и все были счастливы.

Затем неожиданно прозвонил телефон: «Мы не можем зайти на веб-сайт, что происходит?!» Мы посмотрели в наше ПО для мониторинга и увидели, что сервера упали и сайт не работал. Конечно, первым делом мы позвонили хостеру и сказали: «все наши сервера упали. Что происходит?!» Они пообещали проверить сервера и перезвонить после этого. Спустя некоторое время они позвонили: «Ваша файловая система безнадежно испорчена. Что Вы делали?!» Они остановили балансер и и сказали мне посмотреть на один из веб-серверов. Открыв index.php, я был шокирован. Он содержал непонятные куски кода на Си, сообщения об ошибках и что-то, похожее на лог-файлы. После небольшого расследования мы установили, что причиной этому была наша DRBD.

Урок №1

Положите кеш Smarty в active-active DRBD кластер под высокой нагрузкой и Ваш сайт упадет.

Пока хостер восстанавливал веб-сервера, я переписал часть CMS таким образом, чтобы кеш-файлы Smarty хранились в локальной файловой системе. Проблема была найдена и устранена и мы вернулись онлайн.

Теперь это было начало дня. Обычно пик посещаемости приходился на конец дня и до раннего вечера. Ночью посетителей практически не было. Мы опять начали наблюдать за системой. Сайт загружался, но к приближению пикового времени нагрузка все возрастала и ответы замедлялись. Я увеличил время жизни кеша Smarty, надеясь, что это поможет, но это не помогло. Скоро сервера начали выдавать ошибки таймаута или пустые страницы. Два веб-сервера не справлялись с нагрузкой.

Наш клиент был на нервах, но он понимал, что переезд обычно несет с собой некоторые проблемы.

Нам было необходимо как-то уменьшить нагрузку и мы обсудили это с хостером. Один из их админов предложил хорошую идею: «Ваши сервера сейчас на Apache+mod_php. Может перевести на Lighttpd? Это небольшой проект, но даже Википедия использует его.» Мы согласились.

Урок №2

Установите на Ваши сервера веб-сервер «из коробки», ничего не настраивайте и Ваш сайт упадет.

Администратор перенастроил наши сервера так быстро, как только мог. Он отказался от Apache и перешел на конфигурацию Lighttpd+FastCGI+Xcache. Сколько сервера протянут на этот раз?

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

В следующие дни сервера справлялись с нагрузкой относительно хорошо, но в пиковое время они были близки к падению. Мы установили, что узким местом является MySQL и опять позвонили хостеру. Они посоветовали master-slave репликацию MySQL со slave на каждом веб-сервере.

Урок №3

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

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

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

Урок №4

Не планируйте ничего заранее и Ваш сайт рано или поздно упадет.

К счастью, мы продолжали наблюдать и планировать. Мы оптимизировали код, уменьшили количество SQL-запросов и неожиданно узнали о MemCached. Для начала я добавил MemCached в некоторые основные функции, которые были наиболее тяжелыми. Когда мы развернули наши изменения на продакшене мы не могли поверить результатам — как будто мы нашли Священный Грааль. Мы уменьшили количество запросов в секунду как минимум на 50%. Вместо покупки еще одного веб-сервера мы решили, что лучше использовать MemCached.

Урок №5

Не кешируйте ничего и тратьте деньги на новое железо или Ваш сайт упадет.

MemCached помог нам снизить нагрузку на MySQL на 70-80%, что повлекло за собой огромный прирост производительности. Страницу загружались еще быстрее.

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

Урок №6

Положите несколько сотен тысяч небольших файлов в одну директорию, забудьте об Inode и Ваш сайт упадет.

Да, это так. Мы были настолько заняты оптимизацией MySQL, PHP и веб-серверов, что не уделяли должного внимания файловой системе. Кеш смарти хранился в локальной ФС в одной директории. Решением был перенос Smarty на отдельный раздел с ReiserFS. Также мы включили опцию Smarty 'use_subdirs'.

В течение следующих лет мы продолжали оптимизацию. Мы поместили кеш Smarty в memcached, установили Varnish для уменьшения нагрузки на I/O систему, перешли на Nginx (Lighttpd случайным образом выдавал ошибку 500), купили лучшее железо и так далее.

Заключение

Масштабировани веб-сайта — бесконечный процесс. Как только вы исправите одно узкое место, скорее всего вы наткнетесь на следующее. Никогда не думайте «Это все, мы закончили». Это погубит Ваши сервера и, возможно, Ваш бизнес. Оптимизация — это постоянный процесс. Если Вы не можете выполнить работу сами из-за отсутствия опыта/ресурсов — найди компетентного партнера для совместной работы. Никогда не переставайте обсуждать с Вашими командой и партнерами текущие проблемы и проблемы, которые могут появиться в будущем.

Об авторе — Steffen Konerow, автор High Performance Blog.

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

    –3
    Шикарная статья… очень дельно всё. В мемориз…
      –17
      Да и кстати в большенстве случаев проблема решается всё же покупкой нового сервера ибо так проще и во многом дешевле чем время простоев и специалиста.
        +25
        Да вы правы в большенстве случаев нужно все покупать даже депломы и училку по рускому ненужно тратится по чем зря и серверы будут работать хорошо кто бы сомневался.
          –17
          > нужно все покупать даже депломы и училку по рускому ненужно тратится по чем зря

          По вам это, кстати, хорошо видно.
            +15
            это была ирония к предыдущему комментарию (:
              +5
              Зря минусуете, человек грамотно пишет, просто слишком саркастически пошутил.
                –2
                Какая-то толстая ирония… хотя специально залез, посмотрел его другие комментарии — пишет грамотно.
                  +3
                  Наоборот, слишком тонкая — так что даже не все замечают, что это, собственно, ирония.
            +3
            Решает ли это проблему?
              +1
              Ну на месяц решает :)
                +5
                А потом Ваш сайт упадет…
            0
            Хостер как я понял у Вас терпеливый и с дельным подходом к клиентам, посоветуете?)
            –3
            Мой совет, nginx (полноценный, т.е. без apache и прочего говна(php fastcgi)), лучше взять бобольше оперативы, и использовать apc либо memcache, постараться закэшировать все редкоизменяемые вещи (оперативка гораздо удобнее харда :) )
            Живой пример тому rutracker.org
              +3
              И еще, быстрее PHP только PHP, смарти хоть и удобен для дезигнеров, но от него лучше отказаться
                +3
                Быстрее PHP только HTML, а смарти позволяет использовать кэширование в HTML с достаточно гибкими правилами инвалидации кэша. Вряд-ли вы сможете быстро переписать CMS для того, чтобы обеспечить и шаблонизацию, и грамотное разделение логики и отображения, и гибкие возможности кэширования. Ну, или как вариант, напишете еще один смарти. Да, можно использовать тот-же blitz, и другие решения, написанные на C, как и blitz, но CMS потребует очень глубокой переработки, сомневаюсь что это экономически целесообразно. Докупить сервер точно дешевле и проще будет.
              0
              Мой совет, nginx (полноценный, т.е. без apache и прочего говна(php fastcgi))
              А что исполняет php в данной конфигурации?
                0
                Я имел в виду отказаться от шкафов, типа apache, lighttpd, вместо них используя php в качестве fastcgi
                  +6
                  А, я подумал, что php fastcgi тоже относится к говну, ок :)
                    0
                    А Лайти-то чем «шкаф»?..
                  –1
                  на деле все упирается в производительность базы и php, а не проксирование запросов от nginx к apache и обратно
                    0
                    Позвольте узнать, вы там программист или системный администратор?
                      –2
                      Я там знакомый :)
                    –2
                    Какая-то странная позиция для того, чтобы давать советы: «у нас все тормозило/падало, мы позвонили хостеру/администратору, он что-то сделал, используя [технологию], все заработало».
                      0
                      Сириуос Бизнес же! Платишь — люди за тебя работают.
                      0
                      Очень полезная статья. Есть другие интересные решения в области масштабирования, например апачевский hadoop. Не уверен что это подходит к CMS, но для систем где есть много различных серверных процессов и сервисов подойдет.
                        0
                        Лучше всего Hadoop подходит для пакетной обработки больших объемов данных (это когда у вас терабайты чего-то там и вы хотите какие-то рассчеты произвести над этим, используя пару десятков машин). Там где важно время отклика, он себя с ними ведет намного хуже. Я бы сказал, даже совсем не подходит. Хотя вот StumbleUpon как-то умудрились прикрутить к своему сервису HBase, но как я понимаю, читают они очень маленькие объемы данных (буквально несколько ячеек), так что проблема не так остра для них.
                        +5
                        DRBD active-active это вообще говоря типа ядерного реактора
                        умеючи — приносит свет и тепло, неумеючи — разносит всё так, что мало не кажется

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

                        ну и вообще говоря масштабируемость и PHP/MySQL, как говорится ...kommt nicht zusammen, kann man nicht binden, sind nicht verwandt… т.е. только с костылями и через тернии
                          +4
                          кстати, из статьи можно сделать вывод, что ваш хостер (администратор) был не профессионалом в своей области.
                          Нормальный админ никогда не поставит крупный проект на апач+мод_пхп
                            –1
                            «Почему FastCGI не ускоряет PHP» — dklab.ru/chicken/nablas/49.html
                            «mod_php vs CGI vs FastCGI» — dev.1c-bitrix.ru/community/blogs/howto/568.php

                            Вы то сами как профессионал тестировали?
                              0
                              Ну я во-первых не администратор, тем более не профессиональный :)
                              А во-вторых можно хотя бы nginx поверх было поставить, для отдачи статики хотя бы.
                              А про fastcgi читал этот материал. Спасибо
                            +8
                            На мой вкус статья банальна и очевидна. О каждом из пунктов в отдельности полно хороших статей.
                              +3
                              Никто и не спорит :) Автор приводит свою историю получения опыта в highload в боевых условиях. А также подчеркивает, что оптимизация не завершается никогда и ей нельзя научиться заранее — узкие места бывают разные.
                                +9
                                Истины вообще, как правило, банальны и очевидны. Делай зарядку по утрам, работай на любимой работе, а не ради денег, чаще гуляй на свежем воздухе, не пей, а если пьешь — закусывай.
                                И будешь богатым, умным и здоровым.

                                Такие уж они, эти истины. Но их банальность и очевидность нисколько не мешает людям на них класть снова и снова.
                                +7
                                Об авторе — Steffen Konerow, автор High Performance Blog.

                                Я надеюсь, этого в реальности не происходило и описано только в статье. Потому что апач+mod_php, отсутствие memcached, файлы в одной папке — это «вон из профессии» сразу.
                                  +5
                                  Если внимательно почиать статью, то на момент описываемого проекта у автора не было опыта в highload :)
                                  +1
                                  Кешировани смарти, к сожалению, весьма глючная штука, приводящая, иногда, к непредвиденным результатам. Ждем финала Смарти3, хотя более подходящее решение уже найдено:
                                  В нашем частном случае, мы статику кешируем через memcache и nginx отдает ее оттуда напрямую. Если не попал в кеш — проваливаемся в бекенд, который генерирует контент и сохраняет его в memcache
                                  При этом имеем:
                                  — возможность отдавать всю «статику» практически моментально
                                  — при потере кеша он быстро восстанавливается
                                  — динамические блоки собираются nginx через SSI (с предварительной проверкой на такую же закешированность в мемкеше). при этом собираются они параллельно и в случае отсутствия закешированного значения запросы «проваливаются» на разные бекенды одновременно (снижение нагрузки на каждый отдельно-взятый бекенд)
                                    0
                                    Походу админ крутой а программисты не очень раз такая система)
                                      +1
                                      походу, и админ и девелоперы круты, но шибко большой трафик, а такая система — заслуга системного архитектора, и экономит от 4 до 6 серверов для компании ;)
                                      0
                                      смарти ещё и тормаз редкостный…
                                        0
                                        но, блин, гибкий, сцуко… за то и любим… :(
                                          0
                                          х)) а какие из его гибкостей вы используете?
                                            0
                                            в частности (из наиболее критичных):
                                            1) динамически регистрирующиеся модификаторы и блоки
                                            2) поиск шаблона по заданному дереву (удобно для whitelabelling)
                                            3) замечательная изоляция в пределах инклюда (фетчинга) шаблона

                                            +
                                            4) пре-компиляция в качестве «гибкости» засчитывается?
                                            5) упрощенная логика приложения в шаблоне для неособо умного дизайнера засчитывается?
                                              –1
                                              1. а какие именно?
                                              2. это что такое? типа xsl:apply-templates?

                                              4. не, что тут такого? %-)
                                              5. логики там вообще не должно быть
                                          0
                                          но, блин, гибкий, сцуко… за то и любим… :(
                                            0
                                            Хабрахабр — Голосования
                                            Some error… We know…


                                            предыдущее сообщение прошу считать недействительным. смарти дважды гибкий, но не дважды любимый!
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                          +2
                                          теоретически, вероятный вариант
                                          а) nagios (или иная система) сидит внутрисети, а упали внешние каналы
                                          б) nagios (или иная система) долбит мало-зависящий от внешних факторов скрипт в качестве проверки живучести сайта
                                          в) nagios (или иная система) проверяет живучесть с интервалом в каждые 3-5 минут. у нас иногда Call Centre или Customer Support звонит на минуту-две раньше, чем приходит СМС с проблемой…
                                          0
                                          Ничего не написано про сам проект, непонятно какой он был. Иногда на сайте много картинок, тогда нужно оптимизировать одно, иногда много запросов к базе, тогда другое. Просто миллион посетителей в месяц — это примерно 30 тысяч в день, что на самом деле не так много для рядового сайта, поэтому очень не хватает описания специфики работы.
                                            +2
                                            Я один такой, скажите в чем профит от варниша(ваниша)??? Чем им кеш в nginx неугодил? там если юзать +perl+memcache можно вообще оч крутую систему кеширования организовать
                                              +1
                                              А причем тут, собственно, Perl?

                                              Про Варниш — строгий RTFM. Это просто другое средство для повышения производительности/масштабируемости.
                                              +5
                                              Записки Капитана…
                                                +3
                                                Не читайте хабр и ваш сайт упадет
                                                И не насилуйте особо сильно оптимизационую сторону, а то не из-за кого будет сайту падать.
                                                  0
                                                  Не хочу быть занудой, но apache по тексту вобще ни причем. У меня apache спокойно держит 80-100 запросов в секунду (на одном сервере) без падений и железо примерно такое же как у вас.

                                                  Сейчас вот что показывает:
                                                  Server uptime: 15 hours 28 minutes 34 seconds
                                                  Total accesses: 4096855 — Total Traffic: 6.8 GB
                                                  CPU Usage: u21245.7 s6862.09 cu0 cs0 — 50.5% CPU load
                                                  73.5 requests/sec
                                                  48 requests currently being processed, 0 idle workers

                                                  А по nginx — то он удобен и хорош в раздаче статики.

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

                                                  Кстати забыли написать про сессии в PHP — их тоже лучше хранить в memcache, для того что бы избежать проблем с I/O.
                                                    +1
                                                    апач может и больше обслуживать в секунду.

                                                    nginx ставят для того что бы апач быстро отдавал контент и освобождал форки, которые, если медленно отдают сеть контент (клиенты на модемах), в силу синхронной природы занимают форки (по одному на запрос) и упираешься в MaxClients (в отличии от асинхронного nginx или lighttpd).
                                                      +1
                                                      в целом проблема в том, что вместе с форками еще кушается память, и кушается ресурс ОС из-за переключения контексов.
                                                      0
                                                      Total accesses: 19283736 - Total Traffic: 24.0 GB
                                                      CPU Usage: u1022.5 s28.86 cu0 cs0 - .232% CPU load
                                                      84.6 requests/sec - 110.7 kB/second - 1338 B/request
                                                      4 requests currently being processed, 11 idle workers
                                                      

                                                      это я к тому что судя по вашим 48 воркерам у вас запросы по полсекунды генерятся, что уже не показатель быстрой работы.
                                                      А у меня и отработка быстрее, и проца меньше кушает. Правда не знаю чего он в статистике так мало рисует, там вообще где-то 30-40% нагрузка в среднем
                                                      0
                                                      30 тыс. посетителей в день на обычном сайте можно поднять и на среднем по мощности сервере безо всяких ухищрений.
                                                        0
                                                        безо всякого кеширования — чисто пхп+апач
                                                          +1
                                                          1. Смотря как эти пользователи «размазаны» по суткам. Автор пишет, что основной пик вечером, а ночью глухо. Если выбросить 10 часов на «ночь», получается 1М / 30 / (24 — 10) = 2380 в час. В пике нагрузка легко может прыгнуть в 5 раз от «среднего». Далее, не зыбываем, что это уники, которые делают несколько просмотров.

                                                          2. Надо учитывать, что из себя представлят проект: новостной сайт и youtube.com — это разные проекты.

                                                          Так что «30 тыс. посетителей в день… на среднем по мощности сервере» — это весьма спорное утверждение.
                                                          +1
                                                          Я бы ещё добавил замечание о файловом кэше. Если у вас был один сервер, а потом вдруг их стало два, то у каждого из них будет свой файловый кэш. Код может на это быть не рассчитан, причём сразу такие вещи имеют свойство быть не замеченными.
                                                            0
                                                            Мы установили, что узким местом является MySQL и опять позвонили хостеру. Они посоветовали master-slave репликацию MySQL со slave на каждом веб-сервере.

                                                            Я не понял. У них стало три mysql сервера? Один заявленный в начале мастер и по одному слейву на каждом веб сервере?
                                                              0
                                                              Да типа того… Селекты можно вгребать из локальных слейвов очень быстро
                                                              +1
                                                              Что бы Вы ни делали, Ваш сайт все-равно рано или поздно упадет. Закон Мерфи.
                                                                0
                                                                Как это замечательно, не только у нас все делают через жёпу, а потом разгребают :)
                                                                  0
                                                                  Пустите программиста заниматься инфраструктурой сервиса и ресурсами сервера, и он точно упадет :)

                                                                  Товарищам просто нужен был сисадмин: все кочки в статье уровня novice :)
                                                                    0
                                                                    Пустите сисадмина строить архитуктуру — и все разом упадет.

                                                                    Сисадмин нужен для быстрой и точной настройки всего и вся. Продумать же стратегию развертывания для конкретного решения должен архитектор.
                                                                      –1
                                                                      архитектор это главный строитель домов :)
                                                                    0
                                                                    А не из сисадминов ли и программистов вырастают архитекторы?
                                                                      0
                                                                      статья хорошая, написана с юмором
                                                                      все грабли известные… Ну сколько можно на них наступать по 10 раз.
                                                                      я долго смеялся.
                                                                      надо изначально разрабатывать архитектуру нормально.
                                                                      Понятно, что кто ни чеге не делает, тот не ошибается, но и учиться можно на чужих ошибках, а не на своих.

                                                                      Ну и в заключение nginx+php-fpm надежней чем lighttpd + spawn-php
                                                                      (спавнер имеет утечки)
                                                                        0
                                                                        Анти-паттерны хороши! Ёжики кололись и плакали :) Когда уже прекратят тестировать на юзерах? Тогда, когда юзеры перестанут им это позволять. В корпоративном сегменте это лечится финансовыми исками, после чего вся миграция проходит только через тестовые стенды и несколько видов нагрузочного тестирования. И, да, мы тестируем.

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

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