【问题标题】:Django database access speed depends on host used in requestDjango 数据库访问速度取决于请求中使用的主机
【发布时间】: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


【解决方案1】:

可以根据 IP 地址改变 Django 项目中行为的最常见的东西是 Django 调试工具栏。

在文档 (Performance considerations) 中,您可以阅读:

调试工具栏旨在引入尽可能少的开销 可能在页面的呈现。但是,根据您的 项目,开销可能会变得明显。 在极端情况下,它会使开发变得不切实际。

在最糟糕的情况下,我使用调试工具栏获得了大约 50 倍的响应时间。为了减少开销,您可以使用该文档中描述的设置。禁用 SQL 和缓存面板中的堆栈跟踪、模板上下文并删除重定向面板时,我得到了最好的结果:


DEBUG_TOOLBAR_CONFIG = {
    'ENABLE_STACKTRACES': False,
    'SHOW_TEMPLATE_CONTEXT': False,
    'DISABLE_PANELS': [
        'debug_toolbar.panels.redirects.RedirectsPanel',
    ]
}

无论如何,它应该在生产模式中完全禁用,并使用DEBUG = False 设置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    • 2023-03-30
    • 2019-08-10
    • 2010-12-03
    • 2010-11-22
    相关资源
    最近更新 更多