J'ai une application Django existante qui ne fait pas de mise en cache de base de données. Je travaille à l'implémentation de memcached pour améliorer les performances et réduire le nombre d'accès coûteux aux bases de données.Comment nommer/organiser mes clés memcached lorsque j'ai des objets Django avec plusieurs clés étrangères?
La stratégie que je vais utiliser est la suivante: Chaque fois que j'interroge la base de données avec XXX.objects.get() ou XXX.objects.filter(), je vais d'abord vérifier le cache pour voir si le résultat pour cette même requête est déjà en memcached. Si c'est le cas, je vais simplement l'utiliser. Si ce n'est pas le cas, je vais interroger la base de données et l'insérer dans memcached avec un spécifiquement nommé. Chaque fois que je mettrai à jour les résultats de cette requête, j'invaliderai cette clé de cache en utilisant le signal post_save() de Django. Cela semble assez simple, non? Eh bien, je me bats avec la façon dont je devrais nommer mes clés de cache afin que cela fonctionne de manière ordonnée. Le problème est que j'ai des objets modèles Django qui ont des clés étrangères pour 2 autres modèles Django.
Voici mes modèles:
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)
Dans le gestionnaire de post_save() pour myObjectC, je dois invalider les clés du cache SOME_NAME1_X et SOME_NAME2_X parce qu'ils sont maintenant hors de ce jour. Droite? Je pense que c'est ce que je dois faire.
Mais qu'en est-il s'il existe de nombreuses clés de ce type pour chaque instance de chaque classe? Après tout, il y aura une telle clé pour chaque appel XXX.objects.get() ou XXX.objects.filter() par instance. Dois-je les invalider tous manuellement? N'y a-t-il pas un moyen systématique de nommer et d'invalider ces clés en une seule fois sans avoir à me souvenir de chaque entrée du cache moi-même?
Avez-vous vraiment besoin de tout mettre en cache? Votre projet est-il si grand? 95% des projets s'en iront avec une mise en cache de modèle simple, et une mise en cache de jeu de requête mineure pour les requêtes complexes. – petkostas
Hmmm. Je n'ai pas considéré cela. Je pensais que c'était la façon de le faire. –
Si vous voulez utiliser le cache, la manière la plus simple est d'utiliser le framework de création de cache (vous pouvez avoir redis, memcached, etc.): https://docs.djangoproject.com/fr/1.6/topics/cache/ – petkostas