2016-12-01 2 views
0

Ich habe den folgenden Code, wo ich eine funktionsbasierte Ansicht habe, die einen ModelSerializer verwendet, um Daten zu serialisieren. Ich führe dies mit Apache + mod_wsgi (mit 1 Worker-Thread, 1 Kind-Threads und 1 Mod_wsgi Threads der Einfachheit halber).Speicherleck mit Django + Django Rest Framework + mod_wsgi

Damit nimmt meine Speicherbelegung deutlich zu (200M - 1G, basierend auf der Größe der Abfrage) und bleibt dort und geht auch bei Abschluss der Anfrage nicht runter. Bei nachfolgenden Anfragen an die selbe Ansicht/URL erhöht sich der Speicher jedes Mal leicht, nimmt jedoch keinen signifikanten Sprung. Um Probleme mit dem Django-Filter auszuschließen, habe ich meine Ansicht geändert und selbst eine Filterabfrage geschrieben.

Der übliche Verdacht, dass DEBUG = True ist ausgeschlossen, da ich nicht im DEBUG-Modus ausgeführt werde. Ich habe sogar versucht, Guppy zu benutzen, um zu sehen, was passiert, aber ich konnte mit Guppy nicht weit kommen. Könnte jemand bitte helfen, warum die Speicherauslastung nicht nach dem Abschluss der Anfrage zurückgeht und wie man sie debuggt?

Update: Ich verwende Standard-CACHE-Einstellung, d. H. Ich habe es überhaupt nicht definiert, in diesem Fall nehme ich an, dass es den lokalen Speicher für den Cache verwenden wird, wie in den Dokumenten erwähnt.

CACHES = { 
    'default': { 
     'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 
    } 
} 



class MeterData(models.Model): 
    meter = models.ForeignKey(Meter) 
    datetime = models.DateTimeField() 

    # Active Power Total 
    w_total = models.DecimalField(max_digits=13, decimal_places=2, 
            null=True) 
    ... 


class MeterDataSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = MeterData 
     exclude = ('meter',) 


@api_view(['GET', ]) 
@permission_classes((AllowAny,)) 
def test(request): 
    startDate = request.GET.get('startDate', None) 
    endDate = request.GET.get('endDate', None) 
    meter_pk = request.GET.get('meter', None) 
    # Writing query ourself instead of using django-filter to 
    # to keep things simple. 
    queryset = MeterData.objects.filter(meter__pk=meter_pk, 
             datetime__gte=startDate, 
             datetime__lte=endDate) 


    logger.info(queryset.query) 
    kwargs = {} 
    kwargs['context'] = { 
     'request': request, 
     'view': test, 
     'format': 'format', 
    } 
    kwargs['many'] = True 

    serializer = MeterDataSerializer(queryset, **kwargs) 
    return Response(serializer.data) 
+0

Welches Cache-Backend verwenden Sie? – Sayse

+0

@Sayse: Ich habe die CACHE-Einstellung auf Standard, d. H. Nicht definiert, in diesem Fall wird LocalMemory für Cache verwendet ich vermute. – Divick

+0

Ich glaube nicht, dass es ein Leck ist, ich denke, was Sie sehen, ist Daten im Cache, aber ich glaube nicht, dass ich genug habe, um sicher zu sagen .. ([lokaler Speicher Caching] (https: //docs.djangoproject .com/de/1.10/topics/cache/# local-memory-caching)) – Sayse

Antwort

2

Während ich nicht mit Sicherheit sagen kann, werde ich dies als eine Antwort hinzufügen ohnehin auf beurteilt werden ...

Wie Sie wissen, Djangos Standard-Cache ist die LocMemCache

, die in den oben genannten Dokumenten finden Sie:

Beachten Sie, dass jeder Prozess über eine eigene Cache-Instanz

hat

Und ich denke, das ist alles, was Sie sehen. Der Speichersprung ist nur der Speicher Ihrer Abfrage. Ich denke, Sie müssen sich nur Gedanken darüber machen, ob dieser Speicherverbrauch weiterhin über die Normalität hinausgeht.

Das gleiche Dokument sagt auch, dass es in der Produktion möglicherweise nicht sehr lebensfähig ist, also könnte es Zeit sein, darüber hinauszugehen, was Ihnen auch erlauben würde zu sehen, ob Caching der Schuldige war.