И снова кеширование. (Кэширование, cache)

Статус
В этой теме нельзя размещать новые ответы.

maxru

МИФИст
И снова кеширование. (Кэширование, cache)

В заголовок добавил различные варианты написания слова "кеширование" для лучшего поиска.
Читаю книгу Шлосснейгла "Профессиональное программирование на PHP" и, соответственно, появляются вопросы.
Сейчас - это вопрос о кешировании.


Кеширование блоков данных.

Предположим, что класс Article инкапсулирует в себе данные об одной конкретной статье.
Предположим, что существуют методы выдачи этих данных. Сам класс НЕ работает с представлением статьи, он работает только с данными.
Предположим, что есть класс ArticleDecorator, отвечающий за форматирование и вывод данных (на какое устройство - не важно).
(Почему я так назвал эти классы и аспекты вывода содержимого на экран прошу не обсуждать. Классы - чисто гипотетические. Поэтому схему реализации
кеширования на более низком уровне пока обсуждать не будем)
У класса ArticleDecorator есть метод ArticleDecorator::Decorate(Article $obj), который принимает экземпляр класса Article и возвращает,
предположим, html код.

Я вижу несколько способов кеширования:

  1. На уровне ArticleDecorator.

    a) Внутри класса производить проверки и выдавать либо кешированный html, либо генерировать кеш заново.
    b) Воспользоваться примерно таким алгоритмом (простейший случай, возможность отключения кеширования не рассматриваем):
    PHP:
    if(!$cache->getCacheExists('произвольный_идентификатор'))
    {
    	$cache->startCaching('произвольный_идентификатор'); // ob_start();
    	...// необходимые действия c ArticleDecorator
    	$cache->stopCaching('произвольный_идентификатор'); // ob_get_contents(); ob_end_clear();
    }
    $cache->getCache('произвольный_идентификатор');
  2. На уровне Article.

    a) Внутри класса производить проверки и кешировать данные статьи (то есть фактически кеширование запросов к БД).
    b) Делать то же самое кеширование полей обьекта, только с внешней проверкой и дозагрузкой.
    PHP:
    if(!$cache->getCacheExists('произвольный_идентификатор'))
    {
    	...// необходимые действия c Article (инициализация, запросы к БД)
    	$cache->doCaching('произвольный_идентификатор', Article $article);
    }else{
    	$article_data = $cache->getCache('произвольный_идентификатор');
    	$article = new Article($article_data);
    	/* Здесь подразумевается, что при попытке получения из экземпляра класса 
    Article значения какого-либо поля этого класса происходит запрос к БД для получения
     этого значения только если оно == "" (т.е. получение даных происходит при появлении
    необходимости в этих данных)*/
    }
  3. Комбинации 1 и 2.
    [/list=1]

    Внутреннее кеширование мне не нравится из-за необходимости жестко привязывать структуру классов к классу, отвечающему за кеширование.
    Внешнее кеширование мне не нравится из-за необходимости делать некоторые проверки, дополнительные условные операторы.
    Однако бОльшим злом мне все-таки кажется "встроенное" кеширование.



    Способы кеширования (с помощью встроенных средств PHP).
    Вот тут есть несколько способов, которые опять же имеют свои достоинства и недостатки.
    1. Плоские файлы.
      Достоинства:
      - простота реализации
      Недостатки:
      - необходимо следить за режимами доступа к файлу (блокировка во время записи)
      - могут быть "битые" файлы (процесс записи был аварийно прерван)
      - необходимо продумывать иерархию структуры кеширования, т.к. ростом количества файлов в одной "папке" начинает рости время доступа.

      По этому поводу хотелось бы услышать рекомендации по наиболее быстрой реализации кеширования в плоских файлах (в основном по структуре
      каталогов для хранения этих самых файлов).
      Первый недостаток может быть устранен с помощью записи кеша во временный файл, затем unlink() старого файла кеша (при этом для
      процессов уже получивших доступ это останется незаметным, они смогут читать данные из "несуществующего" файла) и переименования временного
      файла в файл кеша.
    2. DBM-кеширование (Berkley DB)
      Достоинства:
      - высокая скорость чтения/записи
      - возможность одновременной записи/чтения
      - идеально подходит для хранения данных вида "ключ"->"значение"
      Недостатки:
      - Нет встроенных средств слежения за временем создания/изменения отдельных строк (проблема определить устарел ли кеш или нет).

      По этому поводу хотелось бы услышать про то, как лучше отследить время последнего обновления кеша (сделать таблицу в другой БД, например MySQL, с timestamp'ом последней модификации???)
    3. Кеширование на основе общей памяти
      Рассматривать не будем. (ИМХО только для крупных проектов на (виртуальных) выделенных серверах. А виртуальный хостинг - это максимум 64 мегабайта оперативной памяти.)
    4. Кеширование на основе cookie
      Достоинства:
      - экономия места на сервере (при большом количестве пользователей)
      Недостатки:
      - "засорение" канала передачи данных лишними данными
      - ограниченные размеры
      - целесообразно хранить только данные для конкретного пользователя
      - проблемы с безопасностью (содержание может быть украдено)
      [/list=1]
      Мое мнение - надо использовать комбинированное кеширование.

      PHP:
      if(!$plainCache->getCacheExists('произвольный_идентификатор'))
      {
      	$plainCache->startCaching('произвольный_идентификатор'); // ob_start();
      	
      	$article_decorator = new ArticleDecorator($article_object);
      	if(!$objectCache->getCacheExists('другой_произвольный_идентификатор'))
      	{
      		$article_object = new Article(345);
      		$article_object->getAllData(); // заполняем все поля класса из БД
      		$objectCache->doCaching('другой_произвольный_идентификатор', $article);
      	}else{
      		$article_data = $cache->getCache('другой_произвольный_идентификатор');// DBM-кеш
      		$article = new Article($article_data);
      	}
      	
      	$plainCache->stopCaching('произвольный_идентификатор'); // ob_get_contents(); ob_end_clear();
      }
      $plainCache->getCache('произвольный_идентификатор');// кеш из плоского файла
      Кеширование с помощью cookie, наверное, стоит использовать только для хранения пользовательских настроек (например язык сайта, регион, скин сайта и т.д.),
      которые хранятся еще и в БД. При этом данные шифровать симметричным алгоритмом.

      Хотелось бы увидеть комментарии уважаемых форумчан по поводу этой портянки.
 
maxru
Мое мнение что ни класс Article ни ArticleDecorator о кешировании не должны ничего знать вообще, кешированием должен заниматься отдельный CacheManager который умеет и знает все остальное, а уж использовать его или нет решает клиентский код. А как-то не очень гламурно получается, ага.
 

Alexandre

PHPПенсионер
Кеширование с помощью cookie, наверное, стоит использовать только для хранения пользовательских настроек (например язык сайта, регион, скин сайта и т.д.),
куки вообще должны хранить минимум информации, как иди сессии или пользовательские настройки, ни какого кеширования в куках.

Прежде чем разрабатывать систему, задайся техническими требованиями к системе. Определи (хотя бы для себя), для чего ты пишешь, какие условия хостинга, какая нагрузка. Может быть часть проблем отпадет сама собой.

"Преждевременная оптимизация - самое большое зло в программировании" - слова от автора книги : "Ис-во программирования" Дональд Кнут.

Так например, на шаред хостингах как правило нет Berkley DB - уже один пункт отпадает.

Механизм кеширования в БД, тоже очень спорное, так как БД - как правило - самое узкое место и основная задержка при выполнении скрипта, именно на выполнении запросов БД. А если это еще и шаред хостинг, то вообще: пиши-пропало....

Так, например, у меня один контентный проект имел при дисковом кеширование размер в несколько Гиг.
приходилось организовывать иерархический доступ к файлам, иначе если более чем 1000 файлов в одной директории, то файловая система Юникс начинает тормозить. Вопрос - а не проще - ли тогда сделать полностью отдаваемый статический сайт, с автоматической генерацией контента - Ив этом случае скорость отдачи возрастает в разы? {Это как оффтоповский приемр, был реализован не мной, мне лишь приходилось вбивать гвозди в кривое сооружение, чтоб оно не рухнуло}

вопрос кеширования не такой простой, как кажется,
надо задаться вопросом - что кешировать (HTML, данные, промежуточные HTML - блоки, Объекты, хеш-массивы), на каком этапе, и вообще, для чего это нужно... и реализуемо-ли технически?! И уж после этого, определиться с рамками своего проекта.
 
Автор оригинала: Alexandre
файловая система Юникс
Дядя, дядя! А что за файловая система такая "Юникс"? Уж не знал что на всех хостингах нынче Юникс со своей одноименной файловой системой, и вот уж не знал что она "тормозит". Особенно если основана на бинарных деревьях ;).
 
