PHP Performance Series: Caching Techniques

Автор оригинала: Mike Willbanks
  • Перевод
Кеширование промежуточного кода (Opcode Caching)
Кэширование кода это один из самых легких и эффективных путей увеличения производительности в PHP. Использовании данного вида кэширования позволит избавиться от большого количества неэффективностей, возникающих при процессе запуска выполнения кода. Кэширование кода сохраняет промежуточный код в памяти для того чтобы не компилировать PHP-код каждый раз при запуске файла.

Существует множество библиотек для такого кэширования, например, APC, XCache, eAccelerator и Zend Platform.

Кэширование промежуточного кода файлов
Когда у нас есть большое количество кода и наш сервис отличается большой посещаемостью, скорее всего мы не будем ждать, когда каждый PHP-файл будет обработан при его вызове, логично в этом случае запустить некий скрипт перед выкладкой кода на сервера, который сразу создаст промежуточный код. Например, код такого скрипта может быть реализован так
/**
* Compile Files for APC
* The function runs through each directory and
* compiles each *.php file through apc_compile_file
* param string $dir start directory
* return void
*/
function compile_files($dir)
{
  $dirs = glob($dir. DIRECTORY_SEPARATOR. '*', GLOB_ONLYDIR);
  if (is_array($dirs) && count($dirs) > 0)
  {
    while(list(,$v) = each($dirs))
    {
      compile_files($v);
    }
  }
  $files = glob($dir. DIRECTORY_SEPARATOR. '*.php');
  if (is_array($files) && count($files) > 0)
  {
    while(list(,$v) = each($files))
    {
      apc_compile_file($v);
    }
  }
}
compile_files('/path/to/dir');


Кэширование переменных
Большинство библиотек кэширования позволяет кэшировать значения переменных. Очень полезно сохранять значения конфигурации или данные, которые сложно вычислить (получить) и которые не меняются (возможно не меняются в течение некоторого времени, тогда на базе такого кэширования можно реализовать кэширование с устареванием, примечание переводчика).
if (!$config = apc_fetch('config'))
{
  require('/path/to/includes/config.php');
  apc_store('config', $config);
}

Практический пример иллюстрируется на базе использования Zend Framework и простого запуска утилиты ab, в данном примере результат XML-конфигурации сохраняется в кэше. Ускорение времени разбора позволяет экстремально быстро получить доступ к параметрам конфигурации.
Код:
if (!$conf = apc_fetch('pbs_config'))
{
  $conf = new Zend_Config_Xml(PB_PATH_CONF. '/base.xml', 'production');
  apc_store('pbs_config', $conf);
}

Команда для теста ab -t30 -c5 www.example.com
Результат без кэширования
Concurrency Level: 5
Time taken for tests: 30.33144 seconds
Complete requests: 684
Failed requests: 0
Write errors: 0

Результат с кэшированием
Concurrency Level: 5
Time taken for tests: 30.12173 seconds
Complete requests: 709
Failed requests: 0
Write errors: 0

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

Файловое кэширование результатов
В некоторых случаях сервер обрабатывает запросы, результатом которых является одинаковый контент. Есть возможность закэшировать подобные вид контента (полностью или его часть)
В данном тексте иллюстрируется пример на основе пакета Pear::Cache_Lite.

Полное кэширование вывода
Полное кэширование довольно тяжело выполнить на большинстве сайтов с постоянно обновляющимися данными из большого количества источников. Все это правда, однако, нет необходимости обновлять данные каждую секунду. Даже 5-10 минутная задержка при экстремально высокой загрузке сайта позволит вам увеличить производительность.
Пример ниже, сохраняет слепок страницы для будущего использования. Такой подход может помочь большому количеству пользователей.
Я не рекомендую использовать данное решение, но если вам нужно что-то быстрое, вы можете его использовать, рано или поздно вы увидите недостатки этого метода.
The Bootstrap Cache Example:
require('/path/to/pear/Cache/Lite/Output.php');
$options = array(
  'cacheDir' => '/tmp/',
  'lifeTime' => 10
);
$cache = new Cache_Lite_Output($options);
if (!($cache->start($_SERVER['REQUEST_URI'])))
{
  require('/path/to/bootstrap.php');
  $cache->end();
}

