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

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проекта.

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

В следующих статьях мы рассмотрим по отдельности все эти темы, более подробно. Вообще, я подумал - почему бы не представить некий высоконагруженный проект, абстрактный, само собой, который нам надо реализовать? И следующие статьи организовать по этому принципу: анализ-проектирование-реализация? Посмотрим, должно получиться интересно! :) Следующая статья выйдет как только у меня появится столько же времени, чтобы подумать и написать небольшое виртуальное ТЗ с оценкой. Не прощаюсь :)
Теги:
Highload
Добавлено: 25 Мая 2018 07:33:36 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...