推荐学习书目
› 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 · 10026 views
    This topic created in 3885 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
    deben
    Mar 16, 2016 via Android
    1
    LZ 是否方便说的详细一点儿呢?
    mailto1587
    mailto1587
    Mar 16, 2016
    2
    是 mysql 连接那块还是阻塞的?
    zhuangzhuang1988
    zhuangzhuang1988
    Mar 16, 2016
    3
    好惨。。。
    janxin
    janxin
    Mar 16, 2016 via iPhone
    4
    mysql 请求太多,但是每个返回都慢导致的队列太长吧?
    sujin190
    sujin190
    OP
    Mar 16, 2016
    5
    @mailto1587 异步的,要是阻塞的就简单多了
    sujin190
    sujin190
    OP
    Mar 16, 2016
    6
    @janxin 是啊,看来比较懂,后来加了队列超时时间,然后要一波一波开始超时了。。
    sujin190
    sujin190
    OP
    Mar 16, 2016
    7
    @deben 不平稳的请求数,在完全异步的 tornado 环境下,会导致 mysql 队列太长,最终请求超时,客户端发起重试,但 mysql 查询请求并未取消,然后就循环超时,高并发时快速失败是个问题,后来加了队列等待超时机制,然后又一波一波开始超时了,削峰又是个问题啊,异步的 mysql 操作,又有可能造成连接池获取连接死锁问题。。
    decaywood
    decaywood
    Mar 16, 2016
    8
    数据库读写分离,或者数据库单独起个服务, tornado 进行异步请求
    sujin190
    sujin190
    OP
    Mar 16, 2016
    9
    @decaywood 读写分离并不能解决这个问题,单独起个服务的话分明又加了个更复杂的问题,否则有 nginx 我为什么要用 tornado 呢?
    CrazySpiderMan
    CrazySpiderMan
    Mar 16, 2016
    10
    Tornado 是垃圾, 用 Node.js
    WildCat
    WildCat
    Mar 16, 2016
    11
    Node.js 是垃圾,用 Golang

    ===

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

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

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

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

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

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