Серверная оптимизация — Что кешировать?

Понравилась статья — публикую ее здесь.

Всё. На этом можно было бы статью закончить, так как эта аксиома повторяется из года в год на форумах и конференциях и кочует из текста в текст на всех технических ресурсах. Однако это ёмкое «Всё» не поясняет деталей. Ведь существует достаточно широкая прослойка программистов, движки и проекты которых справляются с задачей без мемкеша и шардинга. Но момент нагрузки приходит, и приходится разбираться.
Для таких людей я и разобрал на запчасти это универсальный ответ высоконагруженных проектов.
Ограничимся изучением системы для веба. Попросту говоря, на привычном обычном сайте. Используете ли вы готовую CMS, или уже выросли до каркаса, или написали «с нуля» код для нестандартного проекта – основными элементами процесса приёма-отдачи данных всегда будут одни и те же узлы. Я их рассмотрю с точки зрения «Где что можно закешировать».

База данных

Даже если у вас файловая база, есть драйвер (ведь так?) который отвечает за выдачу необходимой информации.
Что тут у нас? Обычно располагать данные по алфавиту неэффективно, поэтому лучшие умы уже придумали огромное количество методов, способов и хаков по скоростной доставке информации на блюдечке. И вы должны знать, что БД не просто вводят индексы, а кешируют их, кешируют результаты запросов, оптимизируют структуру реляционных таблиц и пытаются лишний раз не сканировать тонны данных. Но, вера в гениев это одно, а проверка файла конфигурации на включенность данных механизмов – это долг каждого разработчика! Если у вас есть отдельный администратор сервера (или серверов), то при первом же зафиксированном простое оного заставьте его подкрутить гайки в настройках вашего самого важного узла. Изучите потребление памяти, фрагментированность и доступность дискового пространства для временных файлов.
Своевременное грамотное кеширование запроса может дать вам достаточно времени в условиях быстрорастущего проекта, для подкручивания гаек на всех последующих этапах.
Эта оптимизация доступна всем участникам регаты с полным доступом к хостингу и разобраться с темой придётся, рано или поздно.
Есть еще один шикарный полноформатный кеш, который называется реплика базы данных. Но вряд ли вы зачитаетесь данной статьёй, если в вашем проекте уже есть настолько сложная структура, как мастер база, её реплика, веб-сервер, файл-сервер и группа сбора статистики. В любом случае отдельная база для чтения может с натяжкой считаться кешем.

Логика (или наш Код, которым мы гордимся)

Язык программирования значения не имеет. Это просто инструмент обработки полученных данных. Даже если у вас не модульная структура и весь проект – это один файл, вы всё равно работаете с данными.
Если код ваш, то вы обязаны включать голову во время написании кода. Апологеты быстрой разработки и святого ORM скажут, что тут искать нечего и лучше кешировать где то в другом месте. Доля истины есть, однако каких только уродов не рождают скорописцы!
Итак, на что надо обратить внимание, когда мы уже смотрим в код?
Оптимизируйте запросы к базе. Зачем тянуть все данные, когда нужен только индекс и дата? Чем меньше запрос, тем легче БД его закешировать.
Определите с помощью утилит БД так называемые медленные запросы. Подумайте над индексами в таблицах или в перепланировании запросов и необходимых данных к кешированию это не относится, но раз уж мы тут, то пуркуа бы и не па прямо сейчас?
После стабилизации кода посмотрите где вы дважды обращаетесь к базе за одинаковыми или похожими данными. Может лучше сделать один запрос потолще, но потом полученные данные использовать в нескольких модулях/функциях/циклах? Это еще не кеширование, но вот дальнейшая оптимизация – вынос сложных или массивных результатов вычисления в кеш (в базу или файл) в виде сериализованного массива, или чего там вам удобно, будет очень кстати. И тогда промежуточные вычисления будут проводится быстрее, менее затратно и более комфортно для сайта, задач по расписанию и API.
Соберите всю мелочь, которая обычно болтается в сессии, в переменных, в куках в единое место (если позволяет политика безопасности) и обращайтесь к такой записной книжечке. Это лучше чем вызывать обращение к файловой системе, вызывать методы класса, которые вызывают функцию общего класса, которая выдаёт логин пользователя или, о ужас, дёргает базу простым запросом. Ведь вы не уверены, что чтение сессии происходит из ОЗУ а не из файла сессии? А может админ без спроса вынес сессию в базу а метод этого не учёл? Или логика кода предполагает интернациализацию через тонны абстракций и вызовы подфункций, а вам надо аяксом три раза вернуть слово «Корзина».

