Кеширование в PHP
1267 сообщений
#17 лет назад
Пишу ради хобби CMS и задумался над системой кеширования. Стоит ли кешировать результаты выборки с БД или нужно полагаться на встроенную в MySQL систему кеширования (с++ быстрее PHP)?Сейчас маниакальное (

- Кеш результатов обработки модели
- Кеш страницы целиком
- Кеш выборочных запросов
- Кеш массива настроек и языков
- Кеш части шаблона с результатом вставки туда переменной (в планах)
- Класс для кеширования, позволяющий работать с файлами\APC\Memcache и использовать их где-угодно
3240 сообщений
#17 лет назад
Единого рецепта тут нет и быть не может.Какую стратегию кеширования выбрать в том или ином случае зависит от ситуации.
Например, если страницы сайта не обновляются, или обновляются крайне редко - конечно же лучше кешировать страницы целиком. Причем не средствами PHP или MySQL, а, скажем, используя реверс-прокси, или формируя статику. И не забываем про HTTP заголовки, управляющие кешированием, тоже полезно.
1267 сообщений
#17 лет назад
Ещё такое, не могу придумать как лучше 
1. Загонять в memcache\APC всю таблицу целяком и работать с ней, а при инсертах добавлять значение непосредственно в базу, и, вместо выборки новых данных с таблицы, вставлять в кеш данные.
Недостаток: большой объём информации в кеше
2. Кешировать результаты выполнения каждого запроса отдельно.
Недостаток: большой количество итемов в кеше. Фактически на каждый кешированный запрос по 1 штуке. (если изменить любую часть условия WHERE запрос будет кешироваться отдельно)
3. Предлагайте своё )
Да простят меня все за излишества в программировании

1267 сообщений
#17 лет назад
Цитата ("tvv"):Единого рецепта тут нет и быть не может.
Какую стратегию кеширования выбрать в том или ином случае зависит от ситуации.
Например, если страницы сайта не обновляются, или обновляются крайне редко - конечно же лучше кешировать страницы целиком. Причем не средствами PHP или MySQL, а, скажем, используя реверс-прокси, или формируя статику.
Вопрос сейчас именно в: "Стоит ли средствами PHP кешировать запросы в БД".
3240 сообщений
#17 лет назад
Про таблицы.Если таблица небольшая - то засовываем в кеш целиком.
Если большая - то каждый запрос отдельно (ограничив при этом количество кешируемых запросов).
Что есть "небольшая" или "большая" - определяется по ситуации.
Еще можно строить паттерны типа RecordSet, будет такое вот промежуточное решение, проблема частично решается.
Но, повторюсь, универсального решения для любой таблицы тут нет.
3240 сообщений
#17 лет назад
Цитата ("Zionit"):Вопрос сейчас именно в: "Стоит ли средствами PHP кешировать запросы в БД".
В одних случаях это - лучшее решение. В других оно избыточно, ненужно. В третьих так делать нельзя категорически. Зависит от ситуации.
Более детально опишите ситуацию, в которой нужно работать с такими-то данными - тогда можно будет подсказать вариант стратегии кеширования.
1267 сообщений
#17 лет назад
Цитата ("tvv"):Цитата ("Zionit"):Вопрос сейчас именно в: "Стоит ли средствами PHP кешировать запросы в БД".
В одних случаях это - лучшее решение. В других оно избыточно, ненужно. В третьих так делать нельзя категорически. Зависит от ситуации.
Можно пример ситуаций? Просто хочу предусмотреть как можно больше, что потом вынесу в виде опций для разработка, поддерживающего КМС

