Контент


Мысли о Kohana::cache()

Неожиданно для себя обнаружил, что метод Kohana::cache($name, $data = NULL, $lifetime = 60) работает немного не так, как я ожидал. Предполагая, что параметр $lifetime (время жизни кэша, в секундах) надо указывать при сохранении данных, использовал Kohana::cache($name, $data, $lifetime) для кэширования и Kohana::cache($name) для извлечения из кэша. Вроде бы все логично, но…

Обратил внимание, что кэш практически не используется, т.е. течении дефолтных 60 секунд. Залез в исходники и увидел, что параметр $lifetime никак не сохраняется в файловом кэше. На основании вышеописанных рассуждений опубликовал патч, который позволяет хранить в кэше как сами данные, так и lifetime. Однако в комментариях Shadowhand высказал мнение, что время жизни должен указывать клиент (т.е. тот, кто запрашивает данные из кэша), в связи с чем патч был отклонен.

Тем не менее, вопросы остались. Почему просто не указать ОДИН раз время жизни при сохранении, а потом просто пытаться его считать? В частности, раньше библиотека Cache так и делала. Теперь же любой клиент должен использовать вызов Kohana::cache($name, NULL, $lifetime), а откуда он может знать оптимальный lifetime? В общем, ИМХО, неудобно и нелогично…

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Опубликовано в Kohana3.

Теги: , , .


Комментарии (36)

