為什么 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 還要跟復制集的每個成員建立一條連接,用於監控復制集后端角色的變化情況)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM