модуль DBCache. beta version. FAQ.

Alexandre

PHPПенсионер
модуль DBCache. beta version. FAQ.

где взять пока тут

как работает
берет хеш запроса, который является именем файла. если время последнего update +livetime (sec) менее time() - текущее время то кеш считается устаревшим, данные берутся из БД, как впрочем, если данных в кеше нет.
если кеш - актуален, то данные берутся из кеша.

что представляет кеш csv файл, в котором символы ';' и '\n' закодиорованны.

Зависимости
PHP от 5.1 и выше
Модуль dbcache зависит от модуля mysqli, модуль mysqli должен быть установлен.

Тестирование:
На Linux Mandrake 10.0 PHP 5.2.0 - замечался SigFault
На Linux Mandrake 10.0 PHP 5.1.4 - стабильно
На FreeBSD 6.0 PHP 5.2.2 - стабильно

Инсталляция.

1. скопировать всю папку dbcache в php-src/ext (не обязательно, папка dbcache может находится и в домашней директории)

2. cd dbcache
3. phpize
4. ./configure
5. make && make install
6. создать директорию для кеша и назначить права на запись



Пример использования:
PHP:
	$mysqli = new mysqli("localhost", "akalend", "", "test") or die('Connect failed');
		
	$cacheDir = '/home/akalend/cache';	// полный путь до кеш-директории.
	$dc = new dbCache( $cacheDir );
	$dc->bind( $mysqli ); // привязка к  mysqli object

	$query="select * from test_data limit 50";
	$livetime = 500; 				// время жизни кеша в секундах
	$dc->query($query, $livetime); 		//  выполнение запроса
	while( $res = $dc->fetch() ){			// fetching data, возвращает массив строки или false при достижении конца. 	
		print_r($res);
	} 
	print_r( $dc->getInfo() );			// вывод отладочной информации
Ограничения
- размер одного поля не должен превышать 1000 символов, изменяется при компиляции макроопределением #define BUFFSIZE 1024
- не используются BLOB поля


Почему модуль привязан к mysqli?
это связано с тем, что в приложении как правило есть и некешируемые запросы, хотелосьбы использовать одну коннекцию.
Так как модуль mysqli наиболее популярный, то было решено использовать уже открытую коннекцию от туда.

Планируется ли привязка модуля к PDO mysql?
пока нет, так же как и к другим БД, хотя на мой взгляд это не так и сложно.
хочу довести модуль до стабильной версии.

Почему указывается полный путь:
ну, как правило - файловый кеш выносится за приделы httpdoc, даже желательно вынести на другой физический диск.
всегда можно знать полный путь до своего httpdoc.

Чистится ли кеш?
реализована команда инвалидации кеша : $dc->clear($query );


Планы.
в планах привязка к PDO и мемкешу.
 

Wicked

Новичок
1) Я правильно понимаю, что запросы, содержащие, например, [sql]now()[/sql], программисты должны будут просто пропускать не через инстанс dbcache, а через инстанс mysqli?

2) Как быть с цепочкой запросов типа:
[sql]use db1;select * from table;use db2;select * from table;[/sql] ?
кроме смены базы данных можно поставлять и другие действия: смена кодировки, alter table, whatever else :)

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

korchasa

LIMB infected
Автор оригинала: Wicked
1) ...
2) ...
Это, ИМХО, нормально. Програмист все таки должен понимать что он делает.
3) какие предусмотрены средства для частичной инвалидации кэша, инициируемой не по событию протухания файла, а вручную? Т.е., например, если юзер добавил френда, то это станет заметно только после протухания соответствующего файла кэша?
Этот кеш не очень подходит для такого примера. Такая реализация хорошо подходит для какой-нибудь сложной выборки, на данных где валидность не важна, например супер-пупер-рейтинг пользователей.

2Alexandre
Не опишете сферу применения? Я имею ввиду где это уже используется и почему другие способы кеширования не устроили?
 

FractalizeR

Новичок
zerkms
MySQL очищает кэш запроса при любой модификации любой таблицы, участвующей в нем. Кроме того, кэш MySQL сильно расходует оперативку (его ведь надо поддерживать должного размера), хотя это уже другая история :)

dark-demon
Согласен. Думаю, 0 преимуществ.

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

zerkms

TDD infected
Команда форума
MySQL очищает кэш запроса при любой модификации любой таблицы, участвующей в нем.
что чертовски логично. и что избавляет от весьма сложного процесса слежения за актуальностью кеша

Кроме того, кэш MySQL сильно расходует оперативку (его ведь надо поддерживать должного размера), хотя это уже другая история
цель кеша - ускорение работы. заменять один медленный ресурс (hdd) на точно такой же другой (тоже hdd) - глупо
 

korchasa

LIMB infected
Автор оригинала: zerkms
что чертовски логично. и что избавляет от весьма сложного процесса слежения за актуальностью кеша
Ну тут решение, пока как раз для случаев, когда актуальность не важна.

Автор оригинала: zerkms цель кеша - ускорение работы. заменять один медленный ресурс (hdd) на точно такой же другой (тоже hdd) - глупо
Цель кеша в общем случае - ускорить доступ к данным. А время доступа может еще и от вычислений зависеть. Запросы же разные бывают ;)
 

