当Django对象具有多个外键时,如何命名/排列memcached键?

2024-05-23 16:45:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个现有的Django应用程序,它不做任何数据库缓存。我正在努力实现memcached以提高性能并减少昂贵的数据库访问量。在

我将使用的策略如下:每次我使用三十、 对象.get()或三十、 对象.过滤器(),我将首先检查缓存,以查看相同查询的结果是否已在memcached中。如果是的话,我就用这个。如果不是,我将查询数据库并用一个名为的键将其填充到memcached中。每当我更新这个查询的任何结果时,我都会使用Django的post_save()信号使该缓存键失效。听起来很简单,对吧?在

好吧,我在为如何命名我的缓存键而挣扎,这样才能有序地工作。问题是我有Django模型对象,这些对象具有指向其他两个Django模型的外键。在

以下是我的模型:

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)

在myObjectC的post_save handler()中,我需要使缓存键(一些是“名称1”X和“某些名称2”)无效,因为它们现在已过期。正确的?我想这就是我需要做的。在

但是如果每个类的每个实例都有很多这样的键呢?毕竟,每个人都有一把这样的钥匙三十、 对象.get()或三十、 对象.过滤器()每个实例调用。我必须手动使它们失效吗?难道没有一种系统化的方法可以同时命名和失效这些键而不必自己记住每个缓存条目吗?在


Tags: 对象django模型selfreturnmodelsmemcachedsome
1条回答
网友
1楼 · 发布于 2024-05-23 16:45:27

缓存需要一个可靠且精心设计的策略,因为您可能会以比实际情况更糟糕的方式结束。在大多数项目中,实际上并不需要高级缓存。为什么不在每次更新数据库时缓存页面并删除页面缓存?这将允许查询运行一次,但其余时间将检索缓存。如果您仍然坚持缓存,缓存使用唯一键,则可以根据唯一对象的id和名称创建它们的键组合。 如果更新或创建新对象并删除缓存,则信号是两种方法中的任意一种,但是正如您从自己的示例中看到的那样,页缓存比处理大量对象更容易处理。 除此之外,为什么不使用Django中的构建呢缓存.get, 缓存.set, 缓存.删除功能?这样可以保持项目的兼容性,并将代码与缓存引擎分离(也许明天redis将更适合您的需要)。在

相关问题 更多 >