Будьте в курсе обсуждения, подпишитесь на RSS ленту комментариев к этой записи.

  1. Ъ пишет:

    я в своих поделках при кешировании в файлы делаю touch так, как будто файлы записаны в будущем. При чтении — сверяю время создания файла и текущее. Если файл не из будущего — кеш просрочен.

    Фигли тут сложного для разработчиков Коханы?

  2. aktuba пишет:

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

    Т.е., если никто не запрашивает данные их кеша — он хранится вечно? Бред…

  3. Сергей пишет:

    Согласен.. Довольно странное нестандартное поведение для кеша…
    А такой механизм только для файлового кеша?

  4. BIakaVeron пишет:

    Ъ
    Этот вариант еще лучше. Так можно автоматизировать очистку кэша по крону, т.к. не придется даже считывать содержимое файлов.
    aktuba
    С файловым кэшем в принципе так и будет. Файл удалится только если при обращении обнаружится его «просроченность». В общем-то, надо делать чистку вручную.
    Сергей
    Ну, в трешке я портированный кэш так пока и не посмотрел, но в 2.3.4 все было стандартно.

  5. BaRoN! пишет:

    Думаю, нормальное решение — для случаев, когда одни и те же данные могут отображаться либо на отдельных страницах либо в виде набора.
    Грубо: при выводе заметки в блоге, нужно показывать достоверное количество комментариев. На главной же странице точное значение количества комментариев не так важно, можно его обновить в кэше лишь при просмотре отдельной страницы.

  6. Vegnus пишет:

    По-моему логичней как раз, чтобы клиент указывал время. Ведь если делать так как Вы говорите, то у клиента нету никакой возможности сказать «дай ка мне обнавлённые данные». А это зачастую очень нужно.

  7. Славик Бубнов пишет:

    Мне нравится такой подход!

    Хотя сначала тоже наткнулся на эту «особенность» и был немного в замешательстве )))

  8. BIakaVeron пишет:

    @BaRoN!
    Как по мне, в таком случае лучше кэшировать отдельно блок с коротким анонсом статьи (в том числе и количество комментариев), нет?

    @Vegnus
    Клиент вообще не должен знать, из кэша данные или нет. Так же как и не может знать, к какому моменту времени кэш можно будет считать «просроченным». Этим должен заниматься объект, обладающий всей необходимой информацией, т.е. кэширующий объект.

    @Славик
    Честно говоря, не вижу в нем ничего полезного. К примеру, мы кэшируем данные о пользователе. Далее из десяти различным мест пытаемся загрузить их. Какой lifetime использовать? А если позже мы переделаем что-то в алгоритме кэширования и понадобится изменить lifetime?

  9. Бубнов Славик пишет:

    Думаю, клиент и правда не должен знать из кеша ли берутся его данные или нет.

    Но, вопрос что понимать под клиентом в данном случае.

    Допустим, у меня есть блок информации, который часто дергается разными модулями. Пусть это будут модули A и B.
    Модулю А считает, что кеш должен храниться 1 день, а модуль В считает, что 5 минут. В итоге при очередном обращении соответствующий модуль сам решает истекло ли время жизни кеша или нет — и если надо — обновляет его. Но модуль — это и есть в данном случае кеширующий объект, обладающий всей информацией. А функция Kohana::cache(…) — это просто функция ядра.

    То есть по сути модули А и В можно считать и клиентами, и кеширующими объектами одновременно.

    В любом случае все легко можно заточить под себя, если кто-то считает это неудобным =) Меня лично этот подход устраивает.

  10. aktuba пишет:

    2Бубнов Славик: что значит «Модулю А считает, что кеш должен храниться 1 день, а модуль В считает, что 5 минут.»? Модуль вообще не должен знать, в кеше данные, в базе или вообще на другом сайте. Модуль запрашивает — ядро отдает. Поэтому ядро и должно решать, какой фрагмент сколько хранить

  11. Бубнов Славик пишет:

    Почему не должен-то?! =)

    На самом деле используя в контроллере методы модулей (пусть это будут те же А и В) А->get_data() и B->get_data() — я не думаю о том, насколько актуален кеш и откуда вообще берутся данные. Я эту логику прописал в модуле, который и решает эти вопросы )))

    Или я что-то не так понял? Поправьте плиз если что.

  12. aktuba пишет:

    >На самом деле используя в контроллере методы модулей (пусть это будут те же А и В) А->get_data() и B->get_data() — я не думаю о том, насколько актуален кеш и откуда вообще берутся данные.

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

  13. Бубнов Славик пишет:

    Ну, так и я о том же =) Может просто недопоняли друг-друга ;-)

  14. BIakaVeron пишет:

    Подолью еще немного огоньку в обсуждение ;)

    На самом деле используя в контроллере методы модулей (пусть это будут те же А и В) А->get_data() и B->get_data() — я не думаю о том, насколько актуален кеш и откуда вообще берутся данные. Я эту логику прописал в модуле, который и решает эти вопросы ))

    Так все-таки модули A и B определяют время жизни кэша? Из приведенной выше фразы следует так. Как по мне, если мы храним в кэше собственно данные (не сгенерированный output в виде готового HTML или чего-то подобного, а чистые данные), то они должны быть постоянно актуальными (исключение разве что если там есть часто меняющаяся статистика, которую имеет смысл обновлять с некоторыми интервалами). Например, хранится в кэше последние 10 комментариев блога. При написании комментария автоматически производится перезапись в кэш новых значений.

  15. Бубнов Славик пишет:

    Модули А и В действительно определяют время жизни кеша, но каждый в своем контексте.

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

    Если честно не вижу никаких проблем здесь или противоречий.

  16. aktuba пишет:

    2Бубнов Славик:

    >Модули А и В действительно определяют время жизни кеша, но каждый в своем контексте.

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

    >Что для одного актуально, для другого устарело и он это обновляет.

    Да не должен он решать устарели данные или нет. Модуль должен получить данные, которые ему дали, и обработать их. А откуда они полученны (кеш или баз), модуль даже знать не должен.

  17. Бубнов Славик пишет:

    Хотел прийти к какому-то пониманию, но выходит какой-то холивар )))

    Что одному «бред», другому вполне понятно и подходит )))
    Я, лично, нормально смотрю на эту логику, пусть она и отличается от стандартных мехнизмов кеширования, к которым все привыкли, как к любимой кружке для чая/кофе ;)

    Считаю необходимым в таком случае вернуться к написанному мною ранее:

    > В любом случае все легко можно заточить под себя, если кто-то считает это неудобным =)

  18. Zares пишет:

    Может хватит уже бороться с этим странным изобретением, носящим такое липкое название — кэш?
    Уверен — оно не заслуживает того…
    Ведь на самом деле — что такое кэш? — Некоторый блок данных в текстовом формате…
    Так положите вместо него файл данных SQLite и сбрасывайте туда то, что называете кэшем, и обновляйте его напрямую — затраты на все это гораздо меньше, чем на кеширование плюс масса других положительных моментов ;)
    А еще лучше — использовать разделение всех данных ресурса на оперативные и постоянные, ну и соответственно разделить при этом нагрузку между MySQL и SQLite.

  19. BIakaVeron пишет:

    @Zares
    Можете кинуть в меня камнем, но ведь по сути использование SQLite — то же кеширование, только с использованием другого средства для хранения…

  20. Zares пишет:

    (но ведь по сути использование SQLite — то же кеширование, только с использованием другого средства для хранения…)

    …но с прямым доступом для оперативного обновления и при этом — значительно меньшим потреблением ресурсов системы…

  21. aktuba пишет:

    Ну во-первых: кто сказал, что кеш — это текстовые данные? ;)
    Это может быть и объект, и класс, и изображение и т.д.
    Во-вторых, SQLite будет очень проигрывать тому-же мемкешу, а при нагрузках вообще может положить систему.
    В третьих — использовать SQL-базу для кеша бессмыслено. С таким же успехом можно использовать MySQL с типом таблиц MEMORY.

    Кеш нужен, в первую очередь, для ускорения работы системы. И тут любая база, включая SQLite, будет очень сильно проигрывать обычным файлам или, тем более, мемкешу.

  22. Zares пишет:

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

    Кстати, не мне объяснять то, что «положить» сервер не составит труда и без БД :)

    Главная причина этой проблемы состоит в неразумном построении логики приложения.

    Мало того, что PHP-интерпретатор трудится изо всех сил, собирая (по сотни, тысячи раз в секунду) в кучу все, что нужно для того, чтобы склеить и выдать «нагора» элементарный HTML, в том числе и, винимая это из базы данных… видители, потому, что однажды программисту таким путем было на пару часов быстрее завершить работу над скриптом а затем это стало стандартным подходом!

    Во-вторых — в большинстве случаев отсутствует оптимальное структурирование данных, хранящихся в БД.

    Ведь не проблема выдать одни и те-же наборы данных сотням, тысячам клиентов…

    Проблема в том, что, когда один запрашивает данные — десятки-сотни других в этот момент обновляют их!

    Попробуйте в таблицу с записями добавить поле счетчика количества просмотров плюс поле даты последнего просмотра статьи, например…

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

    Но вот когда дело доходит до использования МЕМКЕША, особенно, например в работе со скриптом на CodeIgniter — тут я спокойно, молча, тихо удаляюсь…

  23. aktuba пишет:

    2Zares: как-то много воды и ничего по сути ;) . Вы писали сайты с большими нагрузками? Подскажете, как сделать многопользовательский блог с комментированием (древовидным) и т.д. Чтобы без кеширования держало 150000-200000 уникальных пользователей в сутки и около 2 000 000 просмотров. Если скажете — буду рад научится подобному.

  24. Zares пишет:

    @aktuba
    О таких вещах не говорят — их просто делают.
    Нет, ошибаюсь — говорят …когда не получается сделать :|

  25. aktuba пишет:

    2Zares: ну это вы зря… Покажите, расскажите — мне действительно интересно (только не предлагайте переводить все на html/ssi). Просто я занимаюсь подобным сайтом и было бы полезно разгрузить его.

    Вот только у меня кое-какие сомнения… Фраза «Но вот когда дело доходит до использования МЕМКЕША, особенно, например в работе со скриптом на CodeIgniter — тут я спокойно, молча, тихо удаляюсь…» говорит о том, что вы не работали с подобными нагрузками. Надеюсь я ошибаюсь ;) .

  26. Zares пишет:

    @aktuba
    Да нет, по-видимому Вы меня не правильно поняли!

    Я не разработчик — я из тех, кто эксплуатирует, и я скорее ищу того, кто сделает то, что мне нужно и при этом — так как мне нужно, а не так как удобно, собственно, разработчику…

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

  27. aktuba пишет:

    >Я не разработчик — я из тех, кто эксплуатирует, и я скорее ищу того, кто сделает то, что мне нужно и при этом — так как мне нужно, а не так как удобно, собственно, разработчику…

    Чаще всего это неверный подход. Лучше давать концепцию разработчику, а реализацию пусть делает он. Конечно бывают исключения, но…

    По поводу меня — тут все сложно =). Я начинал как разработчик десктоп-приложений, а на веб-разработку перешел по необходимости =). Консультации… Пара форумов и несколько друзей — отличных разработчиков. Например, Александр Макаров (rmcreative.ru).

  28. Zares пишет:

    У меня за долгие годы работы в WEB сложилось такое впечатление, что те программисты, которые пришли в веб-программирование из С++ или JAVA имеют несколько предвзятые представления о реализации тех или иных концепций построения веб-приложений.

    Почему-то в большинстве случаев ограничиваются использованием MVC паттерна, возможно потому, что подобное ранее использовали в построении GUI десктопных приложений…

    Ну и, возможно, не совсем корректно говорить об этом в данной теме, на этом блоге, но все-же, как Вы относитесь к не MVC системам, flourishlib вчастности?

  29. aktuba пишет:

    Скорее всего вы правы, в большинстве случаев. Но, как ни странно, я, в данном случае, исключение =), хотя именно MVC мне близко, т.к. мне очень нравится Delphi.

    Все просто — взгляды на какую-то технологию/реализацию очень зависят от опыта работы. Если человек писал простенькие утилиты — вряд ли ему вообще известно понятие MVC. И наоборот — если человек занимался проектированием довольно серьезных приложений, то MVC (или что-то подобное) само появляется ;) .

    Если же взять за основу именно мой опыт, то использовать Model-View-Controller я начал очень поздно в вебе. Да и сейчас я использую немного иначе данную концепцию, не так, как этому учат в многочисленных статьях =).

    А по поводу flourishlib — даже не знаю, что это такое.

  30. KotDev пишет:

    А как использовать например memcached в kohana 3?

  31. BIakaVeron пишет:

    На github’е есть модуль Cache.

  32. aktuba пишет:

    2KotDev: а в чем сложность-то? Что-то я вопрос не понял…

  33. KotDev пишет:

    Сложность в том что нет официального модуля для кэша. А установив тот модуль с github’a получил такую ошибень
    ErrorException [ Warning ]: Invalid argument supplied for foreach()

    SYSPATH/classes\kohana\arr.php [ 213 ]
    208 public static function merge(array $a1)
    209 {
    210 $result = array();
    211 for ($i = 0, $total = func_num_args(); $i $val)
    214 {
    215 if (isset($result[$key]))
    216 {
    217 if (is_array($val))
    218 {

  34. KotDev пишет:

    Пардоньте парни, ставил модуль от некого Nergal’a он и выдал ошибку. Этот же работает. Спасибо

  35. Юрец пишет:

    Писец, я думал только политики срутся как сабаки :)
    Хотел бы высказаться «в защиту» Бубнов Славик и девелопера Kohana.
    Я уверен что это очень хорошо, что время жизни хеша оставлено «на откуп» клиенту-модулю. Бывают ситуации когда этот хещ нужно обновлять 1 раз в неделю а то и в месяц, а бывают ситуации когда его нужно обновлять 1 раз в час. При описанном Бубнов Славик подходе к делу в нужном модуле (класе, методе) меняеш циферю и вуаля.) Интересно как выкручиватся если у тебя лайтайм забит жестко где то в ядре и ты с модуля не имееш даже понятия откуда данные берутся? ;-) Думаю что скорее всего этим минималистическим выиграшем народ.ру пренебрегает …

    И еще раз, «Программеры всех стран, классов, методов и фреймворков — ОБЪЕДИНЯЙТЕСЬ». Хорош мерятся … сами знаете чем. Работы всем хватит, бери да делай. :-)

  36. BIakaVeron пишет:

    @Юрец
    1. Все же обычно одни и те же данные имеют постоянный lifetime. Ну как может быть, что в одном модуле кэш последних десяти комментов считается актуальным в течении 1 минуты, в другом и 10 минут не предел? Данные они и есть данные, они одни и те же.
    2. А модуль и не должен знать, откуда данные берутся (из кэша или нет, стоит ли им доверять и т.д.) — он их просто запрашивает. А источник данных уже сам анализирует, есть что-то стоящее в кэше, надо ли запросить БД и т.д.



Можно включить подсветку кода: <code><pre lang="">...</pre></code>
Разрешены некоторые HTML теги

или используйте trackback.