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

求解 SQLAlchemy 持续一段时间高访问量之后的各种不能理解的异常报错 ~

  •  
  •   Feiox ·
    feiox · 2015-01-07 13:03:00 +08:00 · 11011 次点击
    这是一个创建于 3615 天前的主题,其中的信息可能已经有所发展或是发生改变。

    TimeoutError: QueuePool limit of size 10 overflow 10 reached, connection timed out, timeout 30

    AttributeError: 'NoneType' object has no attribute 'read'
    
    OperationalError: (OperationalError) (2013, "Lost connection to MySQL server during query (error(9, 'File descriptor was closed in another greenlet'))")
    
    ObjectDeletedError: Instance '<BookMetaInfo at 0x10d847790>' has been deleted, or its row is otherwise not present.
    

    有没有遇到类似异常的同学,介绍一下解决经验。
    我是在持续运行 1 个小时之后才会频繁报错。为了方便用的是 Flask-SQLAlchemy 。看官方手册上讲 使用 session 连接池之后不必每次手动 session.close() 但我加了之后,却将频繁异常的时间从 20 分钟延长到1 小时。但还是没有真正解决问题。Google、StackOverFlow 上寻找答案未果,来来来求教。
    注:代码太多,没法放上来。

    16 条回复    2015-10-15 23:40:45 +08:00
    aru
        1
    aru  
       2015-01-07 13:23:28 +08:00 via iPhone
    1. 提升sql的效率,避免慢查询
    2. pool size 提高到50
    aru
        2
    aru  
       2015-01-07 13:25:22 +08:00 via iPhone
    配置下mysql slow log,将超过1秒的sql 语句纪录下来,然后想办法优化sql语句
    tanywei
        3
    tanywei  
       2015-01-07 14:10:18 +08:00
    my.cnf的连接超时也要改啊。
    Feiox
        4
    Feiox  
    OP
       2015-01-07 14:29:38 +08:00
    @aru 并不是慢查询导致的。因为跑测试时都是最多跑到几万的数据量。我真正疑问的是,明明官方手册上说使用连接池之后可以不用 session.close(),那为什么加了之后,却将频繁异常的时间从 20 分钟延长到1 小时。
    keakon
        5
    keakon  
       2015-01-07 15:48:10 +08:00
    session.close() 只是 rollback 并放回连接池,不会真正关闭。

    我感觉你是在多个 greenlet 里同时使用了一个 session。
    kkzxak47
        6
    kkzxak47  
       2015-01-07 17:02:39 +08:00
    'File descriptor was closed in another greenlet'
    这个应该是关键错误吧
    Feiox
        7
    Feiox  
    OP
       2015-01-07 21:08:04 +08:00
    @keakon 如何在多个 gevent 里使用不同的 session 呢?
    @kkzxak47 这个错误意味着什么呢?
    是不是意味着不能偷懒使用 Flask-SQLAlchemy 而应该自己去手动管理 session
    keakon
        8
    keakon  
       2015-01-08 00:40:42 +08:00
    还有一个错你没放在代码里…

    连接池超了,你设的同时可用的连接数是 10 个。因为你没有主动关闭,所以不会被放回连接池,直到 session 被垃圾回收。

    你在每个 greenlet 和线程里都要新建一个 session,否则事务是错的。

    最后,其实在 greenlet 里用 SQLAlchemy 是被阻塞的,没有并发。
    sbmzhcn
        9
    sbmzhcn  
       2015-08-28 16:08:55 +08:00
    请问这个问题解决了吗,我也遇到相同的问题,应该是如果 @keakon 所说。但怎么做呢。
    Feiox
        10
    Feiox  
    OP
       2015-08-28 16:26:35 +08:00
    @sbmzhcn 解决了,使用以下两点: 1. 将连接池加大,自己估算平均量 * 1.5 即可。在调用 SQLAlchemy 的类中加入 __del__ 方法,在该方法中调用 session.close () 即可。
    sbmzhcn
        11
    sbmzhcn  
       2015-08-28 17:29:18 +08:00
    Lost connection to MySQL server during query ([Errno 9] File descriptor was closed in another greenlet

    我觉得别人说的 greenlet 不是协和安全的,当其中一个 session 关闭时,其它还在用,结果就出这错了,不知道大家怎么认为的,现在想知道怎么解决。
    myyou
        12
    myyou  
       2015-08-28 17:29:53 +08:00
    @Feiox 加大连接池是在 pool.py 里直接设置吗?__del__ 方法如何设置啊?
    sbmzhcn
        13
    sbmzhcn  
       2015-08-28 17:31:24 +08:00
    能把你的代码贴出来看看吗,我只要是并行写数据,就会出错。
    Lost connection to MySQL server during query ([Errno 9] File descriptor was closed in another greenlet
    @Feiox
    myyou
        14
    myyou  
       2015-08-28 17:38:57 +08:00
    @Feiox 能不能把你说的两点,详细说明一下?跪谢!
    Feiox
        15
    Feiox  
    OP
       2015-08-30 14:06:37 +08:00
    @myyou 我用的是 Flask-SQLAlchemy ,直接在配置文件中修改 SQLALCHEMY_POOL_SIZE 就可以了,详见 https://pythonhosted.org/Flask-SQLAlchemy/config.html#configuration-keys
    我是在类中使用的,添加 __del__ 方法,使得该对象销毁的时候自动调用 session.close () 具体代码找不到了,大概是

    def __del__(self ):
    db.session.close ()
    # 或者 db.session.remove ()
    @sbmzhcn 我当时解决的并不是并行写的问题,是连接池溢出问题。对于并行写我没有研究过,当时用的方法是使用 Queue 到一个线程中统一写入。
    dingyaguang117
        16
    dingyaguang117  
       2015-10-15 23:40:45 +08:00
    @Feiox LZ 现在的并发多少 SQLALCHEMY_POOL_SIZE 设置的多少呢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1940 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:40 · PVG 08:40 · LAX 16:40 · JFK 19:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.