和我的团队一起,我们目前正在使用FastAPI构建一个API,一旦部署到Kubernetes上,我们真的很难获得良好的性能。我们正在尽可能多地使用异步调用,但总体保持在8RPS/Pod,以保持在我们P99 200ms的SLA之下。
对于资源,我们分配以下内容:
resources:
limits:
cpu: 1
memory: 800Mi
requests:
cpu: 600m
memory: 100Mi
令人惊讶的是,当对Docker容器中本地运行的API进行负载测试时,不会出现这样的性能下降。在那里,我们很容易在单个容器上获得约200RPS,在p99下具有120ms的延迟...
有谁知道哪里会出问题,我可以从哪里开始寻找瓶颈?
干杯!
2条答案
按热度按时间8e2ybdfx1#
首先,尝试为您的API请求至少1个CPU,因为如果节点上没有可用的CPU,则示例只会使用预留的600M CPU,因此如果您有另一个应用程序的请求CPU=400M,Kubernetes将在同一个CPU上运行这两个应用程序,API和第二个应用程序的运行时间分别为60%和40%。而docker在本地主机中使用1个CPU(可能更多)。
如果将Uvicorn与多个工作进程一起使用,还可以将CPU限制增加到或至少为2。
最后,您的本机CPU和Kubernetes集群CPU有一个不同之处,如果您想获得良好的性能,可以测试更好的CPU,从成本上选择最合适的。
imzjd6km2#
最后,我们的性能问题似乎是由不使用
gunicorn
而只使用uvicorn
引起的(尽管FastAPI的作者在他的文档中建议不要使用gunicorn
)。另一方面,Uvicorn的作者在他们的文档中推荐了相反的方法,即使用gunicorn
。我们听从了这个建议,我们的表现问题就解决了。正如本帖子中的人所建议的那样,根据我们的PodSpec的要求设置更多的CPU也是解决方案的一部分。
编辑:最后,我们最终发现性能问题是由于我们使用opentelemeter-Instrument CLI在FastAPI上实现OpenTelemeter而导致的。后者在FastAPI的异步上造成了大量的开销和阻塞调用。无论是使用黑角还是uvicorn,现在的性能都非常稳定。我们仍在使用具有多个工作进程的Gunicorn,但我们也计划重新使用uvicorn单进程,并更动态地进行扩展。