13

我试图看看为什么我的 django 网站(gunicorn 4 workers)在重负载下很慢,我做了一些分析http://djangosnippets.org/snippets/186/没有任何明确的答案,所以我从头开始使用一些负载测试ab -n 1000 -c 100 http://localhost:8888/

一个简单的 Httpreponse("hello world") 没有中间件 ==> 3600req/s

带有中间件(缓存会话、缓存身份验证)的简单 Httpreponse("hello world") ==> 2300req/s

一个简单的 render_to_response 只打印一个表单(缓存模板)==> 1200req/s(响应时间除以 2)

具有 50 个内存缓存查询的简单 render_to_response ==> 157req/s

Memcache 查询应该比这快得多(我使用的是 PyLibMCCache)?模板渲染和这个结果一样慢吗?

我尝试了不同的分析技术,但没有成功。

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 46936
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 400000
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 46936
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

$ sysctl -p

fs.file-max = 700000
net.core.somaxconn = 5000
net.ipv4.tcp_keepalive_intvl = 30

我正在使用 ubuntu 12.04(6Go 内存,核心 i5)

请问有什么帮助吗?

4

2 回答 2

1

这实际上取决于执行 memcached 请求和打开新连接需要多长时间(django 在请求完成时关闭连接),您的工作人员和 memcached 都能够处理更多的压力,但当然如果需要 5/做一个 memcached 调用需要 10 毫秒,然后其中 50 个将成为瓶颈,因为网络延迟乘以调用次数。

现在你只是在对 django、gunicorn、你的机器和你的网络进行基准测试。

除非你在这个级别有什么严重错误,否则这个测试不会给你指出非常有趣的发现。

您的应用程序运行速度变慢的原因很可能与您使用 db 和 memcached 的方式有关(可能在模板渲染时)。

出于这个原因,我真的建议您获取 django 调试工具栏并查看实际页面中发生的情况。

如果事实证明打开与 memcached 的连接是瓶颈,您可以尝试使用连接池并保持连接打开。

于 2013-03-09T13:40:29.273 回答
0

您可以调查 memcached 的性能。

$ python manage.py shell
>>> from django.core.cache import cache
>>> cache.set("unique_key_name_12345", "some value with a size representative of the real world memcached usage", timeout=3600)
>>> from datetime import datetime
>>> def how_long(n):
        start = datetime.utcnow()
        for _ in xrange(n):
            cache.get("unique_key_name_12345")
        return (datetime.utcnow() - start).total_seconds()

通过这种往返测试,我发现 1 个 memcached 查找在我的服务器上大约需要 0.2 毫秒。

django.core.cache 和 pylibmc 的问题在于函数是阻塞的。在 HTTP 请求的往返行程中,您可能会获得该数字的 50 倍。50 乘以 0.2 毫秒已经是 10 毫秒。

如果您在没有 memcached 的情况下在 4 个 worker 上实现 1200 req/s,则平均 HTTP 往返时间为 1/(1200/4) = 3.33 ms。再加上 10 毫秒,它变成了 13.33 毫秒。4 名工人的吞吐量将下降到 300 req/s(这恰好在您的 157 号的范围内)。

于 2014-01-29T13:46:27.093 回答