【问题标题】:Docker/Kubernetes + Gunicorn/Celery - Multiple Workers vs Replicas?Docker/Kubernetes + Gunicorn/Celery - 多个工人与副本?
【发布时间】:2019-01-07 15:52:52
【问题描述】:

我想知道使用 gunicorn 和 celery 部署容器化 Django 应用程序的正确方法是什么。

具体来说,这些进程中的每一个都有一个内置的垂直缩放方式,使用 workers 表示 gunicorn 和 concurrency 表示 celery。然后是 Kubernetes 使用 replicas 进行扩展的方法

还有一个概念是将workers设置为CPU的某些功能。 Gunicorn推荐

每个核心 2-4 个工人

但是,我对这在 CPU 是可分割共享资源的 K8s 上的含义感到困惑 - 除非我使用 resoureceQuotas。

我想了解什么是最佳实践。我能想到三个选项:

  • gunicorn 是否有单个 worker,celery 是否有 1 个并发,并使用副本对其进行扩展? (水平缩放)
  • 让 gunicorn 和 celery 在具有内部缩放(垂直缩放)的单个副本部署中运行。这意味着分别设置相当高的工人和并发值。
  • 一种介于 1 和 2 之间的混合方法,我们运行 gunicorn 和 celery,对工人和并发性的价值很小(比如 2),然后使用 K8s 部署副本进行水平扩展。

围绕这个有一些关于 SO 的问题,但没有一个提供深入/周到的答案。如果有人可以分享他们的经验,将不胜感激。

注意:我们为 Gunicorn 使用默认的 worker_class sync

【问题讨论】:

    标签: django docker kubernetes celery gunicorn


    【解决方案1】:

    这些技术并不像最初看起来那样相似。 它们涉及应用程序堆栈的不同部分,实际上是互补的。

    Gunicorn 用于扩展 Web 请求并发,而 celery 应被视为工作队列。我们很快就会使用 Kubernetes。


    独角兽

    Web 请求并发主要受网络 I/O 或“I/O 绑定”的限制。这些类型的任务可以使用线程提供的协作调度来扩展。如果您发现请求并发限制了您的应用程序,那么增加 gunicorn 工作线程可能是开始的地方。


    芹菜

    繁重的任务,例如压缩图像,运行一些 ML 算法,都是“CPU 绑定”任务。他们不能像更多的 CPU 那样从线程中受益。这些任务应该由 celery worker 卸载和并行化。


    Kubernetes

    Kubernetes 的用处在于提供开箱即用的水平可扩展性和容错能力。

    在架构上,我会使用两个单独的 k8s 部署来表示您的应用程序的不同可扩展性问题。 一个部署用于 Django 应用程序,另一个部署用于 celery 工人。 这使您可以独立扩展请求吞吐量与处理能力。

    我运行 celery worker 固定到每个容器的单个核心 (-c 1),这极大地简化了调试并遵守 Docker 的“每个容器一个进程”的口头禅。它还为您提供了可预测性的额外好处,因为您可以通过增加副本数来扩展每个核心的处理能力。

    扩展 Django 应用程序部署是您需要 DYOR 为您的特定应用程序找到最佳设置的地方。 再次坚持使用--workers 1,因此每个容器只有一个进程,但您应该尝试使用--threads 以找到最佳解决方案。再次通过简单地更改副本数将水平扩展留给 Kubernetes。

    HTH 这绝对是我在从事类似项目时不得不考虑的事情。

    【讨论】:

    • 如果我们只有一台服务器,我们是否可以说依靠 gunicorn 工人并坚持一两个 pod(副本)更好? (避免容器管理负担)谢谢
    【解决方案2】:

    我们使用 Django 和 Celery 运行 Kubernetes kluster,并实现了第一种方法。因此,我对这种权衡以及我们为什么选择这种方法的一些想法。

    在我看来,Kubernetes 就是横向扩展您的副本(称为部署)。在这方面,最有意义的是让您的部署尽可能单次使用,并随着需求的增加增加部署(如果您用完,则增加 pod)。因此,LoadBalancer 管理 Gunicorn 部署的流量,而 Redis 队列管理 Celery 工作人员的任务。这确保了底层 docker 容器简单而小巧,我们可以根据需要单独(自动)扩展它们。

    至于您对每次部署需要多少个workers/concurrency 的想法,这实际上取决于您运行 Kubernetes 的底层硬件,并且需要进行实验才能做到正确。

    例如,我们在 Amazon EC2 上运行我们的集群,并尝试使用不同的 EC2 实例类型和workers 来平衡性能和成本。每个实例拥有的 CPU 越多,需要的实例就越少,每个实例可以部署的 workers 就越多。但我们发现在我们的案例中部署更多更小的实例更便宜。我们现在部署多个 m4.large 实例,每个部署有 3 个工作人员。

    有趣的旁注:gunicorn 与亚马逊负载均衡器结合使用时,我们的性能非常糟糕,因此我们切换到 uwsgi,性能大幅提升。但原理是一样的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-28
      • 2021-01-20
      • 2020-11-07
      • 2021-03-13
      • 2017-05-24
      • 2018-07-05
      • 2020-04-17
      • 2012-12-19
      相关资源
      最近更新 更多