Comments 14
Хабраюзер Suor когда-то анонсировал свою разработку — django-cacheops. В качестве хранилища используется только redis. Если этот факт не смущает, то, думаю, пост можно считать закрытым :-)
+1
Не очень понимаю, как это закрывает пост. К этому приложению применимы все те же две претензии:
Плюс, инвалидация только через удаление записи в кэше, что не всегда является лучшим решением (о чем я пишу в посте).
Приложение хорошее, да, не хуже тех, что перечислены в посте, но у меня не было цели сделать обзор всех готовых решений. Так что может рано пока закрывать? :-)
- Недостаточный контроль за инвалидацией: можно инвалидировать объект, можно инвалидировать все объекты модели, больше ничего.
- Ограничения, возможно, потребующие дополнительного кода (раздел Caveats)
Плюс, инвалидация только через удаление записи в кэше, что не всегда является лучшим решением (о чем я пишу в посте).
Приложение хорошее, да, не хуже тех, что перечислены в посте, но у меня не было цели сделать обзор всех готовых решений. Так что может рано пока закрывать? :-)
0
Недостаточный контроль за инвалидацией: можно инвалидировать объект, можно инвалидировать все объекты модели, больше ничего.
Все объекты кверисета. Со всеми его фильтрами. Что ещё нужно-то? :-)
Плюс, инвалидация только через удаление записи в кэше, что не всегда является лучшим решением (о чем я пишу в посте).
По-моему, Вы как раз и пишете, что обновлять данные в кеше не стоит, т.к. операция неатомарная. И таки да, это правильно.
Думаю, что пример с непосредственным вызовом операций типа incr и decr настолько частный случай (явное управление кешем с явно заданным бэкендом) не может рассматриваться как общий случай, который готовые решения покрывают. Я бы не стал эту претензию предъявлять ни к одному из generic-приложений. Случай не тот.
0
Что ещё нужно-то? :-)
Я приводил пример в посте. Часто, если в обработчике сигнала
created == True
, можно не инвалидировать часть ключей. Например, условно, топ100 статей за все время, свежесозданная статья туда не попадет. Есть и еще ряд проверок, которые могут оказаться очень полезными, чтобы не делать сложные выборки.И я не утверждаю, что это нужно всегда. Но что это есть, знать стоит, и учитывать при выборе подхода к кэшированию тоже стоит.
По-моему, Вы как раз и пишете, что обновлять данные в кеше не стоит, т.к. операция неатомарная.
Немного не о том. Я про то, что часто лучше заменить
cache.delete(key)
на cache.set(key, instance)
, если instance
передается в сигнал.В целом, спор кажется бесперспективным. Я же не говорю: не используйте готовое, пишите все сами, только хардкор и т. д. У готовых решений есть некоторые ограничения. Если они критичны (или есть какие-то другие причины), то можно рассмотреть возможность реализации кэша самостоятельно. Если не критичны, конечно, используйте готовое. Только и всего.
0
Насчёт только удаления — есть недокументированная возможность:
При сохранении юзера он будет закеширован по id, при сохранении профиля по user_id.
А так, в целом, конечно, никакое универсальное решение не универсально настолько, чтобы удовлетворить всех.
CACHEOPS = {
'auth.user': ('get', 60*15, {'cache_on_save': True}),
'people.userprofile': ('get', 60*15, {'cache_on_save': 'user'}),
}
При сохранении юзера он будет закеширован по id, при сохранении профиля по user_id.
А так, в целом, конечно, никакое универсальное решение не универсально настолько, чтобы удовлетворить всех.
0
У johny-cache на самом деле недостатков намного больше чем достоинств. И основной из них — то, что тормозная десериализация queryset'ов зачастую дает отрицательный выигрыш по сравнению с запросом в СУБД. Та же проблема у cache-machine.
Вообще, как подсказывает мой небольшой опыт, большая часть задач решается либо кешированием на уровне вьюх/шаблонов, либо точечным кешированием в считаных местах.
А за django-cached-modelform отдельное человеческое спасибо. Приятно, когда можно воспользоваться чьим-то готовым велосипедом ;)
Вообще, как подсказывает мой небольшой опыт, большая часть задач решается либо кешированием на уровне вьюх/шаблонов, либо точечным кешированием в считаных местах.
А за django-cached-modelform отдельное человеческое спасибо. Приятно, когда можно воспользоваться чьим-то готовым велосипедом ;)
+2
У Johnny Cache есть очень серьезная проблема — он кеширует radnom запросы. Приходится или дописывать какую-то динамическую фигню в запросы или лезть править его внутренности.
0
Не совсем про кверисеты, но как кеширование для меня работает: github.com/smn/django-dirtyfields
Началось все тут: stackoverflow.com/questions/110803/dirty-fields-in-django
Автор сам Armin Ronacher :)
Можно просто if self.is_dirty() — так можно узнать были ли вообще какие-либо изменения. В моем примере проверяется определенные поля.
DirtyFields — вообще обалденная штука. Можно не сохранять модель, если нет на то причины или делать проверку до сохранения.
Началось все тут: stackoverflow.com/questions/110803/dirty-fields-in-django
Автор сам Armin Ronacher :)
class Cacheable(object):
def cleanup(self):
cache.delete(':'.join([self.__class__.__name__, self.id]))
class AwesomeUser(models.Model, DirtyFieldsMixin, Cacheable):
name = models.CharField()
surname = models.CharField()
awesomeness = models.BigIntegerField()
def do_stuff(self):
# Does some awesome stuff
return
def save(self, *args, **kwargs):
# Processing
self.do_stuff()
# Gets modified fields
is_dirty = set(self.get_dirty_fields().keys()) \
& set(['awesomeness', 'name'])
super(AwesomeUser, self).save(*args, **kwargs)
# If got dirty
if is_dirty:
self.cleanup()
# do other stuff
Можно просто if self.is_dirty() — так можно узнать были ли вообще какие-либо изменения. В моем примере проверяется определенные поля.
DirtyFields — вообще обалденная штука. Можно не сохранять модель, если нет на то причины или делать проверку до сохранения.
0
Как именовать ключи?как известно, в CS есть только две трудные вещи. :)
Инвалидация
вероятно, здесь стоит упомянуть ещё одну стратегию — generational cache strategy (прочитать можно, например, тут www.regexprn.com/2011/06/web-application-caching-strategies_05.html), которая позволяет обходиться без явной инвалидации, благодаря использованию динамических ключей.
0
Так инвалидация будет удобней, но станет более «жадной», о чем и сам автор пишет.
Чаще всего это нежелательно. Хотя, можно группировать ключи более «гранулярно». Впервые я услышал о подобном подходе к организации ключей в этой прекрасной презентации.
For example if you update a post in a particular category, this strategy will expire all the keys for all the categories.
Чаще всего это нежелательно. Хотя, можно группировать ключи более «гранулярно». Впервые я услышал о подобном подходе к организации ключей в этой прекрасной презентации.
0
Only those users with full accounts are able to leave comments. Log in, please.
Еще о кэшировании в Django