Кэширование нумеровавших страницы результатов, производящих чистку на обновлении - как решить?

db.accommodations.find({"name":{"$exists":true, "$ne":[], "$not":{"$size":1}}})
5
задан Factor Mystic 21 September 2008 в 03:52
поделиться

8 ответов

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

Если Вы находите, что 80% Ваших представлений форума смотрят на первую страницу потоков, то Вы могли решить кэшировать ту страницу только. Это означало бы и чтения кэша и записи, намного более просты к implment.

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

5
ответ дан 18 December 2019 в 06:52
поделиться

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

ExtendedMemcache->set метод принимает 3 args ($strGroup,$strKey, $strValue) При вызове набора он сохранит отношения между $strGroup, и $strKey, в защищенном свойстве и затем продолжают хранить $strKey кому: $strValue отношения в memcache.

Можно затем добавить новый метод к ExtendedMemcache класс, названный "deleteGroup", который при передаче строка, найдет, что ключи, связанные с той группой, и, производят чистку каждого ключа в свою очередь.

Это было бы что-то вроде этого: http://pastebin.com/f566e913b я надеюсь все, что имеет смысл и удается для Вас.

PS. Я предполагаю, хотели ли Вы использовать статические вызовы, защищенное свойство могло бы быть сохранено в memcache самостоятельно под своим собственным ключом. Просто мысль.

5
ответ дан 18 December 2019 в 06:52
поделиться

Просто обновление: Я решил, что точка Josh's на использовании данных была очень хорошей. Люди вряд ли будут продолжать просматривать страницу 50 форума.

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

Таким образом, я могу использовать единственный ключ кэша на форум, и он прилагает очень мало усилий для очищения/обновления кэша :-)

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

Спасибо!

7
ответ дан 18 December 2019 в 06:52
поделиться

Будьте очень осторожны относительно выполнения этого вида оптимизации, не имея неопровержимых фактов для измерения против.

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

1
ответ дан 18 December 2019 в 06:52
поделиться

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

2
ответ дан 18 December 2019 в 06:52
поделиться

Одно возможное решение не состоит в том, чтобы нумеровать страницы кэш потоков на форуме, а скорее вставить информацию о потоке к Forum::getThreads|$iForumId. Затем в Вашем коде PHP только вытаскивают тех, Вы хотите для той данной страницы, например.

$page = 2;
$threads_per_page = 25;
$start_thread = $page * $threads_per_page;

// Pull threads from cache (assuming $cache class for memcache interface..)
$threads = $cache->get("Forum::getThreads|$iForumId");

// Only take the ones we need
for($i=$start_thread; $i<=$start_thread+$threads_per_page; $i++)
{
    // Thread display logic here...
    showThread($threads[$i]);
}

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

1
ответ дан 18 December 2019 в 06:52
поделиться

flungabunga: Ваше решение очень близко к тому, что я ищу. Единственная вещь, мешающая мне делать это, должна сохранить отношения в кэш-памяти после каждого запроса и загрузки их назад.

Я не уверен, сколько из производительности совершает нападки, это означало бы, но это кажется немного неэффективным. Я буду делать некоторые тесты и видеть, как это удается. Спасибо за структурированное предложение (и некоторый код для показа для него, Спасибо!).

1
ответ дан 18 December 2019 в 06:52
поделиться

В ответ на flungabunga:

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

например.

get seqno_mygroup
23

get mygroup23_mykey
<mykeydata...>
get mygroup23_mykey2
<mykey2data...>

Затем "удалить" группу просто:

incr seqno_mygroup

Вуаля:

get seqno_mygroup
24

get mygroup24_mykey
...empty

и т.д.

1
ответ дан 18 December 2019 в 06:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: