Производительность «1С-Битрикс»: кэширование

В своей работе мы часто сталкиваемся с «1С-Битрикс: Управление сайтом». Мы разделяем боль всех тех, кто пишет о его недостатках, но в то же время понимаем и сторону тех, кто «просто умеет его готовить». Этой статьей мы бы хотели открыть цикл материалов об оптимизации производительности битрикса.

Где бы и когда бы вы ни услышали апологетов битрикса, будь то маркетологи, продающие решения для интернет магазинов, или специалисты битрикса, пытающиеся защищаться от критики из-за низкой скорости работы, они точно будут говорить про кэширование. Приведу небольшую цитату из официальной документации:

Цитатник веб-разработчиков.
Антон Долганин: На данный момент кеширование Битрикса фактически совершенно, и не стоит изобретать своих велосипедов.

И еще одну:

Если в качестве примера брать интернет-магазин, то для каждого товара будет создан файл в кеше, чтобы при следующем обращении покупателя сервер не напрягался с запросами к БД. Это и позволяет запускать магазины уровня Эльдорадо.

Что ж, раз уж Эльдорадо не смогли обойти стороной такой важный вопрос, то и мы начнем именно с него.

Но хватит лирики. Дальше приведем сухие и сжатые строки нашего внутрикорпоративного регламента по «1С-Битрикс: Управление сайтом».

Каждый проект должен разрабатываться с включенным кэшированием «1С-Битрикс: Управление сайтом». Это следует делать для того, чтобы на этапе разработки выяснить все возможные проблемы и ошибки, связанные с кэшированием.

Число запросов к базе данных при включенном кэшировании должно быть сведено к минимуму. Каждая страница должна делать только необходимое и достаточное число запросов к базе данных.

Диагностику числа запросов со страницы можно производить встроенными средствами «1С-Битрикс: Управление сайтом»:

  1. С помощью тестирования производительности «Монитором производительности»,
  2. С помощью вывода отладочной информации на странице.

При работе с кэшированием следует помнить, что весь код внутри кэша исполняться не будет. Предположим, что вам нужно поменять заголовок окна браузера в компоненте bitrix:catalog.element. Мы знаем, что в bitrix:catalog.element настроено и включено кэширование, а, значит, весь код в файлах template.php и result_modifer.php будет выполнен только один раз во время создания кэша. Соответственно, строка $APPLICATION->SetTitle(‘title’); внутри result_modifer.php при включенном кэше работать не будет. В таких случаях нужно использовать component_epilog.php.

Важным моментом при использовании кэша является правильное создание идентификаторов кэша. По умолчанию в каждом компоненте «1С-Битрикс: Управление сайтом» для создания идентификатора кэша используется массив входящих данных $arParams, поэтому, если мы будем в один из параметров передавать timestamp, то мы рискуем получить огромное количество файлов кэша, которое займет все доступное дисковое пространство. Это произойдет из-за того, что идентификатор кэша будет изменяться каждую секунду из-за изменения параметра, в котором передается timestamp. Поэтому нужно быть очень внимательным с такими опциями, как «Кэшировать при установленном фильтре» или при самостоятельном использовании кэша.

Отдельно нужно отметить то, что для компонента bitrix:menu по умолчанию кэш создается для каждой страницы сайта, на которой имеется данное меню. Если меню есть в шаблоне, то мы рискуем получить по одному файлу кэша меню для каждой страницы сайта. Если в шаблоне два меню, то по два. Если три, то по три и т.д. Это поведение можно и нужно отключить с помощью опции CACHE_SELECTED_ITEMS, установленной в N.

Нужно понимать, что при включении этой опции, выбор активного пункта меню («подсветка» текущей страницы) работать перестанет, поэтому этот вопрос нужно будет решать иными средствами.

При использовании в качестве ключа кэша одного или нескольких параметров, приходящих от пользователя, нужно помнить, что при невалидном параметре кэш создавать не следует. В противном случае возникнет проблема схожая с пунктом 5. Кроме того, входящие параметры от пользователя всегда нужно обрабатывать так, чтобы не создавался отдельный кэш для null, '' и 0. Предположим, что мы создаем кэш:

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

Следует создавать как можно меньше файлов кэша, которые покроют как можно большее число запросов. Например, существует инфоблок с событиями организации. На странице нужно выводить только те события, которые проходят в данный момент или пройдут в будущем и скрывать прошедшие. В таком случае нам следует исключить из идентификатора кэша параметр фильтрации '>=ACTIVE_FROM' =>; ConvertTimeStamp(time(), 'FULL'), а прошедшие события отфильтровать на стороне php. Пример:

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

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

Полезным может оказаться следующий шаблон (конечно, только в рамках битрикса — современные php фреймворки предоставляют намного более удобные инструменты решения таких проблем):

С другой стороны, если помимо запроса из базы данных, нам нужно будет провести довольно сложную обработку данных, то, наоборот, следует усложнить идентификатор кэша и создать побольше файлов, в которых будет храниться готовый к выводу в браузер пользователя текст. Предположим, что нам нужно вывести в json большой массив с городами, чтобы передать его через ajax. В таком случае есть смысл закэшировать именно строку с готовым к отправке json:

Большой прирост к производительности может дать переключение кэша с файлов на какое-либо более быстрое хранилище, например, memcache. Однако всегда следует помнить о возможностях сервера, на котором будет располагаться проект. Memcache требователен к оперативной памяти. Если ее будет мало, то мы рискуем получить постоянное вытеснение одних записей кэша другими, а, значит, постоянные запросы к базе данных.

Ссылки по теме:

  1. Кэширование.
  2. Кеширование компонентов.
  3. Кеширование в собственных компонентах.
  4. Кеширование при проектировании сайта.
  5. CPhpCache.
  6. Настройки кеширования.

Производительность «1С-Битрикс»: кэширование: 1 комментарий

  1. В четвертом листинге в 18 строке «$obCache->EndDataCache($vars);» скорее всего тут должна быть переменная $events

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

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