Возьмём среднестатистический сайт.
Сайт динамичный и состоит из PHP скриптов, которые обращаются к базе данных(DB). На страницах так-же присутствуют картинки, css-стили и js-скрипты(назовём это статикой). Крутится всё это на web-сервере Apache.
В принципе это вполне себе рабочая схема, которой более чем достаточно для несложных сайтов с низкой посещаемостью.
Схематично это выглядит так:
Но как быть, если сайт стал популярен и посещаемость сайта увеличилась скажем в 5 раз?
Сайт начинает тормозить, пользователи получают ошибки.
В прошлый раз я объяснял природу этих явлений и пообещал рассказать как избавиться от этого без существенных затрат.
Понять из-за чего именно сервер тормозит не всегда удаётся.
Очень часто тормозит всё и сразу. Почему так происходит?
Дело в том, что срабатывает принцип снежного кома, и чем больше что-то тормозит - тем больше оно утягивает за собой и всё остальное. Если скажем php много работает с диском - то чтение из базы данных тоже может начать тормозить даже на оптимизированных запросах.
Наша задача - снизить нагрузку.
Если вы посмотрите на схему 1 - то первое что бросается в глаза - это то, что для получения статики пользователю приходится обращаться к апачу.
Почему это плохо?
Когда апачу необходимо обработать запрос - создаётся воркер апача, который обрабатывает этот запрос и после этого воркер умирает и освобождает использованные ресурсы. Тратить драгоценные ресурсы на отдачу статичных файлов нецелесообразно. Давай-те попробуем отдавать статику в обход апача. Для этого подойдет другой web-сервер, а именно Nginx.
Nginx и Apache могут корректно работать на одном сервере одновременно, могут и по отдельности.
Nginx - это простенький веб-сервер. Его используют для кэширования или в качестве прокси сервера.
Apache - более мощная система, у которой очень много возможностей, его можно гибко настроить и запустить фактически на любой ОС.
Если установить Nginx в связке с Apache и указать Nginx`у, чтобы он отдавал статику напрямую - то выглядеть это будет так:
Как видите-для отдачи картинок Apache не используется. Так-же Nginx может кэшировать статику и не обращаться каждый раз к файловой системе сайта. Такая оптимизация снизит нагрузку на процессор(Apache будет отъедать меньше) и на файловую систему.
Идём дальше.
Теперь пробуем разгрузить диск.
Так как база данных находится на диске - то чтение из неё информации и так-же запись - это работа с диском.
Если отказаться от операции записи в базу мы не можем - то откажемся от чтения. Для этого используем технологию Memcache.
В чём смысл этого ПО. Memcache представляет из себя key-value хранилище, которое хранится в оперативной памяти и как следствие работает очень быстро.
Понятно, что оно будет очищено в случае перезагрузки компьютера или остановки процесса Memcache, поэтому хранить в нём какие-то важные данные нельзя, их обязательно надо скидывать на диск.
Термин key-value означает, что данное хранилище хранит в себе информацию в формате ключ-значение. То есть положили вы туда какую-то информацию и дали ей конкретное имя. Потом по этому конкретному имени вы её можете получить или удалить. Каких-то таблиц(как базе данных) там нет.
Так-же перед тем как положить туда данные - вы можете указать их время жизни, например 10минут.
Язык, на котором написан сайт сайт, умеет работать с этим хранилищем, так что логика взаимодействия с Memcache определяется в коде приложения.
Выглядит это так.
В каком случае это используется. Например вы вытаскиваете из базы данных 300тысч строк, сортируете их как-то, что-то суммируете, где-то находите среднее значение, потом меняете формат данных и т.д. Это тяжёлая операция и выполнять её для каждого пользователя затратно. Тогда вы выполняете её 1 раз и результат выполнения кладёте в Memcache на 15минут. И когда нужно будет отдать эту информацию следующему посетителю - вы сперва ищете её в мемкэше и если находите-отдаёте. Если нет - тянетесь к БД. Таким образом мы 15 минут не дёргаете БД тяжелым запросом.
Если и такие манипуляции не помогли и вам хочется закэшировать всё что можно - я порекомендую вам Varnish.
Varnish так-же является кэширующей системой. Только кэширует он всю страницу целиком. То есть запросил пользователь страницу, php обработал запрос и сформировал html разметку данной страницы - всю эту разметку Varnish может положить к себе в кэш.
Кэш так-же как и в Nginx хранится строго заданное время, но может быть очищен при необходимости.
На сервере варниш стоит до апача и при поступлении запроса сперва ищет требуемую страницу у себя в кэше. Если находит-отдаёт посетителю, если нет - передаёт запрос в апач.
Схема:
Такая конфигурация сэкономит ресурсы процессора, снизит количество операций с диском и оперативной памятью.
За счёт того, что Varnish будет обслуживать запросы вместо Apache.
Вот вроде бы мы оптимизировали всё что можно, сервер работает быстро, посещаемость растёт.
Теперь мы конечно-же упрёмся в канал.
Что такое канал, кто, как и почему в него упирается я уже объяснял.
Если вы откроете отладочную консоль браузера - то на вкладке "Сеть" вы увидите, что браузер запрашивает все картинки, стили и скрипты которые прописаны на странице. Сама страница как правило весит совсем немного.
Именно статика и занимает большую часть канала. У всех сайтов по-разному, но как правило это может быть 80-90% пропускной способности канала.
Наша задача убрать эти запросы из своего канала и пустить их по другому каналу.
Для такой задачи используется технология CDN (Content Distribution Network), то есть сеть доставки контента. Это уже не софт на вашем сервере, а стороннее решение, которое стоит денег. Оплата производится по объёму траффика, который вы через неё пропустите. Поэтому каких-то фиксированных цен вам никто не предложит. Давать конкретные ссылки я не буду, в поисковике вы легко найдёте множество CDN контор.
Теперь подробнее. Под CDN подразумевается посторонняя организация(их много), у которой есть сеть из множества серверов с большими дисками и очень широким каналом. Эта сеть проксирует запросы(только к статике) на ваш сервер.
Как это работает.
Допустим у вас есть сервер с IP 10.10.10.10 на котором работает ваш сайт example.io . На нём же лежат картинки сайта. В админке регистратора вы прописали DNS вашего сайта на IP 10.10.10.10
CDN имеет IP 10.20.20.20
Далее вы создаёте в админке регистратора указываете, что поддомен cdn.example.io смотрит на IP 10.20.20.20 Таким образом, всё что будет запрошено с cdn.example.io будет отдаваться с серверов CDN, а не с вашего.
И теперь в коде сайта вы указываете всей статике абсолютные пути с поддомена cdn.example.io
Было
<img src="http://example.io/images/file.png">
Стало
<img src="http://cdn.example.io/images/file.png">
Теперь, когда посетитель откроет страницу сайта - то браузер попытается открыть картинку с поддомена cdn.example.io .Если это было сделано впервые - то CDN обратится к вашему сайту, заберет эту картину и сохранит у себя. И в дальнейшем будет отдавать её всем со своего сервера. Хранить он её будет очень долго.
Таким образом посетители будут забивать канал до сервера с IP 10.20.20.20 , а ваш с IP 10.10.10.10 нет.
Ну и рисунок для наглядности.
Вот путём таких оптимизаций можно существенно повысить производительность системы в целом, не вливая деньги в мощность сервера, так как это выйдет значительно дороже.
Привет!
Этот пост был выбран Академией Голоса и попал в список программы поддержки качественных образовательных постов.
Ссылка на твой пост будет опубликована в отчете Академии.
Спасибо за полезный контент (ノ◕ヮ◕)ノ*:・゚✧