Скорость доступа к базе данных Django зависит от хоста, используемого в запросе
У меня проблемы с производительностью/скоростью в приложении Python/Django/Postgres. В частности, скорость запросов к базе данных (через ORM Django), похоже, связана с именем хоста, используемым в запросе к django. В примерах, которые я использую, используется либо localhost
, либо имя хоста виртуальной машины (dev.virtual
). При использовании имени хоста производительность хорошая, но при использовании localhost
наблюдается значительное замедление (порядка десятков раз).
Я создал очень базовое представление, чтобы проверить это:
def generate_load_view(request, resource):
length = int(request.GET.get("length"))
length = 2 ** length
iterations = int(request.GET.get("iterations"))
iterations = 10 ** iterations
if resource == "compute":
load_generator = generate_compute_load
elif resource == "memory":
load_generator = generate_memory_load
elif resource == "database":
load_generator = generate_database_load
else:
raise Http404()
t_start = time.monotonic()
load_generator(length=length, iterations=iterations)
t_end = time.monotonic()
t_elapsed = t_end - t_start
response = {"time": t_elapsed}
return Response(response)
def generate_database_load(length, iterations):
model = django.contrib.contenttypes.models.ContentType
pks = model.objects.values_list("pk", flat=True)
for _ in range(iterations):
random_pk = random.choice(pks)
random_obj = model.objects.get(pk=random_pk)
Я использую объект django ContentType
из удобства.
), так и сервер manage.py
без заметных изменений.gunicorn
Повторюсь, если я делаю запрос к http://localhost/generate_load/
, он работает медленно, но если я делаю запрос (к тому же запущенному приложению, т.е. приложение не перенастраивается и даже не перезапускается) к http://dev.virtual/generate_load/
, он работает значительно быстрее. В обоих случаях запросы делаются с одной и той же виртуальной машины (т.е. с той же машины, на которой запущены приложение django и БД).
Даже при извлечении одного объекта БД наблюдается большая пропорциональная разница, которая, похоже, увеличивается с количеством извлекаемых объектов.
В моих тестах имя хоста рандомизируется (например, при выполнении 10 запросов к каждому, последовательность случайна, а не все сначала одно, потом другое).
Похоже, что замена 127.0.0.1
на localhost
не меняет ситуацию, поэтому я не думаю, что это связано с проблемами разрешения имени localhost
.
Я пробовал изменить строку подключения к БД, чтобы использовать альтернативные имена хостов для БД (например, localhost
и dev.virtual
), а также пробовал изменить SITE_DOMAIN
приложения django, но это ничего не изменило.
Я буду великолепно признателен за любую помощь в понимании и разрешении этой проблемы.
Самая удобная вещь, которая может изменить поведение в проекте Django в зависимости от IP-адреса - это панель инструментов отладки Django.
В документации (Performance considerations) вы можете прочитать:
Панель инструментов отладки разработана таким образом, чтобы вносить как можно меньше накладных расходов в процессе рендеринга страниц. Однако, в зависимости от вашего проекта, накладные расходы могут стать заметными. В крайних случаях это может сделать разработку нецелесообразной.
В моих наихудших сценариях я получил время отклика примерно в 50 раз медленнее при использовании панели инструментов отладки. Чтобы уменьшить накладные расходы, вы можете поиграть с настройками, описанными в документации. Я получил лучшие результаты, отключив стек-трейсинг в панелях SQL и кэша, контекст шаблона и удалив панель перенаправления:
DEBUG_TOOLBAR_CONFIG = {
'ENABLE_STACKTRACES': False,
'SHOW_TEMPLATE_CONTEXT': False,
'DISABLE_PANELS': [
'debug_toolbar.panels.redirects.RedirectsPanel',
]
}
В любом случае, Это должно быть полностью отключено в режиме производства с настройкой DEBUG = False
.