Comments 52
гм… а это случаем не дублирует теги? и какой оверхед при активном использовании (по памяти)?
-1
что значит «дублирует тэги»?
по памяти все нормально, структура в любом случае получается достаточно компактной. Можно еще оптимизировать, но это уже в качестве домашнего задания :)
по памяти все нормально, структура в любом случае получается достаточно компактной. Можно еще оптимизировать, но это уже в качестве домашнего задания :)
0
ну я о том, что тегами то же достигается — удаление разных сущностей (в разных местах) одной командой.
0
Статья про теги. Ваш К.О.
+1
UFO just landed and posted this here
тесты нечитабельные. они не выполняют ту работу, которую вы на них возложили — документирование. также — они совершенно не отражают главную «фичу» топика, такую как «групповое удаление».
по факту: куда более запутанная и сложная реализация, нежели теги. сложная в понимании, в основном
ps: «Подобный подход с успехом работал на проекте photofile.ru под нагрузкой около 4-х млн хитов в сутки.» из этого не значит, что с тегами было бы хуже :-)
по факту: куда более запутанная и сложная реализация, нежели теги. сложная в понимании, в основном
ps: «Подобный подход с успехом работал на проекте photofile.ru под нагрузкой около 4-х млн хитов в сутки.» из этого не значит, что с тегами было бы хуже :-)
0
тесты вполне нормально отражают суть. если есть конкретные притензии а не субъетивные, слушаю.
то же самое и по запутанности реализации. помоему проще просто некуда.
то же самое и по запутанности реализации. помоему проще просто некуда.
0
$this->assertEqual($cache->get(), '1');
$this->assertNotEqual($cache->get(), '2');
где эти ситуации описаны в тестах?
да, есть кейс:
$cache = new MemcacheCacher('key|key1');
$this->assertFalse($cache->exists());
но что будет, если удалить key? где? как догадаться? :-)
protected $header = array();
таким образом пресловутый кешхэдер хранится в памяти, пока не произойдёт перезапись. а что будет, если между этими событиями рядом работающий скрипт возьмёт и изменит хэдер? между получением кэша и его изменением — не обязательно ведь 2 строки, как в тестах. получение и изменение могут быть разделены между собой на десятки-сотню мс.
$this->assertNotEqual($cache->get(), '2');
$cache->delete('comments|counters');
ну или только счетчик пользователя
$cache->delete('comments|counters|user123');
Лучше всего о работе класса расскажет юнит-тест (они вообще часто лучше любой документации):
где эти ситуации описаны в тестах?
да, есть кейс:
$cache = new MemcacheCacher('key|key1');
$this->assertFalse($cache->exists());
но что будет, если удалить key? где? как догадаться? :-)
protected $header = array();
таким образом пресловутый кешхэдер хранится в памяти, пока не произойдёт перезапись. а что будет, если между этими событиями рядом работающий скрипт возьмёт и изменит хэдер? между получением кэша и его изменением — не обязательно ведь 2 строки, как в тестах. получение и изменение могут быть разделены между собой на десятки-сотню мс.
0
про «key» был невнимателен. остальное в силе :-)
0
>но что будет, если удалить key? где? как догадаться? :-)
А это что?
$cache = new MemcacheCacher('key');
$cache->del();
>а что будет, если между этими событиями рядом работающий скрипт возьмёт и изменит хэдер?
А вы подумайте что будет, ну и если обнаружите проблему, которую я не заметил, буду благодарен
А это что?
$cache = new MemcacheCacher('key');
$cache->del();
>а что будет, если между этими событиями рядом работающий скрипт возьмёт и изменит хэдер?
А вы подумайте что будет, ну и если обнаружите проблему, которую я не заметил, буду благодарен
0
эм. значение $header с устаревшими данными будет записано поверх свежих данных. м?
0
да, но ничего страшного не будет. в любом случае при получении данных из кеша, необходимо проверять что данные реально получены. Еще и потому что в любом случае они могут проэкспайрится или исчезнуть из-за глюка на сервере.
0
если данные могут быть потеряны из-за недостатков реализации — значит это повод задуматься о том, что эта реализация не айс. (мягкий намёк на теги, в миллионный раз).
0
данные не могут быть потеряны. с чего вы взяли?
0
дело в том, что в реализации с тэгами, всегда необходимо делать две выборки, и всегда необходимо выбирать данные из кэша. в моей же реализации мы всегда выбираем только кешхеадер, и по нему и только по нему определяем, надо ли выбирать основные данные (которые могут быть немаленькими, а это расходы памяти) или не надо. То есть, мой подход значительно менее ресурсоемкий как по использованию памяти, так и по количеству чтений из кеша, так и по количеству операций.
да, есть одна проблема. дело не в потерях данных, а в том что если вдруг два скрипта, параллельно обновляют кеш, то может случится ситуация, когда один из них удалил некую группу, а второй тут же записал данные, в которых эта группа не удалена. Но я писал выше что приведенный код несовершенен. Данная проблема решается
1. Разнесением кешхеадера. Сейчас все хранится под одним ключем 'cacheheder', но это не очень опитмально. Надо бы сделать не один корень, а несколько, по первым составным частям ключа. Тогда и запись будет более распределенной, то есть несколько скрипотов могут писать в кеш, не мешаю друг другу.
2. Можно добавить систему блокировок, которая исключит оставшийся шанс конфликта двух записей.
3. Можно при удалении данных, не только удалять их из хеадера, но и удалять из кеша тоже, тогда это, даже при присутвии в кешхеадере этих данных, заставит скрипт их обновить (как я уже говрил, клиент обязан проверять факт получения данных в любом подходе)
Но в любом случае, самая большая опасность состоит только в том, что в некоторых ситуациях может оказаться что некоторые данные не обновлились, хотя они были изменены. Но в реальности шанс такого стечения обстоятельств достаточно мал. В конце концов, мы не паримся насчет использования MyISAM в львиной доле наших проектов, хотя там такие ситуации тоже возможны. Но мы как то обходимся без транзакций.
да, есть одна проблема. дело не в потерях данных, а в том что если вдруг два скрипта, параллельно обновляют кеш, то может случится ситуация, когда один из них удалил некую группу, а второй тут же записал данные, в которых эта группа не удалена. Но я писал выше что приведенный код несовершенен. Данная проблема решается
1. Разнесением кешхеадера. Сейчас все хранится под одним ключем 'cacheheder', но это не очень опитмально. Надо бы сделать не один корень, а несколько, по первым составным частям ключа. Тогда и запись будет более распределенной, то есть несколько скрипотов могут писать в кеш, не мешаю друг другу.
2. Можно добавить систему блокировок, которая исключит оставшийся шанс конфликта двух записей.
3. Можно при удалении данных, не только удалять их из хеадера, но и удалять из кеша тоже, тогда это, даже при присутвии в кешхеадере этих данных, заставит скрипт их обновить (как я уже говрил, клиент обязан проверять факт получения данных в любом подходе)
Но в любом случае, самая большая опасность состоит только в том, что в некоторых ситуациях может оказаться что некоторые данные не обновлились, хотя они были изменены. Но в реальности шанс такого стечения обстоятельств достаточно мал. В конце концов, мы не паримся насчет использования MyISAM в львиной доле наших проектов, хотя там такие ситуации тоже возможны. Но мы как то обходимся без транзакций.
0
UFO just landed and posted this here
1. То же самое и у меня. Если в кешхеадере нет данных, из кеша не читаем.
2. Отличия в том, что в реализации с тегами может быть такая ситуация, при которой происходит чтение тэгов (1 операция), получение данных из кеша (2 операция) и после этого выясняется что данные устарели. В моем случае всегда можно определить устарели ли данные только на основе информации из кешхеадера.
>Меня это всегда напрягало, поэтому использую, преимущественно, InnoDB.
Это уже параноя.
2. Отличия в том, что в реализации с тегами может быть такая ситуация, при которой происходит чтение тэгов (1 операция), получение данных из кеша (2 операция) и после этого выясняется что данные устарели. В моем случае всегда можно определить устарели ли данные только на основе информации из кешхеадера.
>Меня это всегда напрягало, поэтому использую, преимущественно, InnoDB.
Это уже параноя.
0
UFO just landed and posted this here
>Вообще, при чтении тегов сразу определяется версия и «годность» данных ;)
Поподробнее ка, плиз.
>Это привычка. Осталась в наследство от Delphi. И считаю, что привычка хорошая ;).
Не понимаю причем тут Дэлфи. Я тоже раньше плотно на нем писал, но почему то привычки такой нет, зато есть чувство здравого смысла, и понимание того когда оно надо а когда нет.
Поподробнее ка, плиз.
>Это привычка. Осталась в наследство от Delphi. И считаю, что привычка хорошая ;).
Не понимаю причем тут Дэлфи. Я тоже раньше плотно на нем писал, но почему то привычки такой нет, зато есть чувство здравого смысла, и понимание того когда оно надо а когда нет.
0
UFO just landed and posted this here
причем тут время? речь то не о времени жизни кеша, а о том что данные были изменены и от этого утарели. а проверить это можно только выбрав сами данные и сравнив их версию со значением тэга. в моем же случае выбирать данные необходимости нет.
0
UFO just landed and posted this here
повторяю вопрос еще раз, как по одному только значению тэга можно понять надо ли выбирать данные?
0
в веб-программировании ситуаций когда несолько запросов работают как единое целое несравнимо меньше чем единичных запросов. так же как и ситуаций конкурентного доступа к ресурсам. таким образом «преимущественно, InnoDB» это параноя, ибо если исходить из реалий то необходимость использования innoDB по определению намного меньше в большинстве веб-приложений.
0
а да, я и не говорил что с тэгами было бы хуже, но, если не ошибаюсь, то тогда, когда этот подход был применен на фотофайле (более двух лет назад), реализации тэгов еще небыло.
0
habrahabr.ru/blogs/webdev/43539/ вот статья по тегам в мемкешед была.
0
Эээ… А смысл тогда в плоском кэшировании, если всё равно руки тянутся задеревить это?
0
Смысл все-таки в удобстве… хоть чуть-чуть по сравнении с совсем уж плоским кешированием.
К тому же кешарование в памяти — для быстроты доступа к данным, что ведь совсем не исключает желания группировать элементы.
К тому же кешарование в памяти — для быстроты доступа к данным, что ведь совсем не исключает желания группировать элементы.
+1
memcached устроен так, что он совершенно не тратит ресурсы на поиск данных, другими словами, скорость поиска нужного значения не зависит от количества данных в memcached.
0
Этто я подразумеваю.
Но допоперация поиска здесь настораживает.
Время оно не резиново.
Но допоперация поиска здесь настораживает.
Время оно не резиново.
0
Меня больше настораживает другое, что я описал в комменте ниже.
Как бы допоперация поиска стоит не так много. Тот же механизм блокировок через memcached чего стоит ))) Это не жалко, да и времени не так много займет. А вот передача пожирневшего «кешхеадер» будет стоить достаточно дорого :) Не столько процессорного времени, сколько iowait. А это может оказаться очень неприятно )
Как бы допоперация поиска стоит не так много. Тот же механизм блокировок через memcached чего стоит ))) Это не жалко, да и времени не так много займет. А вот передача пожирневшего «кешхеадер» будет стоить достаточно дорого :) Не столько процессорного времени, сколько iowait. А это может оказаться очень неприятно )
0
скажите, приминительно к вашему проекту сколько будет весить кешхеадер? Это же не сложно посчитать, достаточно построить хеш из используемых в проекте ключей, и серилизовать его.
0
Ну судя по графикам во всех мемкешах лежит что-то около 7М ключей. Это примерно половина всех сущностей, вторая половина, видимо, не востребована )
Строить хеш совершенно не интересно )
Строить хеш совершенно не интересно )
0
7м только ключей, без данных? И кто-то тут еще говорит об эффективности? Что за проект, если не секрет?
0
Онлайн игра Дозоры. У нас порядка 20М сущностей. От них никуда не денешься, все держим в мемкешах.
0
ну вероятно для онлайн игр то что я тут описал негодится. я не очень знаком со спецификой онлайн игр. Но вот на том же фотофайле было около 40М сущностей (сейчас гораздо больше), но проблем никаких небыло. Я думаю что ресурсы подобные фотофайлу на порядок распростаненее ресурсом типа онлайн-игры.
P.S. И все таки меня терзают смытные сомнения по поводу эффективности хранения такого количества сущностей в мемкеше. Ну да ладно.
P.S. И все таки меня терзают смытные сомнения по поводу эффективности хранения такого количества сущностей в мемкеше. Ну да ладно.
0
Т.е. вы предлагаете хранить структуру, которая помнит о всех объектах, хранящихся в кеше?
А если структура вырастет? По личному опыту знаю, что если в memcached класть данные размером порядка 1Мб, то это чревато частыми ошибками записи (причем почему-то больше записи) или чтения этих данных из кеша. К тому же передавать мегабайт данных по сети это далеко не мгновенно (если кеш находится на другой машине).
Иными словами если ваш «кешхеадер» разростется, это приведет к тормозам, которые будет трудно найти :)
Все сказанное мной относится к очень нагруженному проекту. На не очень больших нагрузках этого может и не случаться.
P.S.: если memcached начинает вытеснять данные, это сигнал, что в архитектуре допущен косячок :) Это не критично, но лучше такого не далать. Хотя бы из чувства прекрасного )))
PPS: Если у вас достаточно серьезный проект и вам нужен специфический функционал, то лучше будет взять исходники memcached и дописать то, что необходимо. Оно будет того стоить )
А если структура вырастет? По личному опыту знаю, что если в memcached класть данные размером порядка 1Мб, то это чревато частыми ошибками записи (причем почему-то больше записи) или чтения этих данных из кеша. К тому же передавать мегабайт данных по сети это далеко не мгновенно (если кеш находится на другой машине).
Иными словами если ваш «кешхеадер» разростется, это приведет к тормозам, которые будет трудно найти :)
Все сказанное мной относится к очень нагруженному проекту. На не очень больших нагрузках этого может и не случаться.
P.S.: если memcached начинает вытеснять данные, это сигнал, что в архитектуре допущен косячок :) Это не критично, но лучше такого не далать. Хотя бы из чувства прекрасного )))
PPS: Если у вас достаточно серьезный проект и вам нужен специфический функционал, то лучше будет взять исходники memcached и дописать то, что необходимо. Оно будет того стоить )
0
+1
Вот что-то такое у меня тоже имеется в мыслях.
С архитектурой где-то косяк явно.
Вот что-то такое у меня тоже имеется в мыслях.
С архитектурой где-то косяк явно.
0
повторяю, подобная архитектура работала без проблем на photofile.ru, одном из самых высоконагруженных фотохостингов рунета. Конечно же можно представить себе и более нагруженные проекты, но все таки кешхеадер размером в мегабайт мне очень сложно себе представить.
0
Ну у нас в среднем 12М хитов в сутки и подобное решение вымерло бы очень быстро :) Тем более при конкурентном доступе. Даже при размере кешхеадера в 100Кб это решение оказалось бы узким местом.
Я считаю, что вы где-то в архитектуре приняли неверное решение. При обновлении того же списка комментариев, куда менее затратно обновить все необходимые значения в кеше, чем почистить кеш и подкинуть работы базе данных. Кеш обычно вводится, когда база или какой-то ресурсоемкий код оказывается узким местом. И решение задачи типа «выльем воду из чайника, чем сведем задачу к предыдущей» в данном случае выглядит странным.
Я считаю, что вы где-то в архитектуре приняли неверное решение. При обновлении того же списка комментариев, куда менее затратно обновить все необходимые значения в кеше, чем почистить кеш и подкинуть работы базе данных. Кеш обычно вводится, когда база или какой-то ресурсоемкий код оказывается узким местом. И решение задачи типа «выльем воду из чайника, чем сведем задачу к предыдущей» в данном случае выглядит странным.
0
Вы видимо немного спутали мою статью с самоучителем по работе с мемкеш. Тема моей статьи узкая, она рассказывает только о том, как реализовать групповое удаление данных из кеша. И только то. А то о чем вы горите, это даже не очевидно. Удалять ли данные из кеша, или менять их там, решается конкретно даже не применительно к конкретному проекту, а применительно к конкретной части конкретного проекта. И это уже абслоютно другая тема, цели освятить которую в данной статье я перед собой не ставил. Как впрочем и хак мемкешеда на тему добавления нового функционала.
0
между прочим размер кешхеадера от количества хитов в сутки не зависит.
0
dklab.ru/lib/Dklab_Cache/
те же яйца, только аналитическая сторона вопроса более глубоко рассмотрена
получился велосипед
те же яйца, только аналитическая сторона вопроса более глубоко рассмотрена
получился велосипед
0
читайте комментарии выше.
1. Моя реализация была придумана раньше
2. Моя реализация оптимальнее по памяти и количеству обращений к мемкешу
1. Моя реализация была придумана раньше
2. Моя реализация оптимальнее по памяти и количеству обращений к мемкешу
0
Уважаемый Роман, приветсвую от имени людей, которым Фотофайл знаком не-по наслышке.
Идея описана не совсем верно, ибо во-первых, на Фотофайле никогда не складировались все сущности в так Вами называемый «кешхеадер», а для каждого набора сущностей он строился отдельно, при необходимости. А во-вторых, в реализаии в мета-данных указывалось не только наличие данных, но и expire, что существенно ускоряло работы системы в целом.
В одном вы действительно правы — вариант из ДКЛаб с тегами появился позднее.
Ну и ради справедливости указали бы, что идея изначально не Ваша.
С уважением.
Идея описана не совсем верно, ибо во-первых, на Фотофайле никогда не складировались все сущности в так Вами называемый «кешхеадер», а для каждого набора сущностей он строился отдельно, при необходимости. А во-вторых, в реализаии в мета-данных указывалось не только наличие данных, но и expire, что существенно ускоряло работы системы в целом.
В одном вы действительно правы — вариант из ДКЛаб с тегами появился позднее.
Ну и ради справедливости указали бы, что идея изначально не Ваша.
С уважением.
0
1. Я специально в примере указал что это всего лишь пример. И даже дальше, по ходу в комментариях я указал что целесообразнее разделить кешхеадер по первому ключу.
2. Я в курсе что там хранилось еще и время жизни, и даже написал что хранить там можно все что угодно. Повторяюсь, пример упрощенный.
3. Можно подробнее узнать, а чья же это, позвольте, идея? Ну как минимум моя и Антона, ибо эту реализацию мы обсуждали с ним вдвоем. Сама же реализация в коде была выполнена мной от и до.
2. Я в курсе что там хранилось еще и время жизни, и даже написал что хранить там можно все что угодно. Повторяюсь, пример упрощенный.
3. Можно подробнее узнать, а чья же это, позвольте, идея? Ну как минимум моя и Антона, ибо эту реализацию мы обсуждали с ним вдвоем. Сама же реализация в коде была выполнена мной от и до.
0
Все же Роман, слова о том, что нужно делить мета-данные по ключам — критичны, иначе затраты на сериализацию выйдут бешенные.
Ну и время жизни- тоже не помешает, хотя от него можно конечно отойти. Для примера. Недалеко.
з.ы. А времена были интересные, да…
Ну и время жизни- тоже не помешает, хотя от него можно конечно отойти. Для примера. Недалеко.
з.ы. А времена были интересные, да…
+1
Sign up to leave a comment.
Использование составных ключей для манипуляции данными в memcached