Заниматься кодом рекомендуется в последнюю очередь. То есть: бизнес налажен, база оптимизирована, внешний кеш работает, всё в порядке, расширяемся. Кешировать данные в этом узле следует на этапе оптимизации затрат на расширение серверной части или когда узкая математическая часть не успевает обрабатывать большие потоки данных. Такое случается в громоздких маркетинг-планах сетевых компаний, генерации отчётов по вычурной статистике и прочих подобных вещах. Результатом оптимизации будет всего лишь снижение нагрузки на не самом нагруженном сервере и оттянет время покупки балансировщика и второго серва.
Если вы еще сидите на CMS и начинаете думать про её оптимизацию, то пора переписывать движок под свои высоконагруженные нужды или докупить ОЗУ. Нет денег? Тогда срочно занимайтесь монетизацией ресурса, а не ковырянием недр кода!

Шаблонизатор

Вроде бы и код, но немного более специализированный. Этот элемент практически всегда присутствует и тоже важен для наших исследований.
Что такое шаблон? Это некая конструкция, которая служит сырьём для создания кода на последующей компиляции. Разница только в том, что в этом коде огромное количество тегов, строк и ссылок, которые перемежаются фрагментами логики. Вещь достаточно понятная, но я замечал, что многие начинающие не вникают в детали работы смарти и блица. А зря!
Если грубо. то шаблонизатор сначала ищет ранее скомпилированный код (или проверяет его актуальность). Если его нет, то он обрабатывает заново шаблон, записывает файл (удаляя иногда предыдущий). Иногда, разработчик просто забывает включить подобное кеширование шаблонов (в рабочей версии неудобно чистить кеш). Хуже, когда опция включена, но время жизни предкомпилированного файла невелико. Тогда задержка нерегулярна и «отловить» её начинающему спецу сложно. Синдром «У меня не тормозит».

Разберитесь в возможностями кеширования вашего шаблонизатора, подберите оптимальные промежутки обновления (если это надо). На крайний случай поставьте задачу в расписание по принудительному обновлению этого кеша ночью, чтобы не вылезло в пике. Изучите скоростные характеристики того диска, где хранятся кеши. Может имеет смысл и есть возможность вынести в ОЗУ?
Настройка кеширования этого этапа обязательна в начале развития проекта. А вот перебор оптимальных значений уже можно перенести на после тюнинга базы и введения кеширования выдачи.
Для тех, кто сидит на готовой CMS, простора для фантазии тут маловато. Однако проверить что используется (алгоритм или готовый продукт), проверить где хранится кеш шаблонов и как он себя ведёт будет не лишним.

Результат

Его величество сгенерированная страница должна быть доставлена клиенту как можно быстрее с необходимой актуальностью. И тут мы можем что-то придумать отдельно, например файловое кеширование или любимый многими мемкеш.
Если вы всё с интересом еще читаете данную статью, то ваш проект, скорее всего, уже столкнулся с проблемами подтормаживания, но всё еще жив и работает в штатном режиме.
Для аксакалов проектовнедрения и сайтостроения нет ничего нового в настройке кластера мемкеша и их проблемы упираются в актуальность выборки. Но, спешу вас удивить, существует огромное количество проектов нормального размера, в которых руки вебмастера еще не добрались до нормального обычного кеша в noSQL БД. Сначала поднимали проект как могли, формировали идею на лету. Потом могло банально не хватить денег на второй сервер, куда стоило бы вынести нашу пухлую базу данных. Есть огромное количество людей, которые хорошо разбираются в бизнесе, дизайне, пишут хорошие тексты. Они подняли проект, но вот сил углубится в администрирование *nix чтобы установить мемкеш уже нет.
Короче говоря, если вы выросли из памперса, первое что надо делать, это кешировать готовую после шаблонизатора страницу. Сначала статику. Потом статические фрагменты динамических страниц. Дальше ищите своё бутылочное горлышко. Если нет прав для установки хранилища ключ-значение, сделайте себе на первых порах файловый кеш главной самых востребованных страниц. Даже такая примитивная вещь сэкономит больше, чем месяцы оптимизации на предыдущих узлах.
Пользователям систем управления контентом стоит поискать в закромах модуль кеширования для своей версии. Или даже наиболее удачный его вариант. К примеру MODx сразу включает механизм файлового кеширования как целых страниц, так и отдельных чанков и сниппетов. Но существует модуль, который вместо файлового хранилища предлагает воспользоваться мемкешем.