Alexandre
Это сарказм? Ты ответишь за слова или нет?. Какая именно файловая система Юникс тормозит?. И как ты определяешь тип файловой системы на сервере? Особенно на сервере maxru, ведь ты ему об этом ведал.
 

boombick

boombick.org
Alexandre
да, как-то странно... у меня ReiserFS на трех тысячах мелких файлов в одной директории отлично работает. Ну уж если тормозит, то можно и по разным дирам разложить :)
 

Alexandre

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

лечшеб поделились дельными советами и своей практикой в организации кеширования или ее нет?
 

Alexandre

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

boombick

boombick.org
многие фундаментальные книги по Unix
беда в том, что когда писались фундаментальные книги, ext3 называли "совсем новой и еще не до конца оттестированной ФС"
Так что лучше следить за веяниями... имхо, конечно же
 

Alexandre

PHPПенсионер
boombick а по теме топикстартера слабо сказать?
А то размазать грязью по лицу желающих здесь нашлось предостаточно.
 

boombick

boombick.org
А то размазать грязью по лицу желающих здесь нашлось предостаточно
я не размазывал грязь ни по чьим лицам. Я высказал свою точку зрения на проблему хранения кеша в файлах относительно скорости работы ФС. Если вы укажете мне на некорректное обращение к кому-либо, публично извинюсь.
 

kvf77

Red Devil
Тема закрыта.

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