【发布时间】:2022-01-11 10:18:53
【问题描述】:
我在 Python/Django/Postgres 应用程序中遇到性能/速度问题。具体来说,数据库查询的速度(通过 Django 的 ORM)似乎与对 django 的请求中使用的主机名有关。我使用的示例使用localhost 或VM 的主机名(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 对象。
数据库 (PostgreSQL) 在同一台机器上的 docker 容器中运行。我使用了 django 的开发服务器(通过manage.py)和gunicorn 服务器,没有明显的变化。
重申一下,如果我向http://localhost/generate_load/ 发出请求,它会很慢,但如果我向http://dev.virtual/generate_load/ 发出请求(向同一个正在运行的应用程序,即应用程序没有重新配置甚至重新启动),则速度会很慢快点。在这两种情况下,请求都来自同一个虚拟机(即运行 django 应用程序和数据库的同一台机器)。
即使在检索单个数据库对象时,也存在很大的比例差异,这似乎与检索到的对象数量成比例。
我的测试随机化了主机名(例如,在向每个请求发出 10 个请求时,顺序是随机的,而不是先一个,然后另一个)。
另外,我通过自定义 django 中间件查看了响应时间,该中间件测量 django 中的请求时间(即,从接收请求到返回响应之前的时间),所以这与应用接收或返回请求的速度(即客户端和应用之间的网络速度)。
似乎用127.0.0.1 替换localhost 并没有改变这一点,所以我认为这与解决localhost 名称的问题无关。我尝试向/etc/hosts 添加条目,看看这是否会改变一些事情:
127.0.0.1 inside
10.20.254.201 outside
outside IP 是 dev.virtual 解析的内容。行为相同,inside 慢,outside 快。
我尝试更改数据库连接字符串以使用数据库的替代主机名(例如,localhost 和dev.virtual),还尝试更改 django 应用程序的SITE_DOMAIN,但这并没有改变事情。
我会非常感谢任何帮助理解和解决这个问题。
【问题讨论】:
-
你在使用 django 调试工具栏吗?
-
@Tonio 是的,我是(或者至少,我启用了它)。我认为您已经解决了:针对
django-debug-toolbar的INTERNAL_IPS设置地址之一的请求都看到了减速。我不认为我会想看那里,所以非常感谢您非常!如果可以,为什么不将您的回复作为答案(包含您可能知道的任何详细信息来解释正在发生的事情)。
标签: python django postgresql