2016-12-01 3 views
0

У меня есть следующий код, где у меня есть представление, основанное на функции, которое использует ModelSerializer для сериализации данных. Я использую это с apache + mod_wsgi (с одной рабочей нитью, 1 дочерними потоками и 1 потоком mod_wsgi для простоты).Утечка памяти с Django + Django Rest Framework + mod_wsgi

При этом использование памяти значительно увеличивается (200M - 1G в зависимости от того, насколько велик запрос) и остается там и не падает даже по завершении запроса. При последующих запросах к одному и тому же представлению/url память немного увеличивается каждый раз, но не требует значительного перехода. Чтобы исключить проблемы с django-фильтрами, я изменил свое представление и сам написал запрос фильтрации.

Обычный подозреваемый, что DEBUG = True исключается, поскольку я не работаю в режиме DEBUG. Я даже пытался использовать guppy, чтобы посмотреть, что происходит, но я не смог уйти с гуппи. Может кто-то может помочь, почему использование памяти не сработает после завершения запроса и как его отладить?

Обновление: Я использую настройку по умолчанию CACHE, то есть я не определил ее вообще, и в этом случае я предполагаю, что она будет использовать локальную память для кеша, как указано в документах.

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

Какую базу данных вы используете? – Sayse

+0

@Sayse: Я оставил параметр CACHE по умолчанию. Я не определил его, и в этом случае он будет использовать LocalMemory для кеша, который я предполагаю. – Divick

+0

Я не верю, что это утечка, я думаю, что то, что вы видите, кэшируется данными, но я не думаю, что мне достаточно сказать наверняка .. ([кэширование локальной памяти] (https: //docs.djangoproject .com/ru/1.10/themes/cache/# local-memory-caching)) – Sayse

ответ

2

Пока я не могу сказать наверняка, я добавлю это как ответ в любом случае судить о нем ...

Как вы знаете, кэш Джанго по умолчанию является LocMemCache

что в приведенных выше документах вы найдете:

Обратите внимание, что каждый процесс будет иметь свой собственный экземпляр собственного кэша

И я думаю, что это все, что вы видите. Скачок в памяти - это просто хранение вашего запроса. Я думаю, вам нужно только беспокоиться о том, что использование этой памяти продолжает расти за пределами нормальной жизни.

В том же документе также говорится, что он может быть не очень жизнеспособным в производстве, поэтому, возможно, пришло время выйти за рамки этого, что также позволит вам увидеть, является ли кеширование виновником.