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
sujin190
V2EX  ›  Python

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

  •  
  •   sujin190 ·
    snower · 2016-03-16 22:14:03 +08:00 · 8761 次点击
    这是一个创建于 3202 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近访问量上来了点,连续挂了两次,异步 io 的高并发反而成坑了,都是管理 mysql 连接管理的问题,想驾驭好它还不易啊
    第 1 条附言  ·  2016-03-19 15:32:55 +08:00
    又去看了下日志统计,四核四进程 2000 多的并发请求,半数是写请求,算不算多呢。。
    52 条回复    2019-12-31 09:23:54 +08:00
    deben
        1
    deben  
       2016-03-16 22:20:23 +08:00 via Android
    LZ 是否方便说的详细一点儿呢?
    mailto1587
        2
    mailto1587  
       2016-03-16 22:23:40 +08:00
    是 mysql 连接那块还是阻塞的?
    zhuangzhuang1988
        3
    zhuangzhuang1988  
       2016-03-16 22:30:17 +08:00
    好惨。。。
    janxin
        4
    janxin  
       2016-03-16 22:33:10 +08:00 via iPhone
    mysql 请求太多,但是每个返回都慢导致的队列太长吧?
    sujin190
        5
    sujin190  
    OP
       2016-03-16 22:41:51 +08:00
    @mailto1587 异步的,要是阻塞的就简单多了
    sujin190
        6
    sujin190  
    OP
       2016-03-16 22:43:24 +08:00
    @janxin 是啊,看来比较懂,后来加了队列超时时间,然后要一波一波开始超时了。。
    sujin190
        7
    sujin190  
    OP
       2016-03-16 22:48:32 +08:00
    @deben 不平稳的请求数,在完全异步的 tornado 环境下,会导致 mysql 队列太长,最终请求超时,客户端发起重试,但 mysql 查询请求并未取消,然后就循环超时,高并发时快速失败是个问题,后来加了队列等待超时机制,然后又一波一波开始超时了,削峰又是个问题啊,异步的 mysql 操作,又有可能造成连接池获取连接死锁问题。。
    decaywood
        8
    decaywood  
       2016-03-16 23:02:27 +08:00
    数据库读写分离,或者数据库单独起个服务, tornado 进行异步请求
    sujin190
        9
    sujin190  
    OP
       2016-03-16 23:10:03 +08:00
    @decaywood 读写分离并不能解决这个问题,单独起个服务的话分明又加了个更复杂的问题,否则有 nginx 我为什么要用 tornado 呢?
    CrazySpiderMan
        10
    CrazySpiderMan  
       2016-03-16 23:14:08 +08:00
    Tornado 是垃圾, 用 Node.js
    WildCat
        11
    WildCat  
       2016-03-16 23:15:06 +08:00
    Node.js 是垃圾,用 Golang

    ===

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

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

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

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

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

    我这里测试用的是 uliweb gevent sqlalchemy postgresql
    dingyaguang117
        52
    dingyaguang117  
       2019-12-31 09:23:54 +08:00 via iPhone
    单线程模型确实是很容易死锁的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2043 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 01:02 · PVG 09:02 · LAX 17:02 · JFK 20:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.