V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kkwezard
V2EX  ›  Flask

flask 用 gunicorn 的 sync worker 比 gevent 等 async worker 更快?

  •  1
     
  •   kkwezard · 2016-03-11 10:49:20 +08:00 · 7050 次点击
    这是一个创建于 2966 天前的主题,其中的信息可能已经有所发展或是发生改变。

    双核 2.6g
    guniorn 启 2 个 worker
    每次 GET 请求去 read 一次数据库

    用 ab 并发 100 去测试 GET
    选 gevent worker 的情况下, qps 220 。
    选 sync worker 的情况下, qps 270 。

    用 ab 并发 500 去测试 GET
    选 gevent worker 的情况下, qps 210 。
    选 sync worker 的情况下, qps 260 。

    请问什么情况下才选用 gevent 这类的 async worker ?是因为并发还不够高吗。还是单次请求的瓶颈不在 IO 上?

    10 条回复    2018-06-28 15:32:45 +08:00
    calease
        1
    calease  
       2016-03-11 16:16:09 +08:00
    你 gevent 是单 interpreter 在跑吗。
    如果是的话要乘以 2 才是双核的真实成绩。
    另外 gevent 的 worker 不要开太高,会影响效率。
    具体多少根据经验和试验自己调整。
    我一般是直接 32 个。
    kkwezard
        2
    kkwezard  
    OP
       2016-03-11 17:37:08 +08:00
    @calease -w 1, 2, 4 我都试了。比较下来 gevent 的吞吐率都不如 sync worker 。我估计是因为我的请求依然是 cpu-bound 型的。数据库操作也是同一机器上的本地回环。可能涉及到外部网络访问等可能阻塞的操作的时候才需要 gevent 吧。你 32 个 worker 是几核的机器?
    toono
        3
    toono  
       2016-03-11 20:48:00 +08:00
    我是新手,用了 flask 不知道怎么上 gunicorn 。
    之前用 Django 用 gunicorn 很简单。
    请老司机带带路。:-)
    aljun
        4
    aljun  
       2016-03-11 22:27:14 +08:00
    @toono - -不是差不多么,带起 app 就可以了啊
    toono
        5
    toono  
       2016-03-11 22:50:09 +08:00
    @aljun 我只是写好了程序,只能在测试服务器运行,不清楚改设置什么才能在 gunicorn 运行😂
    calease
        6
    calease  
       2016-03-11 22:54:53 +08:00
    @kkwezard
    没用过-w 。 gevent 我都是在 script 里 monkey patch 后 spawn 然后 join all 的。
    32 个 worker 是单核的 worker 数量, 8 个核的机器 8 个 script 同时跑,一共是 32*8 个 worker 。
    cpu bound 型无法从 gevent 中受益。
    kkwezard
        7
    kkwezard  
    OP
       2016-03-14 11:36:49 +08:00
    @calease 测试了了一下。请求引入外部网络访问等阻塞操作之后, sync worker 性能剧烈下降, gevent 能保持吞吐率。果然是请求本身特性的问题。谢谢!另外真的需要那么多 worker 吗。根据 gunicorn 的文档推荐和我的测试结果。 worker 数量 2 倍于你的 cpu 核心数量差不多就可以获得最佳性能了。
    calease
        8
    calease  
       2016-03-14 13:08:01 +08:00
    @kkwezard
    worker 的数量取决于你用什么 library 。
    gunicorn 是 sync 的,每个 worker 单独占用一个 interpreter ,所以 worker 数量==cpu 核心数量的 2 倍,因为超线程 1 个 cpu 核心可以跑两个 interpreter 而很少性能损失。
    gevent 是 async 的,用的是 greenlet ,所有的 worker 都共享 interpreter ,所以 worker 数量和 CPU 核心数没有任何关系。而是取决于你的网络情况和 worker 本身对单核 CPU 的使用率。
    kkwezard
        9
    kkwezard  
    OP
       2016-03-14 13:15:52 +08:00
    @calease 了解。确实是这样。
    ashin
        10
    ashin  
       2018-06-28 15:32:45 +08:00
    我也发现 sync 比 gevent 性能好一点点,不知道为啥。
    我测的一个 POST 接口,接口只做一件事就是把收到的参数扔到 rabbitmq 中
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   981 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:53 · PVG 04:53 · LAX 13:53 · JFK 16:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.