Пример на основе .htaccess:
.htaccess
php_value auto_prepend_file /path/to/cache_start.php
php_value auto_append_file /path/to/cache_end.php
cache_start.php
require('Cache/Lite/Output.php');

$options = array(
  'cacheDir' => '/tmp/',
  'lifeTime' => 10
);
$cache = new Cache_Lite_Output($options);
if (($cache->start($_SERVER['REQUEST_URI'])))
  exit;

cache_end.php
$cache->end();

Cache Lite делает большинство тяжелой работы такой как блокирование файла, решение как сохранять контент для различных параметров (в данном примере используется REQUEST URI). Вам также может быть необходимы значения $_POST, $_COOKIE и $_SESSION.

Частичное кэширование
Частичное кэширование это типичный путь оптимизации. Скорее всего на вашем сайте есть части, которые очень редко изменяются или не должны изменяться в реальном времени. Это именно тот случай, когда необходимо применять частичное кэширование и оно позволит вам увидеть приращение в производительности.
Кэширование значения строк
require('Cache/Lite.php');
$options = array(
  'cacheDir' => '/tmp/',
  'lifeTime' => 3600 //1 hour
);
$cache = new Cache_Lite($options);
if (!($categories = $cache->get('categories')))
{
  $rs = mysql_query('SELECT category_id, category_name FROM category');
  $categories = '';
  $cache->save($categories, 'categories');
}
echo $categories;

Пока это чересчур упрощенный пример, он только показывает гибкость сохранения значения. Вы можете сохранять значения массивов для того чтобы обращаться к ним позже.
Кэширования значения массива
require('Cache/Lite.php');
$options = array(
  'cacheDir' => '/tmp/',
  'lifeTime' => 3600, //1 hour
  'automaticSerialization' => true
);
$cache = new Cache_Lite($options);
if (!($categories = $cache->get('categories')))
{
  $rs = mysql_query('SELECT category_id, category_name FROM category');
  $categories = array();
  while($row = mysql_fetch_assoc($rs))
  {
    $categories[] = $row;
  }
  $cache->store($categories, 'categories');
}
var_dump($categories);

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

Кэширование в оперативной памяти
Существует множетсво путей для того чтобы произвести кэширование в памяти: memcached, memory tables в базах данных, RAM disk и другие.
Memcached
С сайта memcache memcached это высокопроизводительная и распределенная кэширующая система, которая увеличивает скорость динамических веб-приложений путём снижения загрузки с базы данных.
О чем это говорит, о том, что можно сохранить данные на одном сервере, к которому будут обращаться другие сервера, это не зависит от вашего веб-сервера (как в случае кеширования промежуточного кода), так как memcached – это демон, который в большинстве случаев используется для кэширования результатов запросов к базам данных.
Пример работы с Memcache:
$post_id = (int) $_GET['post_id'];
$memcached = new Memcache;
$memcached->connect('hostname', 11211);
if (!$row = $memcached->get('post_id_'. $post_id))
{
  //yes this is safe, we type casted it already ;)
  $rs = mysql_query('SELECT * FROM post WHERE post_id = '. $post_id);
  if ($rs && mysql_num_rows($rs) > 0)
  {
    $row = mysql_fetch_assoc($rs);
    // cache compressed for 1 hour
    $memcached->set('post_id_'. $post_id, $row, MEMCACHE_COMPRESSED, time() + 3600);
  }
}
var_dump($row);

Это довольно простой пример работы с memcached. Мы сохранили простой элемент в памяти для будущего использования, до которого в будущем получим лёгкий доступ. Я рекомендую использовать данный метод для данных, к которым вы чаще всего будете обращаться.
Пример настройке параметров сессий для работы с Memcache
session.save_handler = memcache
session.save_path = «tcp://hostname:11211»

Как вы видите поддержка сессий довольно таки простая. Если у вас много серверов memcached переменная save_path должна содержать названия серверов через запятую with each server.
Memory Tables баз данных
Memory tables баз данных могут быть использованы для хранения данных сессии. Вы можете создать таблицу такого типа используя MySQL. Создайте ваш собственный обработчик сессий. Это один из способов увеличить производительность сессий.
RAM Disk
В то время как подход использования оперативной памяти как диска не является примером распределенности, данный подход легко может быть приспособлен для увеличения производительности сайта. Запомните информация находящаяся на таком диске исчезает после перезагрузки сервера.
Создание RAM-диска
mount --bind -ttmpfs /path/to/site/tmp /path/to/site/tmp

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

