各位大佬好,新人报道。 有两个问题想问一下。
1,我用 gunicorn 的 gevent 模式启动 flask,return hello world 的 view,单核并发大概 2000。但是加一次 flasksqlalchemy 的查询或者修改 mysql,单核并发会降低到 200-400 之间,也就是只有原来的 1/10 到 1/5。想问下各位大佬,这个的性能损失在哪个地方?我理解,io 已经被异步了,所以应该不会降低这么多才对。
2,与 flask 结合比较好的,除了 celery 以外,有没有比较轻量的异步任务调用框架或者实现方式?我的需求主要是上传文件,进行异步文件处理。
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 , 其他性能都不够看 |
3
ClericPy 2019-10-28 11:28:59 +08:00
@tu7jako 不做底层开发不用管 uvloop 源码和使用, 无脑 asyncio.set_event_loop_policy 就够了, 它是向 asyncio 协议兼容的, 除了 Windows, 其他系统随便开. 就我随手做的压测显示, 高并发协程能比默认那个提高 20% 左右
|
4
ClericPy 2019-10-28 11:31:37 +08:00
https://github.com/MagicStack/uvloop
这是 uvloop 的 Github, 发现他们测的比我的结果好多了... 至少提高一倍速度 拖 uvloop 的 fu, starlette 框架性能落后 golang 没其他框架落后那么远, 也就慢个两倍左右... |
6
hspeed18 2019-10-28 12:40:59 +08:00
用火焰图之类的 profile 工具跑一下,就能很清楚的看到性能瓶颈在哪里了,不要靠瞎猜。
|
8
ClericPy 2019-11-22 23:31:29 +08:00 1
@sylvos #7
可以看看 quora 和 Reddit 上的老帖, 里面把很多场景讲的比较完整了, 我一时半会说不太清, 提一下简单的理解, 主要思路就是生产者消费者那套, 场景也比较典型 python 内置的 Queue 就可以当一个简易版的消息队列来用; 略微粗糙的也可以用 redis 的 list, 是能抗高并发的; 进一步的就是 kafka 那些. 对 python 来说, 想利用多核很考验水平, 但是如果把任务丢到消息队列的话, 那多核利用可以简单地通过无脑开启多个执行进程, 然后单线程从消息队列里消费任务就可以了, 任务隔离不用考虑那些锁的情况了 比如处理并行任务的竞态条件, 并发数很大但又不想用锁的话, 可以把所有任务丢到一个队列里(这一步是线程安全), 统一单线程处理, 目的就是缓解高并发的压力 或者有些实时性要求不高的任务异步处理, 常见的就是大批量数据入库的时候, 或批量发邮件的任务, 因为频率太高会导致触到邮件服务的 rate limits, 所以把任务慢慢进行, 也能记录任务进度 或者要保证消息的时序性, 所以把消息放在队列里 近几年应该也有了一些其他新的用途, 一时半会想不大起来别的. 总结常见用途就是: 按时序存储消息和消费消息; 异步任务, 缓解高并发压力, 或者异步转同步控制消费速度. |