当我有多个外键的Django对象时,如何命名/排列我的memcached键? [英] How to name/arrange my memcached keys when I have Django objects with multiple foreign keys?

查看:148
本文介绍了当我有多个外键的Django对象时,如何命名/排列我的memcached键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个现有的Django应用程序不执行任何数据库缓存。我正在努力实现memcached以获得性能提升,并减少昂贵的数据库命中数量。



我将使用的策略如下:每当我使用XXX.objects.get()或XXX.objects.filter()查询数据库时,我将首先检查缓存以查看这个相同查询的结果是否已经在memcached中。如果是的话,我会用这个。如果不是,我将查询DB并将其填入memcached,并使用专门命名的键。任何时候我更新此查询的任何结果,我将使用Django的post_save()信号使该缓存键失效。听起来很简单,对吗?



嗯,我正在努力地命名我的缓存键,这样有效地工作。问题是我有Django模型对象有外键2个其他Django模型。



这是我的模型:

  memCache = pylibmc.Client([127.0.0.1])

class myObjectA(models.Model):
field1 = models .CharField(max_length = 255)

def getC_Children(self):
如果SOME_NAME1_%s在memCache中的%self.pk:
返回memCache [SOME_NAME1_%s %self.pk]
else:
newCacheEntry = myObjectC.objects.filter(fk_myObjectA = self)
memCache [SOME_NAME1_%s%self.pk] = newCacheEntry
return newCacheEntry




class myObjectB(models.Model):
field2 = models.CharField(max_length = 255)

def getC_Children(self):
如果SOME_NAME2_%s在memCache中的%self.pk:
返回memCache [SOME_NAME2_%s%self.pk]
else:
newCacheEntry = myObjectC.objects.filter(fk_myOb jectB = self)
memCache [SOME_NAME2_%s%self.pk] = newCacheEntry
return newCacheEntry



class myObjectC(models.Model )
fk_myObjectA = models.ForeignKey(myObjectA,related_name =Blah_Blah)
fk_myObjectB = models.ForeignKey(myObjectB,related_name =Blah_Blah2)
field3 = models.CharField(max_length = 255)

在myObjectC的post_save处理程序()中,我需要使缓存键SOME_NAME1_X和SOME_NAME2_X无效因为他们现在已经过时了。对?我认为这是我需要做的。



但是,如果每个类的每个实例都有这样的密钥呢?毕竟,每个实例的每个XXX.objects.get()或XXX.objects.filter()调用都会有一个这样的密钥。我必须手动使它们全部失效吗?没有一个系统的方式来命名和无效这些密钥,而不必自己记住每个缓存条目。

解决方案

缓存需要一个坚实和精心制定的策略,因为你可能会比他们更糟糕的事情。在大多数项目中,您实际上不需要高级缓存。为什么每次更新数据库时都不会缓存页面并删除页面缓存?这将允许查询运行一次,但是缓存将被检索的其余时间。如果您仍然坚持使用唯一的密钥缓存,则可以通过唯一对象id及其名称创建密钥组合。
如果您更新或创建新对象并删除缓存,则可以使用信号,但是从您自己的示例可以看出,页面缓存的处理方式要比通过大量对象。
除此之外,为什么不使用Django中的build.get,cache.set,cache.delete函数?这样,您可以保持项目的兼容性,并将代码与缓存引擎分离(也许明天再更适合您的需要)。


I have an existing Django app that doesn't do any Database caching. I am working to implement memcached to get a performance boost and reduce the amount of expensive database hits.

The strategy I will use is as follows: Every time I am querying the DB with XXX.objects.get() or XXX.objects.filter(), I will first check the cache to see if the result for this same query is already in memcached. If it is, I will just use that. If it is not, I will query the DB and stuff it into memcached with a specifically named key. Any time I update any results of this query, I will invalidate that cache key by using Django's post_save() signal. Sounds fairly simple, right?

Well, I'm struggling with how I should name my cache keys so that this works in an orderly fashion. The issue is that I have Django model objects that have foreign keys to 2 other Django models.

Here are my models:

memCache = pylibmc.Client(["127.0.0.1"])

class myObjectA(models.Model):  
    field1 = models.CharField(max_length=255)

    def getC_Children(self):
        if "SOME_NAME1_%s" % self.pk in memCache:
           return memCache["SOME_NAME1_%s" % self.pk]
        else:
           newCacheEntry = myObjectC.objects.filter(fk_myObjectA=self)
           memCache["SOME_NAME1_%s" % self.pk] = newCacheEntry
           return newCacheEntry




class myObjectB(models.Model):  
    field2 = models.CharField(max_length=255)

    def getC_Children(self):
        if "SOME_NAME2_%s" % self.pk in memCache:
           return memCache["SOME_NAME2_%s" % self.pk]
        else:
           newCacheEntry = myObjectC.objects.filter(fk_myObjectB=self)
           memCache["SOME_NAME2_%s" % self.pk] = newCacheEntry
           return newCacheEntry



class myObjectC(models.Model):  
    fk_myObjectA = models.ForeignKey(myObjectA, related_name="Blah_Blah") 
    fk_myObjectB = models.ForeignKey(myObjectB, related_name="Blah_Blah2") 
    field3 = models.CharField(max_length=255)

In the post_save handler() for myObjectC, I need to invalidate the cache keys SOME_NAME1_X and SOME_NAME2_X because they are now out-of-date. Right? I think that's what I need to do.

But what if there are numerous such keys for each instance of each class? After all, there will be one such key for each XXX.objects.get() or XXX.objects.filter() call per instance. Do I have to invalidate them all manually? Isn't there a systematic way to name and invalidate these keys all at once without having to remember each cache entry myself?

解决方案

Caching requires a solid and carefully crafted strategy because you might end doing things worse than they are. In most of the projects you actually don't need advanced caching. Why don't you cache the page and delete the page cache each time your DB is updated? this will allow the query to run once but the rest of the times the cache will be retrieved. If you still insist for caching, cache using a unique key, they key combination could be created by the unique objects id and the name of it. Signals are the way to go either way, if you update or create and new object delete the cache, but as you can see from your own example, a page cache is way more easily treated than going through a large number of objects. Apart from that, why don't you use the build in Django cache.get, cache.set, cache.delete function? this way you keep compatibility of your project and decouple your code from the cache engine (maybe tomorrow redis will be more preferred to your needs).

这篇关于当我有多个外键的Django对象时,如何命名/排列我的memcached键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