Надеюсь, что описанное выше было достаточно информативно. Здесь не описан весь потенциал кэширования, например использование кэширования в распределенных базах данных или использование Squid. В будущих статьях я опишу и это…

Средняя зарплата в IT

113 000 ₽/мес.
Средняя зарплата по всем IT-специализациям на основании 5 184 анкет, за 2-ое пол. 2020 года Узнать свою зарплату
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 66

    0
    ниче так, только тэги поправьте (через запятую нужно, а не через пробел)
      0
      Спасибо за статью.
      Я сейчас делаю движок небольшой для сайта и несколько других статьей про кеш читал… но так и не понял, чем APC от memcached отличается с точки зрения разработчика. Может кто пояснит?
        +2
        APC в первую очередь код кэширует. memcashed - данные
          0
          допустим… а Cache_Lite?
            0
            Не знаю, не пользовался.
              0
              посмотри по примерам
              ты на вход подаешь параметры запроса, а кеш определяет были ли такие и выдает контент
              0
              если на сервере достаточно памяти, то APC (его шаред мемори) - хорошее решение, в плане производительности
              0
              Разница в полной мере ощущается, когда у вас несколько аппликэйшн серверов. APC, может быть только свой у каждого сервера, а memcached может быть общий для них всех, на отдельном серваке, например. Соответственно, в этом случае сессии, например, хранить в APC уже нельзя, а в memchached можно.
              0
              как пример, вот реализация кешера из Solar

              http://solarphp.com/class

              Solar_Cache Factory class for cache adapters.
              Solar_Cache_Adapter Abstract cache adapter.
              Solar_Cache_Adapter_Apc APC cache controller.
              Solar_Cache_Adapter_Eaccelerator eAccellerator cache controller.
              Solar_Cache_Adapter_File File-based cache controller.
              Solar_Cache_Adapter_Memcache Memcache cache controller.
              Solar_Cache_Adapter_Var Variable (in-memory) cache controller.
              Solar_Cache_Adapter_Xcache XCache cache controller.

              просто кроме APC есть еще Eaccelerator и Xcache и т.д....
                0
                косвенно связанный с топиком вопрос, кто какие php-профайлеры использует?
                0
                Очень хороша видна работа кэшеров при использовании ORM, скажем phpdoctrine позволяет использовать различные кэшеры для хранения запросов и данных, что ощутимо сказывается на быстродействии. Скажем в своей разработке использую связь доктрина + хкэш.
                  0
                  Хм, статья еще в оригинале показалась неструктурированной. В тех же заголовках перемешаны и хранилища, и методы, и уровни кеширования. Но все равно кому-то полезно ;)
                    0
                    Собственно, кому оказалась интересна эта статья, милости просим претендовать на нашу вакансию: http://habrahabr.ru/job/3188/
                      0
                      Ох-хо-хо. А вам реально нужно все, что здесь написано. Генерация главной 1,5-2 секунды. Это очень много :)
                        0
                        Не совсем понял, это вопрос, ответ, или же констатация факта?
                          0
                          Констатация факта. Хотя это время может складываться из разных составляющих :)
                            0
                            Понял. На главной много всяких счетчиков и другого мусора.
                            Если сделать ее как у гугля то, конечно будет грузится быстрее :)
                              0
                              А вообще нормальный ресурс :) Я у вас xml дергаю :)
                                0
                                Спасиб. Стараемся.
                                А куда дергаем, если не секрет?
                                  0
                                  Ой, даже и не знаю можно ли сказать...
                                  Я исполнитель, код пишу хитрый :)
                      0
                      Скажите, а есть какие-нибудь способы зеркалировать папки/файлы с одного сервера в RAM Disk другого ?
                        0
                        Это скорее вопрос по администрированию nfs (но я могу ошибаться)
                        а зачем вам это, может обойти с использованием другого решения?
                          0
                          Через nfs уже работает.
                          У нас есть сервер, где лежат оригиналы файлов. Есть каталог, в котором в обшей сложности около 20 тысяч файлов. Есть несколько рабочих серверов с Apache+PHP. Для формирования любой страницы сайта нужно произвести очень много операций чтения из этого каталога.

                          По сути ответом на Ваш вопрос будет "очень хочется минимизировать количество файловых операций (чтобы было не через сеть + чтобы было не с физического диска". Если внедрить подобное "зеркалирование", то производительность очень возрастёт (это факт) + не нужно будет ничего переделывать.
                            0
                            По описанию проблемы не понятно ваша ситуация соответственно предлагаемые решения будут пустыми. Опишите детально средний размер файлов и количество необходимых загрузок файлов за один запрос к веб-серверу
                              0
                              Да это не то, чтобы проблема. Она если и появится, то очень не скоро - покупку нового сервера ещё никто не отменял =)
                              Файлы очень маленькие (размер - до 10Кб). Для формирования средней страницы нужно около тысячи обращений к файлам. Так получилось после наворотов админки для верстальщика - ему стало удобно и количество файлов начало расти как снежный ком =)
                                0
                                ну и закиньте содержимое этих файлов или в БД или в memcache
                              0
                              nginx, squid
                            0
                            а если не секрет, rsync чем не угодил?
                            0
                            это скорее вопрос по администрированию nfs (но я могу ошибаться)
                            а зачем вам это, может обойти с использованием другого решения?
                              0
                              $cache->store($categories, 'categories');

                              Не нашел такого метода в документации по Cache_Lite.
                                0
                                Вы абсолютно правы, такого метода нет
                                автор статьи написал, а я не проверил. Речь идет о методе save
                                  0
                                  спасибо!
                                  поменял
                                  0
                                  Может, перенести в "Высокую производительность"?
                                    0
                                    При использовании memcache надо обращать внимание на время коннекта. Оно может быть на порядок больше времени самой выборки и, таким образом, свести все преимущество на нет.

                                    Что касается Memory tables в MySQL, советую помнить об ограничении на максимальный размер такой таблицы. Он определяется минимальным из параметров tmp_table_size и max_heap_table_size. Если размер вырастет больше - сервер просто откажется добавлять новые строки.
                                      0
                                      по поводу первого сомнительно, чтобы коннект к mysql-серверу, был быстрее чем коннект к memchache-серверу. Однако, если выборка маленькая, можно сохранять и в памяти
                                      По поводу второго, ничто же не мешает учитывать сохраняемых размер данных внутри класса обертки и описать сборщик мусора самостоятельно
                                        0
                                        Коннект к mysql и к memcache примерно одинаковы. Но я о коннекте к mysql ничего не писал ;)

                                        Насчет второго - да, проблемы нет. Просто особенность.
                                      +2
                                      Вопрос такой: какой из этих методов, или даже есть ли метод в php кешировать структуры данных не в сериализованном виде, а "такими как есть", т.е. чтобы при каждом запросе не происходила десериализация? На это тратится время. Ясное дело, что в файлы по-другому складывать не получится, но в shared_memory, как мне кажется, вполне. Знаю что shm_put_var точно сериализует. Кто знает как с этим в apc_store/fetch?
                                        0
                                        APC тоже сериализует, попробуйте сохранить, например, PDO объект и увидите "You cannot serialize or unserialize PDO instances", когда будете доставать его из APC.
                                        0
                                        Спасибо большое, очень интересно!
                                          0
                                          При разработке высоконагруженых сервисов, в большинстве своем, все задержки упираются в БД, а не в скорость выполнения скриптов. Что мешает доставить дополнительных дешевых машинок под выполнение php? Главной проблемой все равно будет оптимизация (а желательно и реплицирование или даже кластеризация) БД, ну а здесь уже без memcache просто никак не обойтись!
                                            0
                                            ну стоимость 1 машинки соизмерима со стоимостью 2 месяцев работы хорошего программиста. Может лучше прооптимизировать приложение. Более того вы не учитываете оплату места в стойке, оплату питания и т.д.
                                            Полностью с вами согласен, насчет того что узкие места в приложении это БД и коммуникации с другими сервисами.
                                            Однако не стоит забывать и про скриптовую часть, а именно алгоритм реализации. Не даром же господин Кнут написал 3 том "Сортировка и поиск", более 10 видов сортировки, он же не написал, забейте на все...используйте сортировку методом пузырька, а когда будет тормозить - купите машинку
                                              0
                                              Боюсь, Вы ошибаетесь. Стоимость аренды машинки под php-приложения колеблется около 100$. Стоимость простеньких серверов - это порядка 15-20 000 рублей. Зачастую нагрузка появляется очень быстрыми темпами и оптимизировать весь код и протестировать его вы явно не успеете!!! На это нужны месяцы (для большого проекта). Остается только спасаться дешевеньким железом, а уж потом ждать пока программисты (+ архитектор БД + иногда и администраторы) оптимизируют весь код и программные компоненты и тестеры все это протестируют.
                                                0
                                                Под купить машинку я подразумевал покупку сервера, а не его аренду
                                                Под качественными программистами я имел ввиду не студентов, а людей со большим ОПЫТОМ работы. Насчет простенького сервера не знаю, не давно покупали сервер стоимостью где-то в районе 6-8 тыс. $ для проекта с высокой посещаемостью. Чаще всего весь код оптимизировать не надо, не все сценарии работы с системой являются часто используемыми. А для остального есть профайлер. Можно выяснить узкие места и заострить внимание на них
                                                  0
                                                  Я работаю ведущим разработчиком в компании, которая владеет нескольким нагруженными социальными сетями. Так вот, вывод из практики такой... вы купили машинку за 6-8 тысяч долларов, а теперь подумайте, что будет работать стабильнее и быстрее: одна мощная машинка или кластер из 6-8 обычных за эти же деньги?)))
                                                    0
                                                    1) несколько нагруженных социальных сетей, это сколько загрузок в день?
                                                    2) машинка была куплена с огромным количеством оперативной памяти для кеширования и не одним процессором + никто не говорит, что машинка одна
                                                    3) я вас уверяю запустив глючной код на любом количестве машин он будет тормозить
                                                    4) главный вопрос, вы никогда не пробовали создавать популярные сервисы за СОБСТВЕННЫЕ ДЕНЬГИ?
                                                      0
                                                      1)несколько миллионов хитов на каждую
                                                      2)кшеирование в оперативе (говорю про memcache) обычно выводят на отдельный кластер из дешевого железа, но с большим кол-вом оперативы (подойдут даже десктопные машинки)
                                                      3) исходя из размера заработной платы нормального программиста и сроков переписывания "говнокода", легче купить (читать быстрее и дешевле) дешевого железа, нежели оплачивать зарплату
                                                      4)да, поэтому там заранее была заложена возможность "горячего" масштабирования за малые деньги. Т.е. я имею ввиду, что при резком росте посещаемости, к примеру, на порядок, гораздо проще и самое главное ДЕШЕВЛЕ было просто докупить самое дешевое железо и доставить его в массив.
                                                        0
                                                        по вашему резюме не смог догадаться в каких нагруженных социальных сетях вы работаете, но есть догадка (мойкруг).
                                                        чувствую часть понимания у нас общая, а до некоторых вещей
                                                        договориться никак не можем.
                                                        А куда вы будите ставить такое количество десктопов, ну если только организовать собственный дата-центр.
                                                        немного непонятно словосочетание дешевое железо с большим количеством оперативки...могу ошибаться, но таких материнских плат да чтобы они были дешевые...
                                                        Сведу наш спор к утверждению, с которым вы наверняка согласитесь.
                                                        Код надо писать правильно, но какой бы код не был хороший всегда наступает момент, когда необходимы новые серверные мощности
                                                          0
                                                          1) с утверждением согласен))) самое главное - планировать человеческий код заранее
                                                          2) по поводу догодок напишу в приват
                                                          3) дешевое железо - это до 8000 руб за десктопную машинку. Нынче оперативная память не дорогая... в среднем 1руб за 1 мегабайт, а внекоторых местах и того меньше.
                                                          4)Свой дата-центр можно организовать и в подвале за МКАДом, главное, чтоб канал хороший был, а это теперь не такая редкость.
                                                      0
                                                      в догонку, пока вы на меня не успели обидеться.
                                                      работал в одной компании, пришел на место программиста, оптимизировал местную crm
                                                      страница генерировалась больше минуты, проблема была в том, что предыдущий программист не знал, что такое индексы в БД...понимаю, что пример дурацкий, но все же коду надо уделять внимание
                                                        0
                                                        Странно, что разрабатывая crm, в компании не было должности архитектора БД))) я бы не доверился такому продукту)
                                                          0
                                                          crm был для собственных нужд маленькой компании, а не конечным продуктом. вот почему должность программиста совмещала в себе все эти должности
                                              0
                                              в избранное!
                                                0
                                                Люди, подскажите пожалуйста, как кешировать запросы из БД? Т.е. строки вида /catalog/1934/536/A3446 - запрос к БД, по айдишникам. Как можно кешировать такие запросы, что бы по данному пути, можно было быстро вывести данные. Т.к. постоянно запросы делать в БД нецелесообразно. И ещё: как данные в кеш будут обновляться, если добавлен новый товар. Нужно прописывать обновление кеша? Или его полное стирание, при добавлении новой записи в БД.
                                                  +1
                                                  При загрузке страницы необходимо проверять, создан для нее кэш. если да, показываем из кеша (под кешом можно понимать какое-либо хранилище), если нет создаем в кеше
                                                  Кэширование может быть разным. например если страницы с неизменяемым контентом, перед веб-сервером можно поставить какой-нибудь кэширующий прокси, либо создавать прегенерированные страницы (в случае если такой страницы нет, то , например, ее создает перехватчик ошибки 404), либо сохранять в каком-нибудь другом хранилище

                                                  1) старые записи можно кэшировать спрятав web-сервер за каким-нибудь proxy (например squid). Либо
                                                    0
                                                    спасибо за развернутый ответ!!! только я не понимаю технологию, как проверять, обновилась ли запись в БД или нет? т.е. есть ли смысл тогда, если постоянно проверять обновилась ли запись или можно показывать то что находится в кеше (т.е. устаревание записи). вот это меня беспокоит.
                                                      0
                                                      А что вам мешает в БД создать два поля, дата создания записи в кеше и дата изменения записи
                                                      По поводу использования кеша, вы можете создавать кеш с устареванием, если данные кеша устарели, то пересоздать запись
                                                        0
                                                        огромное спасибо!! как то не додумался:) + в карму как поощрение) пускай виртуальное но спасибо:)
                                                          0
                                                          Так вся фишка кеша же заключается в том чтоб код заново не обрабатывался и не делались никакие запросы в БД, а вы новичку советуете еще и таблицы альтерить)))
                                                            0
                                                            там два вопроса, один про БД, второй про кеш
                                                            а таблицы альтерятся только один раз (лучше при создании) :-)))
                                                            Какой комментатор вредный мне попался :-)
                                                          0
                                                          я обычно делаю проще — закидываю в кеш, а при изменении какой либо части страницы удаляю страницу из кеша, что вынуждает её перегенерироваться
                                                            0
                                                            Подскажите, а какой инструмент позволяет хранить связи, что страница состоит из частей-кусков?
                                                            Суть вопроса, как найти все страницы в которых есть «протухший» кусок, чтобы удалить эти страницы из кеша.
                                                              0
                                                              Это решается установкой времени годности (timeout) информации.
                                                              вот тут php.net/manual/ru/memcache.add.php можно посмотреть
                                                                0
                                                                Время годности это хорошо, но вопрос был о другом. Постараюсь чуть подробнее расписать.

                                                                Допустим, есть страницы с описанием квартир в каталоге. Эти страницы мы и хотим закэшировать.
                                                                И на этих страницах есть блоки информации — «Похожие объявления».
                                                                Одно и то же объявление может быть в похожих на страницах многих объявлений.

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

                                                                Получается есть родительский объект (страница объявления) со своим сроком протухания и есть несколько дочерних кусков внутри этого объекта (блоки похожих объявлений) со своим сроком протухания.

                                                                Вот есть ли такое Cache хранилище, которое умеет такие взаимосвязи поддерживать?

                                                      –2
                                                      Это называется "Заход солнца вручную".
                                                      В JSP кэширование байткода реализовано автоматически.
                                                        +1
                                                        Насколько можно видеть, этот блок посвящен php, а раздувать здесь holy war нехачем

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

                                                      Самое читаемое