推荐学习书目
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
sujin190
V2EX  ›  Python

tornado 连续踩了两次坑,看来想驾驭好它还不容易啊

  •  
  •   sujin190 ·
    snower · Mar 16, 2016 · 9611 views
    This topic created in 3726 days ago, the information mentioned may be changed or developed.
    最近访问量上来了点,连续挂了两次,异步 io 的高并发反而成坑了,都是管理 mysql 连接管理的问题,想驾驭好它还不易啊
    Supplement 1  ·  Mar 19, 2016
    又去看了下日志统计,四核四进程 2000 多的并发请求,半数是写请求,算不算多呢。。
    52 replies    2019-12-31 09:23:54 +08:00
    deben
        1
    deben  
       Mar 16, 2016 via Android
    LZ 是否方便说的详细一点儿呢?
    mailto1587
        2
    mailto1587  
       Mar 16, 2016
    是 mysql 连接那块还是阻塞的?
    zhuangzhuang1988
        3
    zhuangzhuang1988  
       Mar 16, 2016
    好惨。。。
    janxin
        4
    janxin  
       Mar 16, 2016 via iPhone
    mysql 请求太多,但是每个返回都慢导致的队列太长吧?
    sujin190
        5
    sujin190  
    OP
       Mar 16, 2016
    @mailto1587 异步的,要是阻塞的就简单多了
    sujin190
        6
    sujin190  
    OP
       Mar 16, 2016
    @janxin 是啊,看来比较懂,后来加了队列超时时间,然后要一波一波开始超时了。。
    sujin190
        7
    sujin190  
    OP
       Mar 16, 2016
    @deben 不平稳的请求数,在完全异步的 tornado 环境下,会导致 mysql 队列太长,最终请求超时,客户端发起重试,但 mysql 查询请求并未取消,然后就循环超时,高并发时快速失败是个问题,后来加了队列等待超时机制,然后又一波一波开始超时了,削峰又是个问题啊,异步的 mysql 操作,又有可能造成连接池获取连接死锁问题。。
    decaywood
        8
    decaywood  
       Mar 16, 2016
    数据库读写分离,或者数据库单独起个服务, tornado 进行异步请求
    sujin190
        9
    sujin190  
    OP
       Mar 16, 2016
    @decaywood 读写分离并不能解决这个问题,单独起个服务的话分明又加了个更复杂的问题,否则有 nginx 我为什么要用 tornado 呢?
    CrazySpiderMan
        10
    CrazySpiderMan  
       Mar 16, 2016
    Tornado 是垃圾, 用 Node.js
    WildCat
        11
    WildCat  
       Mar 16, 2016
    Node.js 是垃圾,用 Golang

    ===

    233
    CrazySpiderMan
        12
    CrazySpiderMan  
       Mar 16, 2016
    Golang 是垃圾, 用 Erlang.
    CrazySpiderMan
        13
    CrazySpiderMan  
       Mar 16, 2016
    Erlang 是垃圾, 用 Common Lisp.
    CrazySpiderMan
        14
    CrazySpiderMan  
       Mar 16, 2016
    Common Lisp 是垃圾, 用 Rust.
    CrazySpiderMan
        15
    CrazySpiderMan  
       Mar 16, 2016
    Rust 是垃圾, 用 Perl.
    CrazySpiderMan
        16
    CrazySpiderMan  
       Mar 16, 2016
    Perl 是垃圾, 用 PHP.
    CrazySpiderMan
        17
    CrazySpiderMan  
       Mar 16, 2016
    PHP 是垃圾, 用 Python.
    sujin190
        18
    sujin190  
    OP
       Mar 16, 2016
    @CrazySpiderMan 用过 nodejs ,不得不说,没有 yield 的 nodejs 更坑,各种异常处理,查询数据库,麻烦死了,但是 tornado 遇到的问题,估计也会遇到吧
    CrazySpiderMan
        19
    CrazySpiderMan  
       Mar 16, 2016
    @sujin190 我用 Node.js, 在会一点 JavaScript 和看了一点 Node.js 的文档的情况下, 就写过蛮复杂的程序(github star ~= 1200), 用 Tornado, 光是文档我都很难看懂, 设计得极其丑陋, 曾用它开发过程序, 很早就弃坑了.
    motecshine
        20
    motecshine  
       Mar 16, 2016 via Android
    mark 一下以后估计也会遇到
    gx
        21
    gx  
       Mar 17, 2016
    对于这种密集读写风暴还是应该交给上层处理,还有异步数据库驱动的确太坑。
    cevincheung
        22
    cevincheung  
       Mar 17, 2016
    所以还是中间件吧。要不 postgresql 欢迎你
    lecher
        23
    lecher  
       Mar 17, 2016 via Android
    数据库业务设计有问题,至少合理设计缓存处理可以做到 Web 读取的请求不需要穿透到数据库。

    就数据库的处理性能而言,不应该比单机 Web 服务差,要是扛不住单机 Web 的请求,改改读写数据库的业务优化才是上策,一个每秒查询才几百就拖垮的数据库业务,用什么语言都一样会挂。

    数据库扛每秒几千的请求才是合理的,正常的单机业务瓶颈应该出在带宽或者 Web 容器上。
    janxin
        24
    janxin  
       Mar 17, 2016
    @sujin190 上面都提到了,跟语言无关,还是架构设计的问题
    clino
        25
    clino  
       Mar 17, 2016 via Android
    同感 如果瓶颈在数据库上应该想办法做数据库优化
    一个就是能不能配置 nginx 的访问频率限制呢
    clino
        26
    clino  
       Mar 17, 2016 via Android
    @cevincheung postgres 这方面有什么好处?
    deben
        27
    deben  
       Mar 17, 2016
    LS 的各位大神, 如果对于我这种外行人来做数据库频繁写入的业务, 会不会用类似 阿里云 的 RDS 这种产品会更少一些麻烦呢?
    bobuick
        28
    bobuick  
       Mar 17, 2016
    RDS 只是机器性能方便扩展而已, 数据库方面并没什么特别的。同样的配置该它瓶颈还是一样会瓶颈。
    不然地球人就不用分表分库,做分布式分布数据了
    lecher
        29
    lecher  
       Mar 17, 2016 via Android
    RDS 用不好一样挂。
    遇到过个电商团队问过类似的问题,他们才几万用户,每秒一百多 HTTP 请求,还是处理不过来,一查业务, SQL 读写处理各种多级联表,最多的有五级联表,如果都没有命中索引,五个 join 把五个表的记录一乘起来就是非常恐怖的运算量。

    这种情况直接在数据库加冗余字段,减少联表查询,性能一下就上去了。能单表查询尽量单表查询,不行也要把索引规划好,减少联表的消耗。在加上缓存处理,把读取查询结果缓存在内存,数据库基本负载就都在处理写入,可以提高更多性能。
    ainimuyan
        30
    ainimuyan  
       Mar 17, 2016
    @sujin190 有没测试过多少并发的时候开始出现这样的问题呢
    justfly
        31
    justfly  
       Mar 17, 2016
    你现在数据库是瓶颈了就去解决瓶颈的问题,就算不用异步的 MySQL 驱动,数据库到瓶颈不会出现这个问题,也会出现拒绝连接的问题
    realpg
        32
    realpg  
    PRO
       Mar 17, 2016
    一看描述,就是不会写 SQL 的问题……
    跟同步异步、 tornado 、 python 都没啥关系……
    zhicheng
        33
    zhicheng  
       Mar 17, 2016
    @realpg 见了少切肉剁到手嫌菜刀快的。
    wingyiu
        34
    wingyiu  
       Mar 17, 2016
    我们的 tornaod 的 sql 查询都是同步的,只要 sql 足够快, tornado 进程足够多,就没问题了。 py 异步 mysql 库还没有比较稳定健壮的吧
    sujin190
        35
    sujin190  
    OP
       Mar 17, 2016
    @lecher 恩,测试下来, mysql 每次查询数确实过万的,没有 join 查询的话
    sujin190
        36
    sujin190  
    OP
       Mar 17, 2016
    @ainimuyan 其实说起来 mysql 并未到瓶颈,测试下来,每秒过万查询完全没问题,只是 tornado 完全异步,确实查询数据库等待不接受其他连接这个缓冲,使得突然高并发削峰,连接管理上和同步模式有些不一样
    sujin190
        37
    sujin190  
    OP
       Mar 17, 2016
    @wingyiu 是的,使用同步 sql 方式来管理思考查询过程,到了异步来说,似乎问题不太一样,也正在尝试调整
    sujin190
        38
    sujin190  
    OP
       Mar 17, 2016
    @ainimuyan 并发其实不是太高,大概 300-600 左右吧,单机,只是因为我们客户端的原因,有时可能超过数倍,所以突然升高的负载会使得 mysql 连接管理,负载出现异样整个不可用,也正在调整尝试
    strwei
        39
    strwei  
       Mar 17, 2016
    本站用的就是 tornado ,你们有何异议
    tempuseraccount
        40
    tempuseraccount  
       Mar 17, 2016
    都是垃圾,用 C 从头写吧
    xxxcat
        41
    xxxcat  
       Mar 17, 2016
    曾经看到过一篇老外的文章,说是 python 的异步调用比同步调用的代价高很多,所以随着接近数据库瓶颈,异步会更容易出问题,我觉得访问量比较高的系统,框架就不应该直联数据库
    sujin190
        42
    sujin190  
    OP
       Mar 17, 2016
    @xxxcat 多了很多 callback ,消耗时间自然多了很多
    darkbill
        43
    darkbill  
       Mar 17, 2016
    Mark 一下~~
    AndyCrz
        44
    AndyCrz  
       Mar 17, 2016
    我用 tornado 抗过大流量项目(其实也没没多少每天十万条写入),个人经验是这样, 80%是 Mysql 没有配置好,用 dbutils 维持一个连接池,数据用事务进行批量提交已经跑了一年多了,至今没出现过问题
    zonghua
        45
    zonghua  
       Mar 17, 2016
    部署 py 的工程,因为配置的路径少了一条杠,耗费了我一个下午的时间。
    alexapollo
        46
    alexapollo  
       Mar 17, 2016
    明显是存储瓶颈,换 redis 就好了,或者加个缓存
    alexapollo
        47
    alexapollo  
       Mar 17, 2016
    no business with tornado
    sujin190
        48
    sujin190  
    OP
       Mar 17, 2016
    @AndyCrz 我们现在已经数十万写入,数百万 request 了。。 dbutils 同步读写吧
    AndyCrz
        49
    AndyCrz  
       Mar 18, 2016
    @sujin190 这种问题你确定是异步的问题吗?你测试了 profile 了?看一下数据库的 log 了
    lixm
        50
    lixm  
       Mar 18, 2016
    数据库这里慢, 换什么都不行, 把数据库的问题解决了,一切都 OK 了
    clino
        51
    clino  
       Mar 18, 2016
    楼主我自己写了写代码来测试,异步用的是 gevent,感觉还好,如果故意在处理请求的时候改成比较慢的比如说等待一下 shell 子进程的结束等,确实数据库那边会有问题,但是只要调大一下连接池的最大连接数,然后再配置一个合适的数据库连接获取 timeout 的时间,虽然 rps 会变低很多,但是数据库这里不会抗不住才对呢

    楼主你应该有用连接池吧?

    我这里测试用的是 uliweb gevent sqlalchemy postgresql
    dingyaguang117
        52
    dingyaguang117  
       Dec 31, 2019 via iPhone
    单线程模型确实是很容易死锁的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3002 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 100ms · UTC 03:56 · PVG 11:56 · LAX 20:56 · JFK 23:56
    ♥ Do have faith in what you're doing.