1410 сообщений
#17 лет назад
Цитата ("Zionit"):Пишу ради хобби CMS и задумался над системой кеширования. Стоит ли кешировать результаты выборки с БД или нужно полагаться на встроенную в MySQL систему кеширования (с++ быстрее PHP)?
Сейчас маниакальное () количество возможностей кеша уже есть:
- Кеш результатов обработки модели
- Кеш страницы целиком
- Кеш выборочных запросов
- Кеш массива настроек и языков
- Кеш части шаблона с результатом вставки туда переменной (в планах)
- Класс для кеширования, позволяющий работать с файлами\APC\Memcache и использовать их где-угодно
По этому вопросу - советую посмотреть как это сделано в Zend_Cache. Там есть разнообразные бекенды для работы с memcached, sqlite, apc и т.д.
А универсального совета для CMS тут нет - как правило тут приходится кешировать дерево страниц (если таковое есть), контент, настройки можно держать в memcached и т.д.
1267 сообщений
#17 лет назад
Хм. Автор видимо подразумевает, что кешировать можно используя PHP (написать собственный класс который будет сохранять результаты в кеш) или доверять встроенному в MySQL кешу (написанном на с++)Как-то так...
1410 сообщений
#17 лет назад
Цитата ("Zionit"):Хм. Автор видимо подразумевает, что кешировать можно используя PHP (написать собственный класс который будет сохранять результаты в кеш) или доверять встроенному в MySQL кешу (написанном на с++)
Как-то так...
Стоит начать с того, что одной из самых ресурсоемких операций - есть операция открытия соединения с базой..каждый раз в итоге Вы будете открывать соединение, чтобы просто получить кеш?
Единственный случай, когда это удобно, имхо - это когда есть несколько mysql-серверов, которые работают совместно (кластер), тогда да..а так - никакой выгоды не вижу перед кешем на файловой системе или в том же memcached..
3240 сообщений
#17 лет назад
Хорошо. Пример.Форма регистрации, используется AJAX.
Пользователь в селектбоксе выбирает страну, делается AJAX реквест, подгружаются области в другом селектбоксе.
Выбирает область, стартует следующий AJAX запрос, подгружаются города в третьем селектбоксе.
Тут оптимально было бы сделать так.
1. При первом вызове из БД считывается список стран.
Если это проект для рунета, то имеет смысл сразу делать второй запрос, чтобы получить список областей.
Формируется из шаблона HTML код страницы регистрации, уже со странами (для рунета - сразу выбрана Россия, и области уже заполнены).
Этот HTML код целиком заносится в кеш.
При следующем вызове формы регистрации HTML сразу будет браться из кеша.
2. При выборе области делается запрос к БД, выбираются все области/штаты/провинции для выбранной страны. Результат кодируется JSON, и уже в таком виде сохраняется в кеше, при этом ключ кеша включает в себя id страны.
При следующем запросе на получение областей сразу берется эта JSON строка из кеша.
3. С городами - то же самое что и пункт 2.
Кстати, для кеша можно использовать файловую систему (можно совместить с реверс прокси + memcache) и при этом все элементы кеша будут статикой, которая будет загружаться напрямую без малейшего вызова PHP или MySQL.
Таким образом будет достигнута максимальная производительность, которая только возможна в данном случае.
При обращении к кешу ни PHP, ни MySQL вызываться не будут. Любое другое кеширование - что средствами PHP, что MySQL - избыточно.
---------------
Но для других ситуаций нужны будут другие решения!
1267 сообщений
#17 лет назад
Цитата ("ArtLab"):Цитата ("Zionit"):Хм. Автор видимо подразумевает, что кешировать можно используя PHP (написать собственный класс который будет сохранять результаты в кеш) или доверять встроенному в MySQL кешу (написанном на с++)
Как-то так...
Стоит начать с того, что одной из самых ресурсоемких операций - есть операция открытия соединения с базой..каждый раз в итоге Вы будете открывать соединение, чтобы просто получить кеш?
Единственный случай, когда это удобно, имхо - это когда есть несколько mysql-серверов, которые работают совместно (кластер), тогда да..а так - никакой выгоды не вижу перед кешем на файловой системе или в том же memcached..
На файловой системме кешировать запросы по-моему бредово немного, выбор пал на memcache\APC (APC быстрее кстати)
1267 сообщений
#17 лет назад
Хм. Спасибо всем за обсуждение.tvv, да, в вашем случае записать строку JSON в файл будет лучше всего, но как вы говорили для каждого случая есть своё решение. Спасибо.
/me ушёл писать код
1410 сообщений
#17 лет назад
Цитата ("Zionit"):
На файловой системме кешировать запросы по-моему бредово немного, выбор пал на memcache\APC (APC быстрее кстати)
Почему бредово? APC и memcached по сути делают тоже самое.
ФС может не подойти только в том случае, если есть распределенный кеш, который могут дергать разные сервера. В других случаях - ничего бредового в этом нет.
К тому же - не понимаю, почему Вы собираетесь кешировать не результат запросов, а сами запросы..В чем выгода-то? Если она и есть, то она минимальна.
1267 сообщений
#17 лет назад
Цитата ("ArtLab"):Цитата ("Zionit"):
На файловой системме кешировать запросы по-моему бредово немного, выбор пал на memcache\APC (APC быстрее кстати)
Почему бредово? APC и memcached по сути делают тоже самое.
ФС может не подойти только в том случае, если есть распределенный кеш, который могут дергать разные сервера. В других случаях - ничего бредового в этом нет.
К тому же - не понимаю, почему Вы собираетесь кешировать не результат запросов, а сами запросы..В чем выгода-то? Если она и есть, то она минимальна.
Я не точно высказался, кеширую именно результат, извините.
ФС не подходит из-за скорости работы.
1410 сообщений
#17 лет назад
Цитата ("Zionit"):
ФС не подходит из-за скорости работы.
Стоп! Вопрос в том, как Вы хранить будете на ФС, а не в скорости работы ФС.
Причем тут скорость работы? Еще раз привожу пример ту же базу данных - это же тоже файлы на ФС, а не сферические кони в вакууме. Почему тогда вариант с mysql Вам нравится, а ФС - "не подходит из-за скорости работы"?
1267 сообщений
#17 лет назад
Цитата ("ArtLab"):Цитата ("Zionit"):
ФС не подходит из-за скорости работы.
Стоп! Вопрос в том, как Вы хранить будете на ФС, а не в скорости работы ФС.
Причем тут скорость работы? Еще раз привожу пример ту же базу данных - это же тоже файлы на ФС, а не сферические кони в вакууме. Почему тогда вариант с mysql Вам нравится, а ФС - "не подходит из-за скорости работы"?
По полочкам.
БД MySQL - работает на файловой системме (медленно)
Встроеный кеш запросов в MySQL - работает с ОЗУ сервера (быстро)
memcached - работает с ОЗУ сервера, но через
APC - работает с ОЗУ комьютера (быстрее memcache, запросы через сокеты не приходиться отправлять)
Кеш на ФС - работает на ФС

