Магический Highload, или о высокой нагрузке.

Титан. Фото с сайта proza.ru
Титан. Фото с сайта proza.ru

И таки здравствуй, дражайший читатель.

Highload, или проекты с высокой нагрузкой, это, на мой взгляд, естественный этап развития любого профессионального программиста, работающего с современным web. Рано или поздно мы приходим к этому (а точнее, учитывая что мы в массе своей всё-таки не бизнесмены, а специалисты — нас находят те самые бизнесмены в лице HR-отделов корпораций). Так получилось, что вот и я попал в эту струю, и по правде сказать весьма доволен — highload вещь интересная и нетривиальная. Однако, интернеты довольно бедны именно технической информацией по хайлоаду. Почему так? Отчасти оттого, что выделить общие принципы построения высоконагруженных систем довольно сложно. Сколько уникальных пользователей / хитов надо, чтобы считать ресурс высоконагруженным? А какая архитектура системы подпадает под это определение? Какие хоть требования к этой архитектуре? Ответить на эти вопросы сложно, но я всё-таки попытаюсь.

И для начала хочется сделать небольшой экскурс в область высокой нагрузки, принципы построения, и так далее. Сразу скажу, я не истина в последней инстанции — highload это продукты как правило уникальные, и реализуемые под конкретные потребности, особенно учитывая шаткий баланс динамика/скорость. Я имею ввиду соотношение динамического (но «тяжёлого») содержимого, и статического — «лёгкого». Рассматривать предмет мы будем на примере абстрактного портала, скажем новостного.

Итак, с чего начинается высокая нагрузка? Эмпирическое правило (вроде сам придумал, да :) ) это когда с нагрузкой перестаёт справляться один физический сервер (сферический, в вакууме). Ну, не хватает его мощностей для обработки существующего потока посетителей. Даже если на нём 24 гигабайта оперативки, два четырёхядерных проца и SCSI накопители в RAID, плюс 100 МБит канал. К слову сервер такой способен вынести очень неплохую нагрузку, только он зараза дорогой. Попроще это схема 4 ядра + 4 гига, Sata диски, и всё тот же канал в 100 МБит. В принципе, учитывая цены, может оказаться дешевле купить пару серверных лезвий за 35 тысяч рублей каждое, чем одного монстра за 250 тех же деревянных килорублей. Да, дражайший читатель, оценка потенциальной нагрузки и железа под неё — тема необъятная.

Так вот, будем брать некий среднестатистический, подлинно сферический в вакууме сервер, скажем, конфигурацией 2-4 ядерный процессор (один) и оперативка от 2 до 8 гигабайт). Сколько способен вынести подобный зверь? Вообще, это зависит от работающего на нём программного обеспечения. Статическое содержимое (голые html страницы) отдаваемые каким-нибудь nginx, работающем под FreeBSD или, там, CentOS — практически не завалит такой сервак. Нет, ну предел, конечно, есть у всего, однако… В общем, 300-400 тысяч уникальных посетителей в сутки он гарантированно выдержит, а то и больше, и если умрёт, то только по каналу передачи данных или от переполнения оперативки. (Как вы понимаете — статика рулит, и мы к этому ещё вернёмся). Всё бы ничего, вот только в современном интернете (чортов Web 2.0! :) ) статика не котируется практически везде. Мякотку, в виде динамического содержимого, подавай теперь всем, да. Народ хочет, там, писать комментарии, ставить плюсики и минусики фотографиям, и инако делиться своим, как правило никому не нужным, мнением с окружающими (например именно это делает автор на этом блоге вот уже почти два года).

