为什么 MongoDB 连接数被用满了?

使用 MongoDB 时,可能会遇到因为 mongod 连接数用满了,导致客户端无法连接的问题。mongod的最大连接数通过 net.maxIncomingConnections 指定,默认值为1000000,相当于没有限制,生产环境强烈建议根据实际需求配置,以避免客户端误用导致 mongod 负载过高。

Mongod 为什么需要限制连接数?

Mongod 的服务模型是每个网络连接由一个单独的线程来处理,每个线程配置了1MB 的栈空间,当网络连接数太多时,过多的线程会导致上下文切换开销变大,同时内存开销也会上涨。

详细的分析参考 云数据库MongoDB为什么需要限制连接数?

Driver如何使用?

MongoDB 各个语言的Driver 基本都会封装包含一个 MongoClient 的对象(不同语言的 Driver 名字可能稍有不同),通常应用在使用时通过 MongoDB connection string URI 来构造一个全局的 MongoClient,然后在后续的请求中使用该全局对象来发送请求给Mongod。

应用使用的方式大致类似于

// 通常的用法

// global MongoClient object
mongoClient = new MongoClient("mongodb://root:**@host1:port1,host2:port2/admin?replicaSet=repl00& maxPoolSize=100");

// request1
db1 = mongoClient.getDatabase("db1");
coll1 = db1.getCollection("coll1");
coll1.find({...})

// request2
db2 = mongoClient.getDatabase("db2");
coll2 = db2.getCollection("coll2");
coll2.update({...})

// requestN
...

通常每个 MongoClient 会包含一个连接池,默认大小为100,也可以在构造 MongoClient 的时候通过 maxPoolSize 选项来指定。

一种典型的错误使用方式是,用户为每个请求都构造一个 MongoClient,请求结束释放 MongoClient(或根本没释放),这样做问题是请求模型从长连接变成了短连接,每次短连接
都会增加『建立 tcp 连接 + mongodb鉴权』的开销,并且并发的请求数会受限于连接数限制,极大的影响性能;另外如果 MongoClient 忘记释放,会导致MongoClient 连接池里连接一直保持着,最终耗光所有的可用连接。

// 错误的用法
// request1
mongoClient = new MongoClient("mongodb://root:**@host1:port1,host2:port2/admin?replicaSet=repl00& maxPoolSize=100");
db1 = mongoClient.getDatabase("db1");
coll1 = db1.getCollection("coll1");
coll1.find({...});
mongoClient.close();

// request2
mongoClient = new MongoClient("mongodb://root:**@host1:port1,host2:port2/admin?replicaSet=repl00& maxPoolSize=100");
db2 = mongoClient.getDatabase("db2");
coll2 = db2.getCollection("coll2");
coll2.update({...});
MongoClient.close()

// requestN
...

MongoClient 连接池配置多大合适?

通常 MongoClient 使用默认100的连接池(具体默认值以 Driver 的文档为准)都没问题,当访问同一个 Mongod 的源比较多时,则需要合理的规划连接池大小。

举个例子,Mongod 的连接数限制为2000,应用业务上有40个服务进程可能同时访问 这个Mongod,这时每个进程里的 MongoClient 的连接数则应该限制在 2000 / 40 = 50 以下 (连接复制集时,MongoClient 还要跟复制集的每个成员建立一条连接,用于监控复制集后端角色的变化情况)。

时间: 2024-12-22 04:49:46

为什么 MongoDB 连接数被用满了?的相关文章

【干货合集】大流量与高并发:数据库、架构与实践技巧

峰会专题:https://yq.aliyun.com/activity/112 报名入口:http://yq.aliyun.com/webinar/join/49?spm=5176.8155509.437644.12.F2Xi5N 从2009年第一届双十一购物节到2015年双十一全天912.17亿元的交易额,"双十一"当天订单创建峰值增长了350倍(每秒14万笔),支付峰值 (每秒8.59万笔)增长了430倍.为了保证越来越多购物者的用户体验,在IT基础设施上,阿里一次又一次地遭遇并超

linux shell中获取mongodb最大连接数、内存使用情况等

前两天接到了一个新的需求,需要在linux shell脚本中监控到mongodb最大连接数.内存使用情况等. 但是我对于linux shel很不了解,只是会一些简单常用的linux的操作而已,只要一顿狂搜,最终多番尝试下终于获取到这些值. 成功的步骤大致如下: 0. ./mongostat -u admin -p admin --authenticationDatabase admin -n 1 --json >> aaa.txt 把mongodb监控到的一行数据以json格式写入到aaa.t