zerkms

TDD infected
Команда форума
А время доступа может еще и от вычислений зависеть. Запросы же разные бывают
хз, как по мне - так любой запрос должен выполняться за приемлемое для системы время, чтобы клиенту было комфортно
может просто вычисления делаются не тем инструментом и кешировать надо совсем не результаты запроса? ;)

мой вердикт: надуманный модуль
 

FractalizeR

Новичок
Если бы он был надуманным, зачем подобный функционал присутствует во многих движках для работы с БД? В большинстве случаев, будет быстрее прочитать файл с результатами запроса с диска, чем выполнять запрос к БД.

Скажем, нужно нам вывести top10 самых активных модераторов форума на каждой его странице. Информацию по активности получаем из лога модераторов COUNT ... GROUP BY функцией. Информация в этой таблице постоянно меняется, так что MySQL Query Cache тут не даст нам выигрыша в скорости. С другой стороны, этот TOP10 не нужно обновлять каждую секунду. Пользователей устроит, если он раз в десять минут будет обновляться. В этом случае логично сохранить результаты выполнения запроса в кеше на 10 минут. Разве не так?
 

zerkms

TDD infected
Команда форума
Если бы он был надуманным, зачем подобный функционал присутствует во многих движках для работы с БД? В большинстве случаев, будет быстрее прочитать файл с результатами запроса с диска, чем выполнять запрос к БД.
это не ответ. "а вон там так сделано" - аргументация, мягко говорят, слабенькая ;) и в каком большинстве прочитать результаты быстрее?

Скажем, нужно нам вывести top10 самых активных модераторов форума на каждой его странице. Информацию по активности получаем из лога модераторов COUNT ... GROUP BY функцией. Информация в этой таблице постоянно меняется, так что MySQL Query Cache тут не даст нам выигрыша в скорости. С другой стороны, этот TOP10 не нужно обновлять каждую секунду. Пользователей устроит, если он раз в десять минут будет обновляться. В этом случае логично сохранить результаты выполнения запроса в кеше на 10 минут. Разве не так?
почему бы тут не кешировать тогда результаты работы функции getTop10Moders(), которая ещё и форматирует результат в нужный вид, или даже генерирует готовый вывод?
 

Alexandre

PHPПенсионер
) Я правильно понимаю, что запросы, содержащие, например, SQL: now( ) , программисты должны будут просто пропускать не через инстанс dbcache, а через инстанс mysqli?
через mysqli
2) Как быть с цепочкой запросов типа:
SQL: USE db1; - использовать mysqli
SELECT * FROM TABLE ; - исп. dbcache->query(); dbcache->fetch()
далее dbcache->close()
USE db2; - использовать mysqli
SELECT * FROM TABLE ; исп. dbcache->query(); dbcache->fetch()
кроме смены базы данных можно поставлять и другие действия: смена кодировки, alter table, whatever else
c кодировкой не эксперементировал, но модуль исп. стандартное mysql API, все что не кешируется исп. через mysqli, в частности - кодировки, смнена коннекции...
кстати, над сменой коннекции надо проэксперементироваать...
см. пунк Почему модуль привязан к mysqli?
3) какие предусмотрены средства для частичной инвалидации кэша, инициируемой не по событию протухания файла, а вручную?
пункт Чистится ли кеш?
я думал предусмотреть метод clear($query)? если нужно - это дело 30 минут+ часа полтора на отладку... но не вижу необходимости.

Не опишете сферу применения? Я имею ввиду где это уже используется и почему другие способы кеширования не устроили?
пока нигде не используется, находится на этапе тестирования (beta version). преимущество перед другими методами кеширования:
serialize/unserialize - медленнее раз в 10
кеширование смарти - быстрее раз 30-70 если использовать в паре с блитцем...

замер производительности - дело сугубо субъективное, зависит от софта, железа, нагруженности процессора, структуры запроса...

-~{}~ 05.01.08 18:33:

Цель кеша в общем случае - ускорить доступ к данным. А время доступа может еще и от вычислений зависеть. Запросы же разные бывают
спасибо, в точку попал...
в моем проекте некоторые запросы на выделенной базе по 10-15 сек выполняются ;)

-~{}~ 05.01.08 18:40:

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

-~{}~ 05.01.08 18:45:

Да, еще в планах написать метод fetchAll() (в АПИ забит уже), который формировал вывод всего массива запроса. за счет внутреннего цикла и отсутствия внешних (по отношению к модулю) обращений - это ускорит формирование раз в 10.
 

dark-demon

d(^-^)b
кеш БД - неуправляемый пользователем, кешируется все подряд...
я думал предусмотреть метод clear($query)? если нужно - это дело 30 минут+ часа полтора на отладку... но не вижу необходимости.
-~{}~ 05.01.08 18:47:

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

Alexandre

PHPПенсионер
dark-demon ты выдираешь цитаты, не привязанные по смыслу... по делу - сказать слабо.
я думал предусмотреть метод clear($query)? если нужно - это дело 30 минут+ часа полтора на отладку... но не вижу необходимости
это имелось ввиду работы на 30 минут...

