К основному контенту

Кэшируй, кэшируй, кэшируй запрос назло буржуазной Европе!

Обсуждение и дальнейшее развитие темы смотрите в блоге "WEB рукоделие". Комментируйте там же. Простите за неудобства.

Это опять пост про Shop-Script. Давно обещанная на форуме WebAssyst практика кэширования запросов многострадального ШопСкриптаПро.

Предыстория этого вопроса такова: одно время магаз на ShopScript работал у меня на довольно хилом VDS и посещения поисковых ботов практически клали сервер на обе лопатки. Типичная, так сказать, DDOS атака :-) Поэтому я озаботился производительностью самого скрипта. Предпринял следующие логичные, как мне кажется, шаги:

  1. Добавил недостающие индексы в разные таблицы с товаром, параметрами товара, категории, валюты и т.д.
  2. Убрал подсчет запросов категорий и товаров. Во-первых это оказалась бесполезная фича, во-вторых это было просто.
  3. Закэшировал несколько запросов.

Эти три пункта помогли решить проблему. Не знаю, какой оказал бОльшее влияние, но первого точно было недостаточно.

Объяснять как установить PEAR, добавить в include_path путь до него не буду.

Первый вариант кэширования я сделал с помощью класса Cache_Lite из PEAR. В общем-то можно было бы обойтись и просто сохранением в файл, но мне не улыбалось писать код для сравнения даты создания файла, вычисления устаревания кэша и т.д. – все это уже сделано, зачем мне писать то же самое?

Что бы нам такого закэшировать? Посмотрим код ShopScript’a. Ух-ты! Есть вот такой перл в самом index.php:

//load all categories to array $cats to avoid multiple DB queries
//(frequently used in future - but not always!)
  $cats = array();
  $i=0;
  $q = db_query("SELECT categoryID, name, parent, products_count, description, picture FROM ".
    CATEGORIES_TABLE." where categoryID<>0
    ORDER BY sort_order, name")
   or die (db_error());

   while ($row = db_fetch_row($q))
   {
      $cats[$i++] = $row;
   }

Загружаются подряд все категории товаров! Когда это 5-10 категорий – не очень страшно. Если общее количество категорий приближается к сотне, да еще есть описания, то общий объем данных получается очень приличным. Да еще этот код срабатывает при каждом запуске скрипта, нужен-не нужен – пофиг.

Категории меняются редко, поэтому вполне достаточно выполнять такой запрос, скажем, раз в сутки. Вот этим и займемся.

Создадим директорию cache и разрешим скрипту туда запись. Если директория в корне сайта, лучше в нее добавить файлик .htaccess со строчкой ‘Deny from all’.

В начало index.php добавим подключение класса Cache_Lite и создание экземпляра класса. У меня получилось вот так:

$cache_options = array(
  'cacheDir'=>$_SERVER['DOCUMENT_ROOT'] . '/cache/',
  'lifeTime'=>86400);
$cache_categories_id = 'category';
require_once('Cache/Lite.php');

$CacheLite = new Cache_Lite($cache_options);

В переменной $cache_categories_id – метка, по которой будет извлекаться данные из кэша. В общем, доку по Cache_Lite надо хотя-бы просто просмотреть.

А код, где делается запрос к БД на выборку изменим на такой:

//load all categories to array $cats to avoid multiple DB queries
//(frequently used in future - but not always!)

 if ($cats_str = $CacheLite->get($cache_categories_id))
 {
   $cats=unserialize($cats_str);
 }
 else
 {
   $cats = array();
   $i=0;
   $q = db_query("SELECT categoryID, name, parent,
                 products_count, description, picture
                 FROM ".
                 CATEGORIES_TABLE."
                 where categoryID<>0
                 ORDER BY sort_order, name")
       or die (db_error());

   while ($row = db_fetch_row($q))
   {
     $cats[$i++] = $row;
   }
   $CacheLite->save(serialize($cats), $cache_categories_id);
 }

Вот и все. Еще в том же index.php есть запрос на выборку всех валют – тоже хороший кандидат на кэширование.

Еще можно внимательно рассмотреть запросы при выводе информации о товаре (includes/produc_detailed.php) и подумать о том, что информацию о товаре тоже можно кэшировать. Но в случае изменения неплохо бы и сбрасывать кэш.

Схема с PEAR::Cache_Lite прожила довольно долго. VDS я сменил на другой, у которого памяти побольше было и это позволило установить кэшер байткода XCache. А некоторое время назад я обнаружил, что ZendFramework научился работать с этим самым XCache. И я переделал работу с Cache_Lite на Zend_Cache с бэкендом XCache. Теперь переменные хранятся вообще в памяти.

Популярные сообщения из этого блога

Sitemap для Shop-Script

С недавних пор наш национальный поисковик присоединился к славной компании поисковиков, умеющих обрабатывать файлы sitemap . Наверное, это связано с какими-то общеланетарными амбициями. Как бы то ни было, теперь есть возможность скормить Яндексу файл(ы) sitemap . Я решил, что обрабатывать сайт какой-нибудь сторонней приблудой много дольше, чем просто сгенерировать файлы sitemap с помощью скрипта. Тем более, что у shop-script в общем-то довольно простая структура. Новая версия Shop-Script с ЧПУ пока недоступна, получу — модифицирую скрипт. :-) Скрипт простенький, делает sitemap для aux-страниц — это у shop-script так называются обычные статические html страницы; страниц с категориями. Без разбивки на страницы 1, 2 и т.д. на мой взгляд эти страницы не слишком важны страниц с товарами и обсуждениями товаров Можно запускать из браузера, можно по cron’у. Корневую страницу сайта, страницу с новостями, страницу с формой обратной связи и т.п. надо записать в отдельный файл sitemap ...

Набережные

На бывшей доске почета, а ныне просто небольшой фотовыставке достижений Московского Судостроительного и Судоремонтного Завода (МССЗ) увидел пару интересных фотографий продукции этого завода на фоне набережных Москвы. Вот только сами набережные и годы съемки определить не смог. :) Знатоки подсказывают: первая фотография: Гончарная набережная у м.Таганская ; вторая: Фрунзенская набережная дом 34-32-26 .

Зеленые облака

Сегодня часов около 12 дня бежал по делам рядом со станцией метро Юго-Западная и обратил внимание на странный цвет неба. Поскольку прямо по курсу, километрах в трех-четырех находится железнодорожная станция "Очаково", решил, что там авария какая-нибудь. "Хлор или иприт" - внезапно промелькнула мысль. Странно, уроки НВП я, большей частью, прогуливал... Позже в Интернете прочел, что это сильный ветер поднял в воздух большое количество пыльцы. Сделал фотографию на планшет, убедился, что получилось плохо - цвета почти видно, и, так как торопился, не стал дальше заморачиваться. Вот сейчас еду в метро домой, попробовал немного задрать контраст и насыщенность. Может, получится чего.