云数据库MongoDB为什么需要限制连接数?

连接是要消耗资源的,而且消耗的并不少. 内存:MongoDB为例,每个线程都要分配1MB的栈内存出来.1000个连接,1G内存就这么没了,甭管是否是活跃连接 文件句柄:每个连接都要打开一个文件句柄,当然从成本上讲,这个消耗相对内存是小了很多.但换个角度,文件句柄也被其他模块消耗着,比如WT存储引擎,就需要消耗大量的文件句柄 是否真的需要这么多的链接,一般的业务场景下请求压力在1000QPS左右,按照每个请求50ms计算,最多也就需要1000/(1000/50)==50个链接即可满足需求,并且是整

MongoDB云数据库常见问题诊断

重要的内容 MongoDB的主备节点在运行过程中是不固定的,实例重启.升级.节点故障等都有可能导致主备切换,在生产环境应该使用副本集的方式来正确连接MongoDB来实现高可用. 连接问题 用户可通过DMS或mongo shell连接MongoDB云数据库,以下场景都基于用户使用mongo shell连接数据库. Q: 连接实例提示网络超时? # /u01/mongodb_current/bin/mongo --host dds-uf69ba5cf6e123442.mongodb.rds.aliy

MongoDB实战(2)工具集与特殊魔术方法

一.MongoDB启动方式 MongoDB除了支持命令行的启动方式还支持配置文件启动通过读取启动配置文件的方式来启动数据库比方说配置文件如下 则可以使用如下命令 ./mongod -f /etc/mongodb.conf MongoDB参数说明 dbpath: 数据文件存放路径每个数据库会在其中创建一个子目录用于防止同一个实例多次运行的mongod.lock也保存在此目录中. logpath 错误日志文件 logappend 错误日志采用追加模式默认是覆写模式 bind_ip 对外服务的绑定ip

MongoDB如何存储数据

想要深入了解MongoDB如何存储数据之前,有一个概念必须清楚,那就是 Memeory-Mapped Files. Memeory-Mapped Files 下图展示了数据库是如何跟底层系统打交道的. 内存映射文件是OS通过mmap在内存中创建一个数据文件,这样就把文件映射到 一个虚拟内存的区域. 虚拟内存对于进程来说,是一个物理内存的抽象,寻址空间大小为2^64 操作系统通过mmap来把进程所需的所有数据映射到这个地址空间(红线),然后 再把当前需要处理的数据映射到物理内存(灰线) 当进程访问

Mongodb的安装配置

下载软件,版本 mongodb-linux-x86_64-2.0.2.tgz 解压缩后的目录:mongodb-linux-x86_64-2.0.2 然后转移到目录 /usr/local/mongodb 建立相应的数据存放目录和日志目录 mkdir  /usr/local/mongodb/{data,log} 简单的启动服务 执行/usr/local/mongod 就可以了,但是这样一但退出终端,服务业就停止了 以后台方式运行 /usr/local/mongod  --dbpath=/usr/lo

MongoDB 如何保证 oplog 顺序?

MongoDB 复制集里,主备节点间通过 oplog 来同步数据,Priamry 上写入数据时,会记录一条oplog,Secondary 从 Primary 节点拉取 oplog并重放,以保证最终存储相同的数据集. oplog 主要特性 幂等性,每一条oplog,重放一次或多次,得到的结果是一样的:为实现幂等 mongodb 对很多操作进行来转换,比如将 insert 转换为 upsert.$inc 操作转换为 $set等等. 固定大小(capped collection),oplog 使用固定

"Redis客户端连接数一直降不下来"的有关问题解决 good

[线上问题] "Redis客户端连接数一直降不下来"的问题解决 前段时间,上线了新的 Redis缓存(Cache)服务,准备替换掉 Memcached.   为什么要将 Memcached 替换掉? 原因是 业务数据是压缩后的列表型数据,缓存中保存最新的3000条数据.对于新数据追加操作,需要拆解成[get + unzip + append + zip + set]这5步操作.若列表长度在O(1k)级别的,其耗时至少在50ms+.而在并发环境下,这样会存在"数据更新覆盖问题&