RSS Feed
更好更安全的互联网

多线程下pymongo连接数过多的问题处理

2012-04-26

背景

项目中有个应用,用到了多线程,线程中会有对MongoDB的操作。一般涉及到这种场景,都会小心MongoDB的连接的数量控制。

实现这个应用的时候必然已经考虑这点了,但实际碰到的情况是:多线程的程序运行起来,MongoDB连接数比预期多。

涉及的环境:

  • Linux
  • Python 2.6.5
  • MongoDB 2.0.0
  • MongoDB的驱动是pymongo。本文涉及的版本有4个:1.1.1、2.0.1、2.1.1,以及最新的2.2rc1。

过程

简化的代码

先用一段简化的代码来说明下这个问题。

代码的大致意思是创建1个MongoDB连接,然后生成100个线程,在线程中会有对MongoDB的操作

具体使用方式如下:

  • 编辑上述代码,保存为test_pymongo.py
  • 启动MongoDB,确保可以用127.0.0.1访问
  • 运行MongoDB自带的命令行工具mongostat,关注conn这一列,这个时候应该数量是1
  • 执行测试程序,python test_pymongo.py
  • 观察mongostat的conn这一列,猜是多少?2?这是预想的,实际竟然是101
  • 确认pymongo版本是2.0.1

怀疑pymongo版本太旧

  • 升级到最新的正式版本2.1.1
  • sudo pip install pymongo==2.1.1 --upgrade
  • 执行测试程序结果一样,已然有连接数过多的问题

确认自己程序

  • 确认没问题。上面程序只是个实际程序的简化的代码。

意外确认问题

  • 这个这个时候一般会去查看下pymongo的源代码,分析下实现原理
  • 偷个懒。刚好停下来没事,随便瞎逛了下MongoDB的缺陷跟踪系统。想可能是不是pymongo的缺陷,刚好搜到了这个缺陷, https://jira.mongodb.org/browse/PYTHON-287
  • 这个issues大致意思是每个线程还是会创建一个MongoDB的连接,希望能支持线程间共享1个MongoDB连接
  • pymongo预计解决的版本是2.2,一看,竟然刚好是发现改问题的当天发布该版本。果然,当天发布了2.2rc1这个版本

更新到2.2rc1

    • 因为不是正式版本,所以单独下载安装

  • 但失败了,和2.0.1和2.1.1的表现一样

RTFM

  • 查看文档: http://api.mongodb.org/python/2.2rc1/examples/requests.html
  • 发现是程序写法不对,修改的代码如下:
  • 运行程序,连接数符合预期数量是2
  • 关键参数是:auto_start_request=False,这个参数看源码历史,貌似从pymongo1.1.1开始移除了,在2.2rc1这个版本又恢复了,但应该有新的用处了吧。

最后

  • 问题至此,从项目角度,算是告一段落,如果从纯技术研究角度,还可以继续深入
  • 比如:至于pymongo如何处理连接数,谁有兴趣,可以深入下pymongo的源码,貌似可以从这3个py入手,估计可以另起一篇文章来讲解:
    • pymongo/connection.py
    • pymongo/database.py
    • pymongo/pool.py

参考

作者:kun | Categories:技术分享 | Tags:

5条评论

  1. kings0527说道:

    3.0之后的版本 去掉了 只说 增加了一个connect参数。。。也马勒隔壁没说干嘛。。 true和false都没用 连接数开多少线程就涨多少了 导致经常跑着跑着服务器10056 10060 10055之类的错误

  2. zhkzyth说道:

    怒赞”RTFM”

  3. 李少麒说道:

    连接数还是102。

  4. Weareyou-006说道:

    不错。碰上同样问题。

  5. wangxh说道:

    不错,重要的是遇到问题的排查思路

发表评论