V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
AltairXsss
V2EX  ›  Python

并发和异步的问题

  •  
  •   AltairXsss · 2019-10-27 22:57:10 +08:00 · 3165 次点击
    这是一个创建于 1633 天前的主题,其中的信息可能已经有所发展或是发生改变。

    各位大佬好,新人报道。 有两个问题想问一下。

    1,我用 gunicorn 的 gevent 模式启动 flask,return hello world 的 view,单核并发大概 2000。但是加一次 flasksqlalchemy 的查询或者修改 mysql,单核并发会降低到 200-400 之间,也就是只有原来的 1/10 到 1/5。想问下各位大佬,这个的性能损失在哪个地方?我理解,io 已经被异步了,所以应该不会降低这么多才对。

    2,与 flask 结合比较好的,除了 celery 以外,有没有比较轻量的异步任务调用框架或者实现方式?我的需求主要是上传文件,进行异步文件处理。

    8 条回复    2019-11-22 23:31:29 +08:00
    ClericPy
        1
    ClericPy  
       2019-10-28 01:13:17 +08:00   ❤️ 1
    你 sqlalchemy 的 driver 用的是 pure Python 的还是有 C 加速的, 后者会在 gevent 里无法打猴子补丁导致 block, 如果是纯 Python 的 pymysql 的话, 这玩意性能你就算使用了各种事务连接池合并提交什么的操作, 性能也很差的; 再加上 sqlalchemy 本身也不是以性能出名的

    对你目前架构来说, 数据库操作想提速试试走消息队列吧

    都用上 Python 了, 而且还不用 asyncio + uvloop, 就别指望性能有多好看了..

    至于 celery, 不管是 redis 还是 rabbitmq, 我只评价一句: 又慢又占内存.

    另: 如果是 Python2, 请无视我上面所有话. Python2 和 Python3 在同步框架里, 除了 falcon , 其他性能都不够看
    tu7jako
        2
    tu7jako  
       2019-10-28 11:23:23 +08:00
    @ClericPy 请问层主有 uvloop 的 demo 吗???对这个不太熟,想了解一下
    ClericPy
        3
    ClericPy  
       2019-10-28 11:28:59 +08:00
    @tu7jako 不做底层开发不用管 uvloop 源码和使用, 无脑 asyncio.set_event_loop_policy 就够了, 它是向 asyncio 协议兼容的, 除了 Windows, 其他系统随便开. 就我随手做的压测显示, 高并发协程能比默认那个提高 20% 左右
    ClericPy
        4
    ClericPy  
       2019-10-28 11:31:37 +08:00
    https://github.com/MagicStack/uvloop
    这是 uvloop 的 Github, 发现他们测的比我的结果好多了... 至少提高一倍速度

    拖 uvloop 的 fu, starlette 框架性能落后 golang 没其他框架落后那么远, 也就慢个两倍左右...
    tu7jako
        5
    tu7jako  
       2019-10-28 11:34:55 +08:00
    @ClericPy 感谢!
    hspeed18
        6
    hspeed18  
       2019-10-28 12:40:59 +08:00
    用火焰图之类的 profile 工具跑一下,就能很清楚的看到性能瓶颈在哪里了,不要靠瞎猜。
    sylvos
        7
    sylvos  
       2019-11-22 21:56:58 +08:00 via iPhone
    @ClericPy 如何走消息队列能不能指点一下
    ClericPy
        8
    ClericPy  
       2019-11-22 23:31:29 +08:00   ❤️ 1
    @sylvos #7
    可以看看 quora 和 Reddit 上的老帖, 里面把很多场景讲的比较完整了, 我一时半会说不太清, 提一下简单的理解, 主要思路就是生产者消费者那套, 场景也比较典型

    python 内置的 Queue 就可以当一个简易版的消息队列来用; 略微粗糙的也可以用 redis 的 list, 是能抗高并发的; 进一步的就是 kafka 那些. 对 python 来说, 想利用多核很考验水平, 但是如果把任务丢到消息队列的话, 那多核利用可以简单地通过无脑开启多个执行进程, 然后单线程从消息队列里消费任务就可以了, 任务隔离不用考虑那些锁的情况了

    比如处理并行任务的竞态条件, 并发数很大但又不想用锁的话, 可以把所有任务丢到一个队列里(这一步是线程安全), 统一单线程处理, 目的就是缓解高并发的压力

    或者有些实时性要求不高的任务异步处理, 常见的就是大批量数据入库的时候, 或批量发邮件的任务, 因为频率太高会导致触到邮件服务的 rate limits, 所以把任务慢慢进行, 也能记录任务进度

    或者要保证消息的时序性, 所以把消息放在队列里

    近几年应该也有了一些其他新的用途, 一时半会想不大起来别的. 总结常见用途就是: 按时序存储消息和消费消息; 异步任务, 缓解高并发压力, 或者异步转同步控制消费速度.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   941 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 21:39 · PVG 05:39 · LAX 14:39 · JFK 17:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.