Вот тут то разработчики и начали полировать наждачкой головы, в попытке отшлифовать самородок и извлечь из черепа бриллиант решения этой дилеммы. Как, как спросите вы, реализовать проект, который выдерживал бы высокую нагрузку, и при этом был динамичным и вебдванольным? Решений наплодилось масса, да. Но спешу вас успокоить — их в первом приближении всё-таки не очень много. Итак, первый класс решений выражается фразой: «Не хватает одного сервера? Так нате вам два. (Или больше)». Иначе говоря, необходимо раскидывать нагрузку по разным серверам — масштабировать систему. Скажем, вместо одного сервера — заводится пять, с идентичным содержимым. «Ура!» крикнет наивный чукотский мальчик, «ресурс способен вынести нагрузку в 5 раз больше!». Так-то оно так, да, но здесь у нас всплывают проблемы с репликацией (поддержанием идентичности вот того, содержимого, на всех серверах), и балансировкой нагрузки между ними. Иначе говоря, как сделать так, чтобы пользователи не ломились на один сервер, а равномерно распределялись по всем, и при этом имели одинаковый функционал, одинаковые данные, и так далее — как в McDonald’s: «в любой стране вы получите то же самое»? А то, знаете ли, пользователь был-был на одном сервере, а потом его балансировщик кинул на другой, а данные сессии остались на старом. Для пользователя они безнадёжно пропотерялись, и ему надо как минимум залогиниваться заново. Неприятность, ога. Об этом мы поговорим в статье посвящённой распределению нагрузки.

Второй путь указанный мощным программёрским дзеном, это кэширование. Чем больше статики — тем лучше! :) Это действительно так, несмотря на веб-два-нульность, воспетую современными интернетами. Кэшировать в высоконагруженных проектах нужно всё, что можно, но не более того. «А как обеспечить динамичность содержимого», спросите вы меня? Очень просто — мы разделим содержимое на статическое и динамическое (и создал Б-г твердь, и отделил воду, которая под твердью, от воды, которая над твердью. И стало так). Условно говоря, есть несколько классов данных, разделяемые по частотному признаку изменяемости. Что эта абракадабра значит? Ну, есть данные, которые в 99% случаев не изменяются никогда, например картинки, или крайне редко (css и javascript файлы). Их можно назвать подлинно статическими. Есть данные, которые изменяются пользователем (написана новая статья, оставлен комментарий, поставлен плюсик в голосовании) — одним словом, пользователь не просто страницу прочитал, но и что-то на ней сделал. Это к примеру HTML-содержимое, которое генерируется из нескольких источников (БД, PHP). Третья категория — это данные, которые постоянно изменяются, что-то, что постоянно взаимодействует с пользователем, к примеру это Ajax-элементы, которые обязаны обеспечивать актуальную информацию (впрочем, их, ха-ха, кэшировать тоже можно). Основное отличие в том, что эти элементы «мгновенно» обрабатывают запрос пользователя с участием Backend скриптов (то есть например отправлен ajax-запрос на php скрипт, и тот его сразу обработал, например в БД записал). Ну и естественно по максимуму надо использовать кэширование браузером (нахрена подгружать по двадцать раз одну CSS, когда она при кликах на ссылках ни разу не меняется?!). Про это мы поговорим в заметке о, собственно, кэшировании для снижения нагрузки с highload проекта.

Третий путь — перенос максимума функционала на сторону пользователя. У него компьютер железный, он за ним один сидит, так что лишний javascript или flash у него на странице выполняющийся — не повредит. Скажем, строить графики по точкам лучше не на сервере, средствами какой-нибудь GD, а у пользователя, средствами этого вашего JavaScript. Аналогично предварительная обработка картинок, вычисления… В общем всё, что можно — надо переносить к нему, естественно не в ущерб безопасности и функциональности.

Четвёртый путь — правильно настроенное программное обеспечение сервера. Даже интерпретируемые языки, типа PHP, имеют громадное количество возможностей по оптимизации. Например простая связка Apache + PHP, установленный как модуль — меркнет по сравнению с nginx, работающим с интерпретатором PHP в режиме FastCGI, да ещё и с подгруженным PHP-оптимизатором, вроде XCache. Разумеется, архитектура среды, на которой выполняется ваше приложение, это тема скользкая и щекотливая, можно сказать практически интимная. Всё зависит от потребностей и возможностей, конкретной задачи. Однако некоторые базовые вещи я в соответствующей заметке постараюсь описать.

Немного особняком, по моему мнению, стоит такая интересная возможность как CDN — Content Delivery Network. Она позволяет разбросать вашу «статику» по географически распределённым серверам, ближе находящихся к юзеру. Особняком, потому как затрагивает темы кэширования, отчасти, и отчасти же тему размножения серверов. Плюс это сторонний сервис, как правило, потому решать — надо оно вам или не надо, стоит в каждом конкретном случае по-своему. Примерно в том же «особняке» обосновалась такая тема как оптимизация backend скриптов highload проекта.