-~{}~ 05.01.08 19:04:

не вижу никаких преимуществ перед тем же мэмкэшем.
не путай мух с котлетами...
мемкеш - это модуль доступа (вреппер к API ) к демону мемкеш. Для кеширования данных запроса - нужно разрабатывать свой скрипт кеширования.

мой модуль - это конкретно - кеширование запросов.
в планах есть использование API к демону мемкеш.

ну если пошла уж такая пьянка... у меня в прошлом проекте кеш составлял пару гиг... а точнее на все проекты - 4 гига. правда там кешировался HTML (всеми любимый смарти)
в настоящем проекте - кеш (чисто csv данные ) составляет 230 Мег

Но всеже какой нужно сервер - чтоб удержать эти пары - четверку гиг???
 

fixxxer

К.О.
Партнер клуба
как чистить данные при устаревании (insert/update/delete запросы)?
что происходит с запросами вида select [одно и то же] limit 10 offset 0/10/20/.. ?
 

MiksIr

miksir@home:~$
Задачи кеширования на уровне DB к сожалению столь специфичны, что использование их в реальности приносит больше проблем, чем пользы. Иногда кеширование запроса полезно, но, увы иногда, а чаще всего бывает вредно. Самое печальное в такой схеме, что тот код, который знает, какие данные можно кешировать, а какие нет, находится на другом уровне абстракции, чем db класс.

-~{}~ 05.01.08 20:19:

Автор оригинала: Alexandre
ну если пошла уж такая пьянка... у меня в прошлом проекте кеш составлял пару гиг... а точнее на все проекты - 4 гига. правда там кешировался HTML (всеми любимый смарти)
в настоящем проекте - кеш (чисто csv данные ) составляет 230 Мег
Но всеже какой нужно сервер - чтоб удержать эти пары - четверку гиг???
230 мег копейки, 4 гига HTML-а тоже копейки, ибо он хорошо gzipается, что умеет мемкеш. Другой вопрос - насколько необходим такой кеш, ибо хранить там результат любого запроса без протухания - это весьма неверно, а мемкеш же будет сам выталкивать давно ненужные данные.
 

dark-demon

d(^-^)b
ты выдираешь цитаты, не привязанные по смыслу... по делу - сказать слабо.
прочитай, пожалуйста, моё сообщение, состоящее преимущественно из твоих цитат, сверху вниз, а не по диагонали.



мемкеш - это модуль доступа (вреппер к API ) к демону мемкеш. Для кеширования данных запроса - нужно разрабатывать свой скрипт кеширования. мой модуль - это конкретно - кеширование запросов.
не вижу принципиальной разницы.
 

Alexandre

PHPПенсионер
как чистить данные при устаревании (insert/update/delete запросы)?
см. Чистится ли кеш?

что происходит с запросами вида select [одно и то же] limit 10 offset 0/10/20/.. ?
каждый запрос - уникален, следовательно у него свой кеш.
у меня в другом проекте (DataAccessLavel) предусмотренно изъятия части кеша ( эту тему я предлагал на обсуждение в НЕКОНФ...тм) возможно данный функционал я перенесу и в данный модуль. Мнебы выявить узкие места в данном модуле, нужна помощь в тестировании, в нормальном деплойменте...
чтоб инсталляцию сократить с семи до простых четырех шагов...
Задачи кеширования на уровне DB к сожалению столь специфичны, что использование их в реальности приносит больше проблем, чем пользы. Иногда кеширование запроса полезно, но, увы иногда, а чаще всего бывает вредно. Самое печальное в такой схеме, что тот код, который знает, какие данные можно кешировать, а какие нет, находится на другом уровне абстракции, чем db класс.
установи в своем уровне абстракции флаг: кешировать/нет...
не надо решение об использовании кеша переносить на уровень абстракции доступа к данным, флаг должен задаваться на уровне модели данных и передаваться ниже...

в одном проекте я использовал специально разработанный абстрактный доступ к данным, вынесеный за пределы пхп. там - решение о выборе типа кеширования (мем или файл) определяется именно в модели данных. а данный модуль является только исполнителем.

мемкеш - это модуль доступа (вреппер к API ) к демону мемкеш. Для кеширования данных запроса - нужно разрабатывать свой скрипт кеширования. мой модуль - это конкретно - кеширование запросов.
не вижу принципиальной разницы.
тогда я не вижу принципиальной разницы между php_mysql и кеширующим скриптом
PHP:
$file = 'sql_cache.txt'; 
$link = mysql_connect('localhost','username','password') 
    or die (mysql_error()); 
mysql_select_db('shop') 
    or die (mysql_error()); 
/* form SQL query */ 
$query = "SELECT * FROM categories"; 
$result = mysql_query($query) 
    or die (mysql_error()); 
while ($record = mysql_fetch_array($result) ) { 
    $records[] = $record; 
} 
$OUTPUT = serialize($records); 
$fp = fopen($file,"w"); // open file with Write permission 
fputs($fp, $OUTPUT); 
fclose($fp);
 
Сверху