Утечка памяти с Django + Django Rest Framework + mod_wsgi
У меня есть следующий код, где у меня есть представление на основе функций, которое использует ModelSerializer для сериализации данных. Я запускаю это с apache + mod_wsgi (с 1 рабочим потоком, 1 дочерним потоком и 1 потоком mod_wsgi для простоты).
При этом мое использование памяти значительно возрастает (200–1G в зависимости от размера запроса) и остается там и не снижается даже после завершения запроса. При последующих запросах к одному и тому же представлению / URL-адресу память каждый раз немного увеличивается, но не делает значительного скачка. Чтобы исключить проблемы с django-filter, я изменил свое представление и сам написал запрос на фильтрацию.
Обычное подозрение, что DEBUG=True исключено, так как я не работаю в режиме DEBUG. Я даже пытался использовать гуппи, чтобы увидеть, что происходит, но я не смог далеко уйти с гуппи. Может кто-нибудь помочь, почему использование памяти не снижается после завершения запроса и как отладить его?
Обновление: я использую настройку 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)
1 ответ
Хотя я не могу сказать наверняка, я все равно добавлю это как ответ, чтобы судить об этом...
Как вы знаете, кеш по умолчанию в django LocMemCache
Который в вышеупомянутых документах вы найдете:
Обратите внимание, что у каждого процесса будет свой собственный экземпляр кеша
И я думаю, что это все, что вы видите. Скачок в памяти - это просто хранение вашего запроса. Я думаю, что вам нужно беспокоиться только о том, чтобы использование памяти продолжало расти за пределами нормы.
В том же документе говорится, что он может быть не очень жизнеспособным в производственном процессе, поэтому, возможно, пришло время выйти за рамки этого, что также позволит вам увидеть, является ли кеширование виновником.