设为首页 收藏本站
查看: 1087|回复: 0

[经验分享] PHP-FPM模式下可怕的 MongoDB-PHP-Driver 连接池无节制连接问题

[复制链接]
YunVN网友  发表于 2015-7-8 09:01:52 |阅读模式
@郑昀汇总 创建日期:2013/1


问题发生环境:

  • Nginx
  • PHP 5.3.10 as php-fpm extension to nginx
  • mongodb-php-driver 1.2.12
  • MongoDB 2.2

此问题是 MongoDB PHP Driver 1.2.x 的官方特性导致的,描述请看 PHP-202 和  PHP-347 。简单地说,PHP-FPM模式下,每一个 PHP Worker 进程都有自己独立的 mongodb 连接池,从而导致连接数极易超标,内存数也随之倍增。

一,PHP服务背景:
某个 Web 应用是通过 Nginx+factcgi 运行的 PHP 程序提供服务的。
PHP-FPM的最大子进程数,是通过 php-fpm.conf 的 max_children 参数设置的(或pm=dynamic时由 spare_servers+start_servers 参数综合决定)。这个值曾被设置为512


二,MongoDB服务背景:
mongodb 实例的最大连接数限制可以通过启动参数中的 maxConns 设置:

  • maxConns:默认值取决于系统的限制(如 ulimit 和 file descriptor)。如果没设置这个参数, mongodb 自己不会限制连接数。但,你不能设置超过 20,000 。
一般不刻意设置 maxConns 参数。

三,MongoDB PHP Driver 的可怕连接池特性(BUG?)
MongoDB 官方提供的 mongodb-php-driver 在 1.3.0 以下版本(1.2.0~1.2.1x),拥有一个可怕的连接池实现方案,在执行任何查询时,都会从连接池中请求一个连接,完成之后再归还给连接池。这里的完成是指持有该连接的变量离开了它的作用域。

PHP-FPM模式下,一个 PHP Web 应用能对 MongoDB instance 建立的并发连接数计算方式如下:

  • 进程数:max-children = 512 ,那么是 512 个进程;
  • 一个MongoDB实例对应一个连接池:主站配置了165和166两个副本集实例;
  • 连接池中的连接数:mongodb-php-driver 对此不做任何限制,可以无限增加直到句柄耗尽为止。

——————郑昀:此计算方式出自 mongo.connecting.pools ——————
根据 mongodb 官方文档说明,虽然连接数无限增长理论上是有可能的,但实际观测发现,一个 Web Server 与一个 mongodb 实例的连接数通常会稳定在一个值上,不会有太大的起伏
那么,假设一个 PHP Web 应用向 mongodb-165 发起的连接数为
750 个,
该 MongoDB 实例为此需要维护的内存数至少为:
750 × 默认10MB = 7.5 GB
五,解决办法
迅速升级到 mongodb-php driver 1.3.2。

参考文档:
1)2012-12-9,Connection Handling with the MongoDB PHP driver,英文稿,中文翻译稿;
2)李丹的测试结果:
“再测试一下驱动升级到1.3.2稳定版后的ab结果,发现close效果很明显,很快的连接数就下降到测试之前的数量了。虽然在峰值上大于老的驱动,但是应该可以解决现有线上的高连接持续的问题。”
3)mongodb Connection Pooling (version 1.2.0-1.2.12 *only*);
4)mongodb-java-driver 定义了一个应用与 mongodb 实例能建立的最大连接数,即 (connectionsPerHost × threadsAllowedToBlockForConnectionMultiplier)个连接:

  • mongo.options.connectionsPerHost:每个Application与 MongoDB 实例能建立的最大物理连接数,默认是10;
  • mongo.options.threadsAllowedToBlockForConnectionMultiplier:可以等待池中有连接可用的最大线程数,默认是5。
5)crazyshell,2012,MongoDB maxConns参数;

赠图几枚:
DSC0000.jpg

spymemcached 相关文章:
1)spymemcached 的 useNagle 问题与 TCP/IP延迟发送数据
2)spymemcached :某个mc节点操作连续超时超过998次就 Auto-Reconnect 的特性
3)关于 Multiget hole:spymemcached对此的实现方法
推荐阅读:
三个实例演示 Java Thread Dump 日志分析

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-84360-1-1.html 上篇帖子: NoSQL之MongoDB开篇 下篇帖子: 认识MongoDB
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表