django - 如何在 Django、UWSGI 和 Kubernetes 的峰值负载下优化每秒请求数
问题描述
我们有一个应用程序经历了一些非常短而尖锐的峰值——通常大约 15-20 分钟长,峰值为 150-250 个请求/秒,但在此期间大约平均为 50-100 个请求/秒。p50 响应时间约为 70 毫秒(而 p90 约为 450 毫秒)
该应用程序通常只是为来自数据库/memcached 集群的模型提供服务,但有时也会向 3rd 方 API 等(跟踪/Stripe 等)发出请求。
这是一个使用 uwsgi 运行的 Django 应用程序,运行在 Kubernetes 上。
我将为您省去完整的 uwsgi/kube 设置,但 TLDR:
# uwsgi
master = true
listen = 128 # Limited by Kubernetes
workers = 2 # Limited by CPU cores (2)
threads = 1
# Of course much more detail here that I can load test...but will leave it there to keep the question simple
# kube
Pods: 5-7 (horizontal autoscaling)
如果我们假设平均响应时间为 150 毫秒,我会粗略计算出 93 个请求/秒的总容量 - 略低于我们的峰值。在我们的日志中,我们经常得到uWSGI listen queue of socket ... full
日志,这是有道理的。
我的问题是......我们有什么选择来处理这个峰值?限制:
- 似乎 128 侦听队列是由内核决定的,而 kube 文档建议增加它是不安全的。
- 我们的 Kube 节点有 2 个核心。一般建议似乎是将您的工作人员数量设置为 2 * 核心(可能 + 1),所以我们在这里几乎达到了我们的极限。增加到3似乎没有太大影响。
- Django 中的多个线程显然会导致奇怪的错误
我们唯一的选择是在 kubernetes 级别上保持水平扩展吗?当然,除了使我们的查询/缓存尽可能高效之外。
解决方案
推荐阅读
- awesome-wm - 有没有办法监控 awesome-wm 中可见客户列表的变化?
- javascript - 使用 FullCalendar 显示事件数组
- hl7-fhir - 在 XML 和 Json 之间转换 fhir
- sql - SQL - ROW_NUMBER 用于多条件 LEFT JOIN
- typescript - Typescript 接口继承和泛型类型推断
- vba - 基于登录信息的控制表单
- python - MSYS 上的 PyQtWebEngine
- excel - 列底部的自动求和
- amazon-web-services - AWS Quicksight 前 10 名表
- sql - 如何在不舍入或截断 0 的情况下截断 Presto 中的纬度和经度?