【问题标题】:Preventing slow queries from exausting gunicorn worker pool防止慢查询耗尽 gunicorn 工作池
【发布时间】:2014-03-14 08:15:43
【问题描述】:

假设我们有一个相当典型的 Django Web 应用程序:

  • 在应用程序前面有一个 Nginx 做代理和服务 静态内容
  • 有 gunicorn 启动 worker 来处理 Django 请求
  • 有基于 Django 的网络应用程序做各种有趣的事情
  • 有一个用于会话/缓存的 Redis 服务器
  • 有一个 MySQL 数据库为来自 Django 的查询提供服务

一些 URL 基本上只是一个渲染的 Django 模板,几乎没有查询,一些页面包含来自 Redis 的一些信息。 但是有一些页面会执行一些相当复杂的数据库查询,这可能(在所有可能的优化之后)需要几秒钟才能在 MySQL 端执行。

这是我的问题 - 每次 gunicorn 工作人员收到对此类 heavy URL 的请求时,它都会在一段时间内不再服务其他请求 - 它只是闲置在那里等待数据库回复。如果有足够多的此类查询,那么最终所有工作人员都只是闲置并等待 heavy URL,而没有人为其他更快的页面提供服务。

有没有办法让工作人员在等待数据库回复时做其他工作?或者在这种情况下以某种方式扩大工作池(最好不要同时扩大 RAM 使用量和数据库连接数:))?至少有没有办法找出关于有多少工作人员在一个 gunicorn 池中忙碌以及每个工作人员处理请求多长时间的统计数据?

【问题讨论】:

  • 你试过使用 gunicorn 的异步工作者类型吗?
  • 您可能还想将您的数据库查询单独发布到 Stackexchange,您可能会对一些您没有想到的优化感到惊讶。
  • 您可能会发现我在blog.dscpl.com.au/2014/02/… 的帖子很有趣。但是,由于没有适当的多线程选项,也没有在一个托管系统中垂直拆分应用程序的能力,gunicorn 实际上是这类优化的糟糕选择。

标签: python mysql django redis gunicorn


【解决方案1】:

一种可能适用于您的情况的简单方法是增加工作人员的数量。建议的工作人员数量为 2-4 x {NUM CPUS}。根据负载和对站点的请求类型,这可能就足够了。

如果增加工人数量还不够,下一步要研究的是使用异步工人(关于它的文档here)。更详细的配置选项在here 中描述。请注意,根据您选择使用的异步工作器类型,您必须安装 eventlet、gevent 或 tornado。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-24
    • 2015-01-18
    • 2017-07-10
    • 2022-01-03
    • 2015-06-04
    • 1970-01-01
    相关资源
    最近更新 更多