1267 сообщений
#17 лет назад
Далее:- MySQL \ FS cache:
Медленная работа, файловый кеш медленнее хотя-бы потому, что нужно информацию с БД преобразовать в сохраняемый формат, а потом обратно (PHP).
- MySQL Cache:
C++, прямая работа с ОЗУ без обработки в PHP
- Memcached \ APC \ etc.:
Быстро, но нужно предварительно получить данные с базы, а потом их сохранять в кеш (PHP)
Соответственно: всё, что PHP теоретичски медленнее С++
3240 сообщений
#17 лет назад
Цитата ("Zionit"):memcached - работает с ОЗУ сервера, но через HTTP протокол (быстро)
Через какой-какой протокол?
Там же открывается соединение на порт 11211, и обмен идет по своему протоколу, при этом на все время сессии удерживается постоянное соединение.
HTTP было бы очень медленно, ну никак не предназначен HTTP для этого.
Цитата ("Zionit"):
Кеш на ФС - работает на ФС .
На самом деле ФС - это тоже своего рода БД, только не реляционная. И тоже имеет свой кеш в ОЗУ.
И не нужно забывать про виртуальные диски, которые целиком могут быть расположены в ОЗУ.
Так что сразу хоронить ФС не стоит IMHO, для ряда случаев ФС - лучший выбор, хотя конечно же не для всех.