uWSGI python高负载配置

我们有一个拥有32个内核的大型EC2实例,目前运行的是Nginx,Tornado和Redis,每秒平均提供5K请求.一切似乎都运行良好,但cpu负载已经达到70%,我们必须支持更多的请求.其中一个想法是用uWSGI取代Tornado,因为我们并没有真正使用Tornado的异步功能.

我们的应用程序由一个函数组成,它接收一个JSON(〜= 4KB),执行一些阻塞但非常快的东西(Redis)并返回JSON.

>对其中一个Tornado实例(Nginx)的代理HTTP请求
>解析HTTP请求(Tornado)
>读取POST正文字符串(字符串化JSON)并将其转换为python字典(Tornado)
>从位于同一台机器上的Redis(阻塞)中取出数据(py-redis with hiredis)
>处理数据(python3.4)
>在同一台机器上更新Redis(py-redis with hiredis)
>为响应准备字符串化JSON(python3.4)
>发送对代理的响应(龙卷风)
>向客户发送回复(Nginx)

我们认为速度提升将来自uwsgi协议,我们可以在单独的服务器上安装Nginx,并使用uwsgi协议代理对uWSGI的所有请求.但在尝试所有可能的配置并更改操作系统参数后,即使在当前负载下,我们仍然无法使其工作.
大多数时候Nginx日志包含499和502错误.在某些配置中,它只是停止接收新请求,例如达到某些操作系统限制.

正如我所说,我们有32个内核,60GB可用内存和非常快的网络.我们不做重物,只做非常快速的阻塞操作.在这种情况下,最好的策略是什么?进程,线程,异步?应该设置哪些OS参数?

目前的配置是:

[uwsgi]
master = 2
processes = 100
socket = /tmp/uwsgi.sock
wsgi-file = app.py
daemonize = /dev/null
pidfile = /tmp/uwsgi.pid
listen = 64000
stats = /tmp/stats.socket
cpu-affinity = 1
max-fd = 20000
memory-report = 1
gevent = 1000
thunder-lock = 1
threads = 100
post-buffering = 1

Nginx配置:

user www-data;
worker_processes 10;
pid /run/Nginx.pid;

events {
    worker_connections 1024;
    multi_accept on;
    use epoll;
}

OS配置:

sysctl net.core.somaxconn
net.core.somaxconn = 64000

我知道限制太高,开始尝试每一个可能的价值.

更新:

我最终得到了以下配置:

[uwsgi]
chdir = %d
master = 1
processes = %k
socket = /tmp/%c.sock
wsgi-file = app.py
lazy-apps = 1
touch-chain-reload = %dreload
virtualenv = %d.env
daemonize = /dev/null
pidfile = /tmp/%c.pid
listen = 40000
stats = /tmp/stats-%c.socket
cpu-affinity = 1
max-fd = 200000
memory-report = 1
post-buffering = 1
threads = 2
最佳答案
我认为你的请求处理大致分解如下:

> HTTP解析,请求路由,JSON解析
>执行一些产生redis请求的python代码
>(阻止)redis请求
>执行一些处理redis响应的python代码
> JSON序列化,HTTP响应序列化

您可以在近乎空闲的系统上对处理时间进行基准测试.我的预感是往返时间可以缩短到2或3毫秒.在70%的cpu负载下,这将达到大约4或5毫秒(不计算在Nginx请求队列中花费的时间,只是uWSGI工作器中的处理).

在5k req / s时,您的平均进程中请求可能在20 … 25范围内.与您的VM完美匹配.

下一步是平衡cpu核心.如果您有32个内核,则分配1000个工作进程没有意义.您最终可能会在上下文切换开销上阻塞系统.良好的平衡将使工作人员的总数(Nginx uWSGI redis)在可用cpu核心的数量级上,可能需要额外的一点来覆盖阻塞I / O(即文件系统,但主要是对其他人进行的网络请求)主机像DBMS).如果阻塞I / O成为等式的重要组成部分,请考虑重写异步代码并集成异步堆栈.

首先观察:你将10个工人分配给Nginx.但是,Nginx在请求上花费的cpu时间比uWSGI花费的时间要少得多.我首先将大约10%的系统专用于Nginx(3或4个工作进程).

其余部分必须在uWSGI和redis之间分配.我不知道redis中索引的大小,或者你的python代码的复杂性,但我的第一次尝试是uWSGI和redis之间的75%/ 25%分割.这将使大约6名工人和uWSGI上大约20名工人成为主人.

至于uwsgi配置中的threads选项:线程切换比进程切换轻,但如果你的python代码的很大一部分是cpu绑定的,它将不会因为GIL而飞.如果您的处理时间的很大一部分被I / O阻塞,则Threads选项主要是有趣的.您可以禁用线程,或尝试使用workers = 10,threads = 2作为初始尝试.

相关文章

一、Linux下Nginx的安装 1.去官网 http://nginx.org/download/下载对应的Nginx安装包,推荐使...
一、空格:默认匹配、普通匹配 location / { root /home; } 二、= :精确匹配(表示匹配到 /home/resou...
``` nginx -c 配置文件路径 ``` ``` /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.con...
前言 nginx可所谓是如今最好用的软件级别的负载均衡了。通过nginx的高性能,并发能力强,占用内存下的特...
1.ngnix概念 Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。由俄...
博客园从今天上午就开始报502错误 , 他的原因还不知道 , 暂时先说下我们遇到502的排查情况 最大的可能性...