rti*_*dru 30 django celery gunicorn docker kubernetes
我想知道使用gunicorn和芹菜部署容器化Django应用程序的正确方法是什么.
具体来说,这些过程中的每一个都具有垂直缩放的内置方式,workers用于炮弹和concurrency芹菜.然后是Kubernetes使用缩放方法replicas
还有这种将工人设置为与CPU的某些功能相等的概念.Gunicorn建议
每个核心2-4名工人
但是,我很困惑这对于K8而言是什么,其中CPU是可分割的共享资源 - 除非我使用resoureceQuotas.
我想了解最佳实践是什么.我能想到三个选项:
关于此问题,有一些问题,但没有一个提供深入/深思熟虑的答案.如果有人可以分享他们的经验,我将不胜
注意:我们使用默认worker_class sync为Gunicorn
sta*_*cks 17
这些技术并不像最初看起来那么相似.它们涉及应用程序堆栈的不同部分,实际上是互补的.
Gunicorn用于扩展Web请求并发,而芹菜应该被视为工作队列.我们很快就会到达kubernetes.
Web请求并发主要受网络I/O或"I/O绑定"的限制.可以使用线程提供的协作调度来缩放这些类型的任务.如果您发现请求并发性限制了您的应用程序,那么增加gunicorn工作线程可能就是开始的地方.
繁重的任务,例如压缩图像,运行一些ML算法,是"CPU绑定"任务.它们不能像更多的CPU一样受益于线程化.这些任务应该由芹菜工人卸载和并行化.
Kubernetes派上用场的方法是提供开箱即用的水平可扩展性和容错能力.
在架构上,我将使用两个单独的k8s部署来表示应用程序的不同scalablity问题.Django应用程序的一个部署和芹菜工作者的另一个部署.这允许您独立地扩展请求吞吐量与处理能力.
我运行芹菜工人固定到每个容器的单个核心(-c 1)这极大地简化了调试并坚持Docker的"每个容器一个进程"的口头禅.它还为您提供了可预测性的额外好处,因为您可以通过增加副本计数来扩展每个核心的处理能力.
缩放Django应用程序部署是您需要DYOR来查找特定应用程序的最佳设置的地方.再坚持使用,--workers 1因此每个容器只有一个进程,但您应该尝试--threads找到最佳解决方案.再次通过简单地更改副本计数,将水平缩放保留给Kubernetes.
HTH这绝对是我在处理类似项目时必须要解决的问题.
小智 14
我们用Django和Celery运行Kubernetes kluster,并实现了第一种方法.因此,我对这种权衡的一些想法以及为什么我们选择这种方法.
在我看来,Kubernetes就是关于水平扩展你的副本(称为部署).在这方面,最有意义的是将您的部署尽可能地单独使用,并在需求增加时增加部署(如果用完则增加容量).因此,LoadBalancer管理Gunicorn部署的流量,Redis队列管理Celery工作人员的任务.这可以确保底层的docker容器简单而小巧,我们可以根据需要单独(并自动)扩展它们.
至于您对每次部署需要多少workers/ 多少concurrency需求的想法,这实际上取决于您运行Kubernetes的底层硬件,并且需要实验才能正确运行.
例如,我们在Amazon EC2上运行我们的集群,并尝试使用不同的EC2实例类型并workers平衡性能和成本.每个实例拥有的CPU越多,所需的实例越少,workers每个实例的部署就越多.但我们发现在我们的案例中部署更小的实例更便宜.我们现在部署多个m4.large实例,每个部署有3个worker.
有趣的旁注:我们gunicorn与亚马逊负载平衡器相结合的性能非常糟糕,因此我们改用uwsgi了性能提升.但原则是一样的.
| 归档时间: |
|
| 查看次数: |
3241 次 |
| 最近记录: |