Балансировщик

Если у вас его еще нет, то он появится со временем. С его появлением вся лабуда сверху будет у вас называться бэкэндом, а наш подзаголовок назовётся фронтендом. Справедливости ради надо сказать, что файловое кеширование результата и фронтенд причудами архитектора может располагаться и рядом, и в обратном порядке. Но не будем усложнять таксономией простую статью для новичка.
Задача балансировщика разрулить очередь обычных запросов между всеми бэкендами, определить по типу запроса куда его направить и т.п. Главная оптимизация на этом этапе – отдача статических элементов, минуя все тяжеловесные баррикады из веб-серера с логикой и базой с данными. Это, главным образом, картинки, таблицы стилей, документы. Можно настроить отдельно файловый кеш, который будет отдаваться не бекендом, а напрямую балансировщиком. Надо всего лишь организовать поставку html (js, css, xml) страниц по нужному пути своевременно.
Можно написать свой модуль с персональной логикой кеширования результатов работы бэкэндов. Ведь ответ не обязательно бывает киломегабайтный. Можно разом для всех в памяти сервера балансировщика запомнить JSON с текущим лучшим игроком или последним твитом админа.
Прибегать к внедрению самого балансировщика можно на ранних этапах развития проекта. Ендженикс перед апачем много не съест, а масштабируемость проекта вырастет.

Клиент

Он тоже подвергается нашим уговорам что-то запомнить и не просить лишний раз нас занятых мучить всех демонов системы. И сами браузеры успешно пытаются избавить удалённый сервер от лишних мучений. Локально кешируются графические файлы и прочая мультимедия. Запоминаются пары логин-пароль, последние посещённые ресурсы и прочее. Но мы можем сделать еще более продвинутый вариант: ведь мы же знаем чего хотим от своей страницы!
В минимальном варианте, мы можем рассчитывать на хранение всякой персонализированной мелочи в печеньках. У флеша есть какой-никакой запас мегабайт для разгона. HTML5 нам даёт еще больший полигон для хранения записочек в формате огромных талмудов. Сохраните безопасную информацию на стороне клиента и модифицируйте страницу джаваскриптом. Корзина, последние отправленные сообщения, текущую амуницию и прочее.
Еще лучше, когда вы отвяжете логику своего приложения от привычного PHP и перенесёте на сторону нашего любимого пользователя. Сам скрипт закешируется браузером (а предварительно пулей отдастся енджениксом) и спокойненько на стороне сервера посчитает статистику персональных данных (покупок, бонусов, убитых монстров) из локального кеша.

Итоги подведём

Надеюсь для всех стартаперов-бизнесменов, а не технарей, вынесенная в заглавие фраза и короткий ответ теперь означают гораздо больше, чем просто необходимость заплатить денег за решение проблемы. Мы рассмотрели общую схему работы обычного веб-проекта в разрезе отдачи одиночного ответа пользователю и теперь понимаем что и когда и в какую сторону можно заоптимизировать кешированием. Прежде чем натравливать программистов на оптимизацию кода уже можно смело анализировать эффективность покупки ОЗУ или введения нового сервера с балансировщиком и мемкешем на нём же.
Как и чем именно кешировать – вопрос другой. Где и когда, думаю уже можно определить:
Настройте быстро базовые мелочи в конфигурации базы данных, проверьте кеширование шаблонизатора и|или CMS. По возможности сразу настройте балансировщик и организуйте отдачу статики минуя веб-сервер.
Кешируем результат (статику, фрагменты динамики, полный кеш) в файлы или key-value хранилище.
Глубоко изучаем нашу базу данных и настраиваем максимально эффективное кеширование запросов, проводим оптимизацию ключей. Возможно пора вводить реплику.
Изучаем внутренности нашего шаблонизатора, оптимизируем параметры. Возможно меняем привычный Smarty на более быстрый, но сложный в реализации Blitz. Сокращаем и ускоряем файловые операции на этом уровне.
Устраняем косяки и излишки нашего кода. Оптимизируем работу с данными из базы и приводим в порядок работу с мелочью.
В работающем коде и отработанной бизнес-логике проекте начинаем переносить на сторону клиента рутинные операции, персонализацию и её обработку.

И не забываем: кеширование – это не единственный метод оптимизации проекта!
http://habrahabr.ru/blogs/server_side_optimization/129623/