Итог прост: чаще всего в реальных проектах задействуют сразу несколько методов оптимизации. Причем — практически везде основная идея: «Уменьшить нагрузку на серверах высоконагруженного проекта». Парадокс, но это так. В данном обзоре мы с вами просто посмотрели — что бывает, какие методы снижения нагрузки на сервер есть? Мы выявили увеличение числа серверов (масштабирование), кэширование содержимого, перенос функционала в машину пользователя, оптимизация и качественная настройка самих серверов, ну и оптимизация собственно ПО — скриптов, например — работающего на сервере.

В следующих статьях мы рассмотрим по отдельности все эти темы, более подробно. Вообще, я подумал — почему бы не представить некий высоконагруженный проект, абстрактный, само собой, который нам надо реализовать? И следующие статьи организовать по этому принципу: анализ-проектирование-реализация? Посмотрим, должно получиться интересно! :) Следующая статья выйдет как только у меня появится столько же времени, чтобы подумать и написать небольшое виртуальное ТЗ с оценкой. Не прощаюсь :)

Автор

Алекс Разгибалов

Сумасшедший мужчина, неопределённого возраста, наслаждающийся манией преследования. Паталогически недоверчив, эгоистичен, авторитарен. Вторичные диагнозы - программист и поц. Владеет английским языком на уровне около хренового разговорного. Также знаком с некоторыми другими языками. Интересуется всем и вся, за счёт чего в любой области знания являются поверхностными, неглубокими. Характер невыдержанный. Крепость - 55 градусов.

Магический Highload, или о высокой нагрузке.: 4 комментария

    1. Возможно и есть, но мне она не попадалась. Нет, ну можно сказать (условно), что вот 500 000 пользователей в сутки — это высокая нагрузка. Но через 5 лет эта характеристика будет некорректной, так как среднестатистический сервер+канал будут её легко выдерживать. Прогресс не стоит на месте же :) Потому я лично считаю для простоты, что высокая нагрузка — это когда одного сервера мало уже. И это тоже не точная характеристика, так как во-первых, неясно какого сервера, во-вторых, неясно какое ПО на нём работает. Например статическое содержимое вполне может безболезненно крутиться на одном сервере, и нагрузка на систему будет упираться в канал передачи данных.

      Например на работе у меня — довольно большая часть проектов крутится на архитектуре «2х2» — когда есть два основных зеркала проекта — «мастера», и два дополнительных — включающихся только в пиковые моменты или если упал один из мастеров. Соответственно контент между ними «синкается» по мере необходимости, а обращения проходят через сравнительно несложную балансировку через DNS. Причем учитывая архитектуру приложения — в принципе, теоретически, он может и на одиночном сервере работать (почти статика). Проект считается высоконагруженным.

  1. Спасибо за интересную статью. Касательно вопроса о численной характеристике — могу добавить, что понятие highload крайне относительное. Его нельзя мерять независимо от конкретного проекта.
    Также советую прочесить эту статью: http://highload.com.ua/post/%D0%A7%D1%82%D0%BE%20%D1%82%D0%B0%D0%BA%D0%BE%D0%B5%20highload%20%D0%B8%20%D1%87%D1%82%D0%BE%20%D1%81%20%D0%BD%D0%B8%D0%BC%20%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C

    1. Согласен, кстати — действительно годная статья по части замеров. Но вот опять-таки заставила задуматься фраза о том, что проблемы с производительностью по вине PHP бывают не часто. Вот вопрос, смотря как написано — мне доводилось видеть проекты с адовым кодом, с созданием кучи объектов и прочего. Хотя да, как правило узкие места это БД и канал…

      Кстати насчет профилировщика — пока что лучшее, что довелось видеть, встроенный в NuSphere PHP Editor, но увы, им давно не пользуюсь, перебравшись на шторм, но там он исключительно качественный и удобный…

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Собирать идеально - не обязательно, просто приблизительно соберите картинку (должен быть включен JavaScript).WordPress CAPTCHA